Search code examples
opencvcolor-space

OpenCV Display Colored Cb Cr Channels


So I understand how to convert a BGR image to YCrCb format using cvtColor() and seperate different channels using split() or mixChannels() in OpenCV. However, these channels are displayed as grayscale images as they are CV_8UC1 Mats.

I would like to display Cb and Cr channels in color like Barns image on Wikipedia. I found this solution in Matlab, but how do I do it in OpenCV?

Furthermore, the mentioned solution displayed Cb and Cr channels by "fills the other channels with a constant value of 50%". My question is:

Is this the common way to display Cr Cb channels? Or is there any recommendations or specifications when displaying Cr Cb channels?


Solution

  • I made a code from scratch as described in answer. Looks like it's what you need.

    Mat bgr_image = imread("lena.png");
    
    Mat yCrCb_image;
    cvtColor(bgr_image, yCrCb_image, CV_BGR2YCrCb);
    
    Mat yCrCbChannels[3];
    split(yCrCb_image, yCrCbChannels);
    
    Mat half(yCrCbChannels[0].size(), yCrCbChannels[0].type(), 127);
    vector<Mat> yChannels = { yCrCbChannels[0], half, half };
    Mat yPlot;
    merge(yChannels, yPlot);
    cvtColor(yPlot, yPlot, CV_YCrCb2BGR);
    imshow("y", yPlot);
    
    vector<Mat> CrChannels = { half, yCrCbChannels[1], half };
    Mat CrPlot;
    merge(CrChannels, CrPlot);
    cvtColor(CrPlot, CrPlot, CV_YCrCb2BGR);
    imshow("Cr", CrPlot);
    
    vector<Mat> CbChannels = { half, half, yCrCbChannels[2] };
    Mat CbPlot;
    merge(CbChannels, CbPlot);
    cvtColor(CrPlot, CrPlot, CV_YCrCb2BGR);
    imshow("Cb", CbPlot);
    waitKey(0);
    

    enter image description here

    As for converting grayscale images to color format, usually in such case all color channels (B, G, R) set to one grayscale value. In OpenCV CV_GRAY2BGR mode implemented in that manner.

    As for "fills the other channels with a constant value of 50%" I believe it's common way to visualize such color spaces as YCbCr and Lab. I did not find any articles and descriptions of this approach, but I think it's driven by visualization purposes. Indeed, if we fill the other channels with zero, fundamentally nothing has changed: we can also see the influence of each channel, but the picture does not look very nice:

    enter image description here

    So, the aim of this approach to make visualization more colorful.