问题
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