如何处理RGB到YUV的转换

17

这个公式的意思是:

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;

如果U变量变为负数,会怎样呢?

U = -0.14713 * R - 0.28886 * G + 0.436 * B;
假设R和G的值都取最大值(即1),而B的值为0。 因此,我想在OpenCV中实现这个协定函数, 那么,如何处理负值? 使用浮点图像?无论如何,请解释一下,也许我还没有完全理解。
3个回答

14

根据YUV颜色平面,当以小数表示时,Y、U和V都允许为负数。

YUV颜色空间


13

您可以使用cvtColor在OpenCV中进行RGB<->YUV转换,其中对于YUV->RGB使用CV_YCrCb2RGB代码,而对于RGB->YUV使用CV_RGBYCrCb代码。

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

将一张图片从一个色彩空间转换到另一个。


谢谢!我搜索了这样一个函数,我认为YCrCb与YUV不同... - maximus
没问题。请注意,您也可以转换3通道图像。如果您需要合并Y、U和V分量,可以使用merge函数,该函数接受一个vector<Mat>对象。 - Jacob
3
@maximus - 严格来说是这样的。YUV用于模拟电视标准,而YCrCb用于数字标准 - 色彩空间不同。但仅仅是有微小差异。 - Martin Beckett
在C++中:cv::cvtColor(image, yuv_image, CV_RGB2YCrCb); - Lucas Walter
请注意,目前opencv 2.4.中存在一个错误,导致从RGB转换为YUV时出现不正确的转换。在实现的公式中,红色蓝色通道被交换*了。 http://code.opencv.org/issues/4227 - Temak
请查看有关此错误的详细帖子,网址为https://dev59.com/aGsz5IYBdhLWcg3wWmfL#29890941。 - Temak

2

对于平面格式,OpenCV并不是最适合的工具。相反,最好使用ffmpeg。例如:

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);
}

将 YUV420 图像转换为 RGB32。


有趣的方法 :) - maximus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接