在OpenCV中将YUV转换成BGR或RGB

我有一个电视采集卡,以YUV格式input。 我在这里看过类似于这个问题的其他post,试图尝试所有可能的方法,但都没有提供清晰的图像。 目前最好的结果是OpenCV cvCvtColor(scr, dst, CV_YUV2BGR)函数调用。

我目前还不知道YUV格式,说实话,我看起来好像存储了4个频道,但是只有3个? 我已经包含了捕捉卡的图像,希望有人能够理解我可以用来填补空白的事情。

YUV到BGR转换的图像

Feed是通过DeckLink Intensity Pro卡进入的,并且可以在Windows 7环境中使用OpenCV在C ++应用程序中访问。

更新

我已经看过维基百科关于这个信息的文章,并试图在我的应用程序中使用公式。 下面是从它接收输出的代码块。 任何意见是极大的赞赏。

 BYTE* pData; videoFrame->GetBytes((void**)&pData); m_nFrames++; printf("Num Frames executed: %d\n", m_nFrames); for(int i = 0; i < 1280 * 720 * 3; i=i+3) { m_RGB->imageData[i] = pData[i] + pData[i+2]*((1 - 0.299)/0.615); m_RGB->imageData[i+1] = pData[i] - pData[i+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[i+2]*((0.299*(1 - 0.299))/(0.615*0.587)); m_RGB->imageData[i+2] = pData[i] + pData[i+1]*((1 - 0.114)/0.436); } 

尝试RGB转换

它看起来像你正在解码一个YUV422流为YUV444。 尝试对您提供的代码进行修改:

 for(int i = 0, j=0; i < 1280 * 720 * 3; i+=6, j+=4) { m_RGB->imageData[i] = pData[j] + pData[j+3]*((1 - 0.299)/0.615); m_RGB->imageData[i+1] = pData[j] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); m_RGB->imageData[i+2] = pData[j] + pData[j+1]*((1 - 0.114)/0.436); m_RGB->imageData[i+3] = pData[j+2] + pData[j+3]*((1 - 0.299)/0.615); m_RGB->imageData[i+4] = pData[j+2] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); m_RGB->imageData[i+5] = pData[j+2] + pData[j+1]*((1 - 0.114)/0.436); } 

我不确定你的常量是否正确,但最坏的情况是你的颜色会关闭 – 图像应该是可识别的。

在较新版本的OPENCV有一个内置函数可以用来做YUVRGB转换

cvtColor(src,dst,CV_YUV2BGR_YUY2);

在下划线之后指定YUV格式,如此CV_YUYV2BGR_xxxx

BlackMagic Intensity软件在bmdFormat8BitYUV中返回YUVY格式,所以2个源像素被压缩成4个字节 – 我不认为openCV的cvtColor可以处理这个。

你可以自己做,或者只是调用Intensity软件的ConvertFrame()函数

编辑:YUV通常存储为
在这里输入图像说明

对于每个像素有一个Y(亮度),但是对于行中的每个交替像素只有一个U和V(颜色)。

所以如果数据是一个无符号字符指向上面显示的内存的开始。

像素1,Y =数据[0] U =数据[+1] V =数据[+3]
像素2,Y =数据[+2] U =数据[+1] V =数据[+3]

然后使用您的示例代码中使用的YUV-> RGB系数。

这可能是错误的道路,但许多人(我的意思是工程师)将YUV与YCbCr混合使用。

尝试

 cvCvtColor(src, dsc, CV_YCbCr2RGB) 

或CV_YCrCb2RGB或者可能是一个更奇特的类型。

也许有人被颜色模型YCbCr和YUV弄糊涂了。 Opencv不处理YCbCr 相反,它有YCrCb ,它在opencv中的实现方式与YUV相同

从opencv源代码https://github.com/Itseez/opencv/blob/2.4/modules/imgproc/src/color.cpp#L3830

 case CV_BGR2YCrCb: case CV_RGB2YCrCb: case CV_BGR2YUV: case CV_RGB2YUV: // ... // 1 if it is BGR, 0 if it is RGB bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2; //... converting to YUV with the only difference that brings // order of Blue and Red channels (variable bidx) 

但还有一件事要说。
OpenCV分支2.4。*中的转换CV_BGR2YUVCV_RGB2YUV目前存在一个错误

目前,这个公式被用于执行:

 Y = 0.299B + 0.587G + 0.114R U = 0.492(RY) V = 0.877(BY) 

它应该是什么(根据维基百科 ):

 Y = 0.299R + 0.587G + 0.114B U = 0.492(BY) V = 0.877(RY) 

红色和蓝色通道在执行的公式中错位。

在bug未修正的情况下转换BGR-> YUV可能的解决方法:

  cv::Mat source = cv::imread(filename, CV_LOAD_IMAGE_COLOR); cv::Mat yuvSource; cvtColor(source, yuvSource, cv::COLOR_BGR2RGB); // rearranges B and R in the appropriate order cvtColor(yuvSource, yuvSource, cv::COLOR_BGR2YUV); // yuvSource will contain here correct image in YUV color space