BGR2YUV and YUV2BGR not working as expected

Hi,

I am trying to convert white image in raw RGB . Using BGR2YUV and YUV2BGR to convert from BGR to YUV and vice-versa.


int width, height, bpc;
vector<unsigned char> data;
vector<unsigned short> data16;

void show(string str) {
      Mat img(height, width, CV_8UC3, data.data());
      uint32_t size = (uint32_t)pow(2, bpc)-1;
      Mat displayImage;
      img.convertTo(displayImage, CV_8UC3, 255/size);
      imshow(str, displayImage);
      waitKey(0);
  }
  void show16(string str) {
      Mat img(height, width, CV_16UC3, data16.data());
      uint32_t size = (uint32_t)pow(2, bpc)-1;
      Mat displayImage;
      img.convertTo(displayImage, CV_16UC3, 65535/size);
      imshow(str, displayImage);
      waitKey(0);
  }

void convertToYCbCr444() {
            Mat rgb;
            if (bpc <= 8) {
                 rgb = cv::Mat(height, width, CV_8UC3, data.data());
             } else {
                 rgb = cv::Mat(height, width, CV_16UC3, data16.data());
             }
             Mat ycbcr;
             cvtColor(rgb, ycbcr, COLOR_BGR2YUV);
             if (bpc<=8) {
                 memcpy(data.data(), ycbcr.data, data.size());
                 show("YUV8 bits");
             } else {
                 memcpy(data16.data(), ycbcr.data, data16.size() * sizeof(unsigned short));
                 show16("YUV16 bits");
             }
  }

void convertToRawRGB() {
            Mat ycbcr;
            if (bpc <= 8) {
                ycbcr = cv::Mat(height, width, CV_8UC3, data.data());
            } else {
                ycbcr = cv::Mat(height, width, CV_16UC3, data16.data());
            }
            Mat rgb;
            cvtColor(ycbcr, rgb, COLOR_YUV2BGR);
            if (bpc<=8) {
                memcpy(data.data(), rgb.data, data.size());
                show("RGB bits");
            } else {
                memcpy(data16.data(), rgb.data, data16.size() * sizeof(unsigned short));
                show16("RGB16 bits");
            }
}

But when I display image using above show()/show16(), rgb image is being displayed correctly. But YUV image is totally different not even near to RGB.

Example:
Input image: White, R=255, G=255, B=255 for 8 bits
I am able to display this white image in RGB format.
Once I convert RGB image into YUV, and display, it will not be white and in different color.

I am trying to convert RGB to YCbCr444/YUV444 and vice versa.

am I missing something here?

if you throw a yuv image at imread(), it will just map: y → b, u → g, v → r
so indeed it will look funny. it wont convert your yuv image silently back to bgr (which is probably, what you expected), so it would look ‘normal’.
and btw, any other image editor i know, does the same

Thanks Berak, It means to display image, always better to convert it back to BGR and display. Is my understanding correct?

This works now. I am converting back to BGR to display. Thanks Berek.

I see many conversion formats for YCbCr4:2:2 and 4:2:0. which one to use? is there a document explaining all these?
//YUV 4:2:0 formats family
0, // CV_YUV2RGB_NV12 = 90,
0, // CV_YUV2BGR_NV12 = 91,
0, // CV_YUV2RGB_NV21 = 92,
0, // CV_YUV2BGR_NV21 = 93,

    0,                      // CV_YUV2RGBA_NV12 = 94,
    0,                      // CV_YUV2BGRA_NV12 = 95,
    0,                      // CV_YUV2RGBA_NV21 = 96,
    0,                      // CV_YUV2BGRA_NV21 = 97,

    0,                      // CV_YUV2RGB_YV12 = 98,
    0,                      // CV_YUV2BGR_YV12 = 99,
    0,                      // CV_YUV2RGB_IYUV = 100,
    0,                      // CV_YUV2BGR_IYUV = 101,

    0,                      // CV_YUV2RGBA_YV12 = 102,
    0,                      // CV_YUV2BGRA_YV12 = 103,
    0,                      // CV_YUV2RGBA_IYUV = 104,
    0,                      // CV_YUV2BGRA_IYUV = 105,

    0,                      // CV_YUV2GRAY_420 = 106,

    //YUV 4:2:2 formats family
    0,                      // CV_YUV2RGB_UYVY = 107,
    0,                      // CV_YUV2BGR_UYVY = 108,
    0,                      // //CV_YUV2RGB_VYUY = 109,
    0,                      // //CV_YUV2BGR_VYUY = 110,

    0,                      // CV_YUV2RGBA_UYVY = 111,
    0,                      // CV_YUV2BGRA_UYVY = 112,
    0,                      // //CV_YUV2RGBA_VYUY = 113,
    0,                      // //CV_YUV2BGRA_VYUY = 114,

    0,                      // CV_YUV2RGB_YUY2 = 115,
    0,                      // CV_YUV2BGR_YUY2 = 116,
    0,                      // CV_YUV2RGB_YVYU = 117,
    0,                      // CV_YUV2BGR_YVYU = 118,

    0,                      // CV_YUV2RGBA_YUY2 = 119,
    0,                      // CV_YUV2BGRA_YUY2 = 120,
    0,                      // CV_YUV2RGBA_YVYU = 121,
    0,                      // CV_YUV2BGRA_YVYU = 122,

    0,                      // CV_YUV2GRAY_UYVY = 123,
    0,                      // CV_YUV2GRAY_YUY2 = 124,