Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Mat object from a YV12 image buffer

Tags:

opencv

yuv

I have a buffer which contains an image in YV12 format. Now I want to either convert this buffer to RGB format or create a Mat object from it directly! Can someone help me? I tried this code :

cv::Mat input(widthOfImg, heightOfImg, CV_8UC1, vy12Buffer);
cv::Mat converted;
cv::cvtColor(input, converted, CV_YUV2RGB_YV12);
like image 496
s4eed Avatar asked Sep 11 '13 09:09

s4eed


2 Answers

That's possible.

    cv::Mat picYV12 = cv::Mat(nHeight * 3/2, nWidth, CV_8UC1, yv12DataBuffer);
    cv::Mat picBGR;
    cv::cvtColor(picYV12, picBGR, CV_YUV2BGR_YV12);
    cv::imwrite("test.bmp", picBGR);  //only for test

Opencv color conversion flags

The height is multiplied by 3/2 because there are 4 Y samples, and 1 U and 1 V sample stored for every 2x2 square of pixels. This results in a byte sample to pixel ratio of 3/2

4*1+1+1 samples per 2*2 pixels = 6/4 = 3/2

YV12 Format

Correction: In the last version of OpenCV (i use oldest 2.4.13 version) is color conversion code changed to COLOR_YUV2BGR_YV12

    cv::cvtColor(picYV12, picBGR, COLOR_YUV2BGR_YV12);
like image 194
JaRo Avatar answered Nov 20 '22 00:11

JaRo


here is the corresponding version in java (Android)...

This method was faster than other techniques like renderscript or opengl(glReadPixels) for getting bitmap from yuv12/i420 data stream (tested with webrtc i420 ).

long startTimei = SystemClock.uptimeMillis();

Mat picyv12 = new Mat(768,512,CV_8UC1);  //(im_height*3/2,im_width), should be even no...
picyv12.put(0,0,return_buff); // buffer - byte array with i420 data
Imgproc.cvtColor(picyv12,picyv12,COLOR_YUV2RGB_YV12);// or use COLOR_YUV2BGR_YV12 depending on output result

long endTimei = SystemClock.uptimeMillis();
Log.d("i420_time", Long.toString(endTimei - startTimei));

Log.d("picyv12_size", picyv12.size().toString()); // Check size
Log.d("picyv12_type", String.valueOf(picyv12.type())); // Check type

Utils.matToBitmap(picyv12,tbmp2); // Convert mat to bitmap (height, width) i.e (512,512) - ARGB_888

save(tbmp2,"itest"); // Save bitmap
like image 41
anilsathyan7 Avatar answered Nov 19 '22 23:11

anilsathyan7