Histogram equalization not working on color image - OpenCV

前端 未结 3 772
礼貌的吻别
礼貌的吻别 2020-12-23 02:10

I am trying to perform a histogram equalization using OpenCV using the following function

Mat Histogram::Equalization(const Mat& inputImage)
{
    if(inp         


        
相关标签:
3条回答
  • 2020-12-23 02:49

    I implemented a histogram equalization for BGRA image. I think this function is useful for your goal (but you should ignore the alpha channel).

    Mat equalizeBGRA(const Mat& img)
    {
    Mat res(img.size(), img.type());
    Mat imgB(img.size(), CV_8UC1);
    Mat imgG(img.size(), CV_8UC1);
    Mat imgR(img.size(), CV_8UC1);
    Vec4b pixel;
    
    if (img.channels() != 4)
    {
        cout << "ERROR: image input is not a BGRA image!" << endl;
        return Mat();
    }
    
    for (int r = 0; r < img.rows; r++)
    {
        for (int c = 0; c < img.cols; c++)
        {
            pixel = img.at<Vec4b>(r, c);
            imgB.at<uchar>(r, c) = pixel[0];
            imgG.at<uchar>(r, c) = pixel[1];
            imgR.at<uchar>(r, c) = pixel[2];
        }
    }
    
    equalizeHist(imgB, imgB);
    equalizeHist(imgG, imgG);
    equalizeHist(imgR, imgR);
    
    for (int r = 0; r < img.rows; r++)
    {
        for (int c = 0; c < img.cols; c++)
        {
            pixel = Vec4b(imgB.at<uchar>(r, c), imgG.at<uchar>(r, c), imgR.at<uchar>(r, c), img.at<Vec4b>(r, c)[3]);
            res.at<Vec4b>(r, c) = pixel;
        }
    }
    
    return res;
    }
    
    0 讨论(0)
  • 2020-12-23 02:52

    Histogram equalization is a non-linear process. Channel splitting and equalizing each channel separately is not the proper way for equalization of contrast. Equalization involves Intensity values of the image not the color components. So for a simple RGB color image, HE should not be applied individually on each channel. Rather, it should be applied such that intensity values are equalized without disturbing the color balance of the image. So, the first step is to convert the color space of the image from RGB into one of the color spaces which separate intensity values from color components. Some of these are:

    • HSV/HLS
    • YUV
    • YCbCr

    Convert the image from RGB to one of the above mentioned color spaces. YCbCr is preferred as it is designed for digital images. Perform HE of the intensity plane Y. Convert the image back to RGB.

    In your current situation, you are not observing any significant change, because there are only 2 prominent colors in the image. When there are lots of colors in the image, the splitting method will cause color imbalance.

    As an example, consider the following images:

    Input Image

    Intensity Image Equalization

    Individual Channel Equalization

    (Notice the false colors)

    Here is the OpenCV code for histogram equalization of color image using YCbCr color space.

    Mat equalizeIntensity(const Mat& inputImage)
    {
        if(inputImage.channels() >= 3)
        {
            Mat ycrcb;
    
            cvtColor(inputImage,ycrcb,CV_BGR2YCrCb);
    
            vector<Mat> channels;
            split(ycrcb,channels);
    
            equalizeHist(channels[0], channels[0]);
    
            Mat result;
            merge(channels,ycrcb);
    
            cvtColor(ycrcb,result,CV_YCrCb2BGR);
    
            return result;
        }
        return Mat();
    }
    
    0 讨论(0)
  • 2020-12-23 03:10

    And the python version, @sga:

    import cv2
    import os
    
    def hisEqulColor(img):
        ycrcb=cv2.cvtColor(img,cv2.COLOR_BGR2YCR_CB)
        channels=cv2.split(ycrcb)
        print len(channels)
        cv2.equalizeHist(channels[0],channels[0])
        cv2.merge(channels,ycrcb)
        cv2.cvtColor(ycrcb,cv2.COLOR_YCR_CB2BGR,img)
        return img
    
    
    fname='./your.jpg'
    img=cv2.imread(fname)
    
    cv2.imshow('img', img)
    img2=hisEqulColor(img)
    cv2.imshow('img2',img2)
    

    However this will produce noise in the image (Eg, the left image below)

    0 讨论(0)
提交回复
热议问题