17

The formula says:

Y = 0.299 * R + 0.587 * G + 0.114 * B;

U = -0.14713 * R - 0.28886 * G + 0.436 * B;

V = 0.615 * R - 0.51499 * G - 0.10001 * B;

What if, for example, the U variable becomes negative?

U = -0.14713 * R - 0.28886 * G + 0.436 * B;

Assume maximum values for R and G (ones) and B = 0 So, I am interested in implementing this convetion function in OpenCV, So, how to deal with negative values? Using float image? anyway please explain me, may be I don't understand something..

Jacob
  • 34,255
  • 14
  • 110
  • 165
maximus
  • 4,201
  • 15
  • 64
  • 117

3 Answers3

14

Y, U and V are all allowed to be negative when represented by decimals, according to the YUV color plane.

YUV Color space

Community
  • 1
  • 1
Dolph
  • 49,714
  • 13
  • 63
  • 88
13

You can convert RGB<->YUV in OpenCV with cvtColor using the code CV_YCrCb2RGB for YUV->RGB and CV_RGBYCrCb for RGB->YUV.

void cvCvtColor(const CvArr* src, CvArr* dst, int code)

Converts an image from one color space to another.

Jacob
  • 34,255
  • 14
  • 110
  • 165
  • Thank you!! I searched for such a function and I thought that YCrCb is something different than YUV... – maximus May 25 '10 at 16:39
  • No problem. Note that you can convert 3-channel images as well. If you need to merge the Y,U and Vcomponents, you can do that with `merge` which takes a `vector` object. – Jacob May 25 '10 at 17:20
  • 3
    @maximus - strictly speaking it is. YUV is for analogue TV standard YCrCb is digital - the color space is different. But only very slightly – Martin Beckett Jan 17 '12 at 19:34
  • In C++: cv::cvtColor(image, yuv_image, CV_RGB2YCrCb); – Lucas Walter Mar 14 '15 at 22:47
  • Keep in mind that there is currently a bug in opencv 2.4.*, which causes incorrect convertation from RGB to YUV. *Red* and *Blue* channels are *swapped* in the implemented formula. http://code.opencv.org/issues/4227 – Temak Apr 27 '15 at 08:11
  • Look at detailed post about the bug here http://stackoverflow.com/a/29890941/1351629 – Temak Apr 27 '15 at 08:43
2

for planar formats OpenCV is not the right tool for the job. Instead you are better off using ffmpeg. for example

static void rgbToYuv(byte* src, byte* dst, int width,int height)
{

    byte* src_planes[3] = {src,src + width*height, src+ (width*height*3/2)};
    int src_stride[3] = {width, width / 2, width / 2};
    byte* dest_planes[3] = {dst,NULL,NULL};
    int dest_stride[3] = {width*4,0,0};
    struct SwsContext *img_convert_ctx = sws_getContext(
        width,height,
        PIX_FMT_YUV420P,width,height,PIX_FMT_RGB32,SWS_POINT,NULL,NULL,NULL);
        sws_scale(img_convert_ctx, src_planes,src_stride,0,height,dest_planes,dest_stride); 
    sws_freeContext(img_convert_ctx);
}

will convert a YUV420 image to RGB32

Yaur
  • 7,333
  • 1
  • 25
  • 36