我有来自相机(PAL)的数据流 我从回调函数得到的数据类型格式为U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4-Y4-V4-Y5 ......
我需要使用OpenCV的cvCvtColor()函数将颜色格式更改为RGB(或BGR)。该功能的用法是 cvCvtColor(YCrCb,dst,CV_YCrCb2BGR); 现在这里(实际上是之前)出现问题,dst是一个3通道8U图像,没关系,但是如何直接在IplImage中存储来自回调函数的数据呢?如果我可以正确存储它,我可以使用cvCvtColor()来转换图像。任何功能,任何其他库? 如果我在每个帧中使用RGB< - > YUV数学转换,那么会导致70%的CPU使用率,所以我不想使用它们,我正在寻找一种更简单的CPU方式。
答案 0 :(得分:2)
如果你的输入格式是YUY2,那么它实际上是Y-U-Y-V,我的例子假设如下。但是,如果您的格式确实是U-Y-V-Y,只需更改示例或颜色空间中的顺序(请参阅下面的注释)。
您可以通过双通道Mat阵列将此YUY2 / YUYV422数据呈现给OpenCV。
有两种方法可以填充Mat img:通过复制和引用。根据您的应用程序,您可以选择。
两者都假设您在char数组image_yuv
中有yuv数据。
1a上。通过引用原始数据(没有mem alloc; fast):
Mat img(height, width, CV_8UC2, img_yuv);
1b中。通过将数据复制到Mat:
Mat img(height, width, CV_8UC2);
uchar *pix = img.ptr<uchar>(r); // first byte of the row in image
for (int r = 0, b=0; r < height; r++) {
for (int c = 0; c < width; c+=4) {
*pix++ = image_yuv[b++]; // y
*pix++ = image_yuv[b++]; // u
*pix++ = image_yuv[b++]; // y
*pix++ = image_yuv[b++]; // v
}
}
现在您已经在Mat img中拥有了数据,您可以使用cvtColor将其转换为其他颜色空间:
2a上。改为BGR:
cvtColor(img, img_p, COLOR_YUV2BGR_YUY2);
imshow("window", img_p);
2B。改为灰度:
cvtColor(img, img_p, COLOR_YUV2GRAY_YUY2);
imshow("window", img_p);
注意:如果您的格式为U-Y-V-Y,请更改复印顺序或更改色彩空间(COLOR_YUV2BGR_UYVY或COLOR_YUV2GRAY_UYVY)。请参阅OpenCV源代码中的imgproc.hpp。
答案 1 :(得分:0)
我会像这样为帧缓冲区创建一个Iplimage头:
IplImage* header = cvCreateImageHeader(cvSize(width,height), IPL_DEPTH_8U, 3);
headercopy->widthStep = width*3;//I hope this will right for you... :)
headercopy->imageData = (char*) bufferstart;
你现在可以使用Iplimage标头作为普通的Iplimage希望就是这样。 对于转换,您可能需要分配一个新的IplImage对象!
答案 2 :(得分:0)
IIRC openCV不支持交错YUV,它只支持平面YUV420 / YUV422,其中整个图像的Y数据首先是降低分辨率U和V(由JPEG使用)
您可以将数据重新排序到平面中,也可以使用此formulae here中的Converting YUV->RGB(Image processing)->YUV during onPreviewFrame in android?或更快的整数版本自行生成RGB数据{{3}}
答案 3 :(得分:0)
我还发现这个代码只是将YUV 4:2:2转换为rgb也许这可能是有用的.... convert YUV422 to RGB24(不,不是) 但也许我发现的其他网站可能更有用。他没有提供任何代码将图像转换为opencv标准RGB24,因此您必须了解c代码并使其适应opencv标准: http://wss.co.uk/pinknoise/yuv2rgb/
不知怎的,我找不到任何好的解决方案......