Channel and Bit values of a YUV2 data

人走茶凉 提交于 2019-12-11 11:00:00

问题


I have a data stream coming from a Camera(PAL) The data type I got from callback function is in a format like U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4-Y4-V4-Y5 ......

I need to change the color format to RGB (or BGR) by using OpenCV's cvCvtColor() function. Usage of the function is cvCvtColor(YCrCb, dst, CV_YCrCb2BGR); Now here(actually before) comes the problem, dst is a 3 channel 8U image, thats OK, but how can I store the data coming from callback function in an IplImage directly ? If I can store it correctly, I can use cvCvtColor() to convert the image. Any function, any other libraries? If I use RGB<->YUV mathematical conversion in every frame, that results in 70%++ CPU usage so I don't want to use them, I'm looking for a more easier way for CPU.


回答1:


If your input format is YUY2, then it is actually Y-U-Y-V and my example below assumes that. However, if your format is indeed U-Y-V-Y, just change the order in my example or color space (see notes below).

You can present this YUY2/YUYV422 data to OpenCV via a 2-channel Mat array.

There are two ways you can fill the Mat img: By copy and by reference. Depending on your application, you can choose either.

Both assume you have yuv data in a char array image_yuv.

1a. By reference to original data (without mem alloc; fast):

Mat img(height, width, CV_8UC2, img_yuv);

1b. By copying data into 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
    }
}

Now that you have your data in Mat img, you can use cvtColor to convert it to other color spaces:

2a. Change to BGR:

cvtColor(img, img_p, COLOR_YUV2BGR_YUY2);
imshow("window", img_p);

2b. Change to grayscale:

cvtColor(img, img_p, COLOR_YUV2GRAY_YUY2);
imshow("window", img_p);

Note: If your format is U-Y-V-Y, either change the copy order, or change color space (COLOR_YUV2BGR_UYVY or COLOR_YUV2GRAY_UYVY). See imgproc.hpp in OpenCV source code.




回答2:


I would make a Iplimage header for the frame buffer like this:

    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;

You can now use the Iplimage header as a normal Iplimage hope that was it. For the conversion you will maybe need to allocate a new IplImage object!




回答3:


IIRC openCV doesn't support interleaved YUV it only does planar YUV420/YUV422 where the Y data for the entire image is first followed by reduced resolution U and V (as used by JPEG)

You can either re-order the data into planes or simply generate the RGB data yourself using the formulae here or the faster integer version in this answer Converting YUV->RGB(Image processing)->YUV during onPreviewFrame in android?




回答4:


I also found this code for just transforming YUV 4:2:2 to rgb maybe this could be usefull.... convert YUV422 to RGB24 (no this not) But maybe this other site I found could be more useful. He doesn t give any code for converting the image to opencv standard RGB24 so you will have to understand the c code and adapt it for opencv standard: http://wss.co.uk/pinknoise/yuv2rgb/

somehow I can t find any good solution....



来源:https://stackoverflow.com/questions/11541795/channel-and-bit-values-of-a-yuv2-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!