如何在不使用cv2.equalizeHist的情况下进行直方图均衡化

2024-09-29 17:14:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过几个步骤来实现直方图均衡化:

  • 如果是灰色,则我进行计算

  • 如果是RGB,我使用其他函数将其转换为YIQ颜色,然后在Y级别上进行计算,然后将其转换回RGB

我不允许使用任何lib函数,我必须自己制作均衡函数

到目前为止,它看起来像是对灰色图像的工作,但对RGB,它给了我混乱的结果

代码:

def transformRGB2YIQ(imgRGB: np.ndarray) -> np.ndarray:
    """
    Converts an RGB image to YIQ color space
    :param imgRGB: An Image in RGB
    :return: A YIQ in image color space
    """

    yiq_from_rgb = np.array([[0.299, 0.587, 0.114],
                             [0.59590059, -0.27455667, -0.32134392],
                             [0.21153661, -0.52273617, 0.31119955]])

    YIQ = np.dot(imgRGB.reshape(-1, 3), yiq_from_rgb).reshape(imgRGB.shape)

    return YIQ

    pass


def transformYIQ2RGB(imgYIQ: np.ndarray) -> np.ndarray:
    """
    Converts an YIQ image to RGB color space
    :param imgYIQ: An Image in YIQ
    :return: A RGB in image color space
    """
    yiq_from_rgb = np.array([[0.299, 0.587, 0.114],
                             [0.59590059, -0.27455667, -0.32134392],
                             [0.21153661, -0.52273617, 0.31119955]])
    rgb_from_yiq = np.linalg.inv(yiq_from_rgb)
    RGB = np.dot(imgYIQ.reshape(-1, 3), rgb_from_yiq).reshape(imgYIQ.shape)

    return RGB
    pass


def hsitogramEqualize(imgOrig: np.ndarray) -> (np.ndarray, np.ndarray, np.ndarray):
    """
        Equalizes the histogram of an image
        :param imgOrig: Original Histogram
        :ret
    """
    print(imgOrig.size)
    if imgOrig.size == 540000:
        img=imgOrig*255
        histOrig, bins = np.histogram(img.flatten(), 256, [0, 256])

        cdf = histOrig.cumsum()
        cdf_m = np.ma.masked_equal(cdf, 0)
        cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
        cdf = np.ma.filled(cdf_m, 0).astype('uint8')

        imgEq = cdf[img.astype('uint8')]
        histEq, bins2 = np.histogram(imgEq.flatten(), 256, [0, 256])

    else:
        img=transformRGB2YIQ(imgOrig)*255
        histOrig, bins = np.histogram(img[:, :, 0].flatten(), 256, [0, 256])

        cdf = histOrig.cumsum()
        cdf_m = np.ma.masked_equal(cdf, 0)
        cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
        cdf = np.ma.filled(cdf_m, 0).astype('uint8')

        img[:, :, 0] = cdf[img[:, :, 0].astype('uint8')]
        histEq, bins2 = np.histogram(img[:, :, 0].flatten(), 256, [0, 256])
        imgEq=transformYIQ2RGB(imgOrig)

    plt.imshow(imgEq)
    plt.show()

    return imgEq, histOrig, histEq

    pass


Tags: fromimageimgreturnnprgbhistogramndarray
1条回答
网友
1楼 · 发布于 2024-09-29 17:14:42

如果有人需要

def transformRGB2YIQ(imgRGB: np.ndarray) -> np.ndarray:
    """
    Converts an RGB image to YIQ color space
    :param imgRGB: An Image in RGB
    :return: A YIQ in image color space
    """
    transMatrix = np.array([[0.299, 0.587, 0.114],
                            [0.59590059, -0.27455667, -0.32134392],
                            [0.21153661, -0.52273617, 0.31119955]]).transpose()
    shape = imgRGB.shape
    return np.dot(imgRGB.reshape(-1, 3), transMatrix).reshape(shape)

    pass


def transformYIQ2RGB(imgYIQ: np.ndarray) -> np.ndarray:
    """
    Converts an YIQ image to RGB color space
    :param imgYIQ: An Image in YIQ
    :return: A RGB in image color space
    """
    transMatrix = np.linalg.inv(np.array([[0.299, 0.587, 0.114],
                                          [0.59590059, -0.27455667, -0.32134392],
                                          [0.21153661, -0.52273617, 0.31119955]])).transpose()
    shape = imgYIQ.shape
    return np.dot(imgYIQ.reshape(-1, 3), transMatrix).reshape(shape)
    pass


def hist_eq(img: np.ndarray) -> (np.ndarray, np.ndarray, np.ndarray):
    """
    This function will do histogram equalization on a given 1D np.array
    meaning will balance the colors in the image.
    For more details:
    https://en.wikipedia.org/wiki/Histogram_equalization
    **Original function was taken from open.cv**
    :param img: a 1D np.array that represent the image
    :return: imgnew -> image after equalization, hist-> original histogram, histnew -> new histogram
    """

    # Flattning the image and converting it into a histogram
    histOrig, bins = np.histogram(img.flatten(), 256, [0, 255])
    # Calculating the cumsum of the histogram
    cdf = histOrig.cumsum()
    # Places where cdf = 0 is ignored and the rest is stored
    # in cdf_m
    cdf_m = np.ma.masked_equal(cdf, 0)
    # Normalizing the cdf
    cdf_m = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
    # Filling it back with zeros
    cdf = np.ma.filled(cdf_m, 0)


    # Creating the new image based on the new cdf
    imgEq = cdf[img.astype('uint8')]
    histEq, bins2 = np.histogram(imgEq.flatten(), 256, [0, 256])

    return imgEq, histOrig, histEq

    pass


def hsitogramEqualize(imgOrig: np.ndarray) -> (np.ndarray, np.ndarray, np.ndarray):
    """
        Equalizes the histogram of an image
        The function will fist check if the image is RGB or gray scale
        If the image is gray scale will equalizes
        If RGB will first convert to YIQ then equalizes the Y level
        :param imgOrig: Original Histogram
        :return: imgnew -> image after equalization, hist-> original histogram, histnew -> new histogram
    """

    if len(imgOrig.shape) == 2:

        img = imgOrig * 255
        imgEq, histOrig, histEq = hist_eq(img)

    else:
        img = transformRGB2YIQ(imgOrig)
        img[:, :, 0] = img[:, :, 0] * 255
        img[:, :, 0], histOrig, histEq = hist_eq(img)
        img[:, :, 0] = img[:, :, 0] / 255
        imgEq = transformYIQ2RGB(img)

    return imgEq, histOrig, histEq

    pass

相关问题 更多 >

    热门问题