Ask Your Question
1

Placing UYVY data in a Mat, C++

asked 2019-09-07 13:34:12 -0600

updated 2019-09-07 15:57:02 -0600

Hi,

may this question is not new, but i did not found an answer via google or in this forum.

I have image data in UYVY form (according to fourcc), Like here: http://fourcc.org/pixel-format/yuv-uyvy

For instance: Image width: 100, image height 300. So the data has 200 columns (as it is stored in UYVY it is two times the image width ) and 300 rows of uint8_t values.

So far so simple.

All i want is to get that data in a Mat within C++

What i tried (and this is, i assume, naive)

Let´s say data is the pointer to the data i already have.

Mat frame = Mat(300, 100, CV_8UC2, data); 
imshow("frame", frame);

But i am getting Memory faults.

Do i have to declare the Mat with ... (300,200, ...) as it is UYVY data. I guess not ! ? Also: CV_8UC2 should be correct for UYVY data, right ?

What i am doing wrong ?

Does the Mat somehow need to know, that it is UYVY data? Yes ! But how ? Declaring CV_8UC2 while creating the Mat object (like in the code above) does obviously only create the space, but the mat and so imshow do not know in which order (format) the image data is stored.

My data (and so the pointer) is correct, i checked that. Maybe the problem is, that Mat does store the data not as uint8_t, but as ... whatever --- larger than a byte. that would also be a reason, why i get memory faults.

My problem formulated in one sentence is: How can i get uint8_t data in UYVY order in a Mat?

Thanks a lot for your help in advance.

Best regards

Markus

edit retag flag offensive close merge delete

2 answers

Sort by » oldest newest most voted
1

answered 2019-09-10 14:30:12 -0600

Hello,

thanks for your answer. Splitting and working with cvtColorTwoPlane like suggested crashes. But finally your suggest leads me to the rigth answer:

frame = Mat(300, 200, CV_8UC2,data);
bgrFrame = Mat(300,200, CV_8UC3);
cvtColor(frame, bgrFrame, COLOR_YUV2BGR_UYVY, 0);

bgrFrame is now in the format (and correctly filled) so that it can be displayed for instance with imshow.

UYVY data could be generated like this (full red in this example):

for (int i = 0 ; i < xres  * yres * 2 ; i+=4)
    {
        data[i] = 102;
        data[i+1] = 62;
        data[i+2] = 239;
        data[i+3] = 62;
    }

Where xres and yres is the resolution. Two pixels r = 255, g = 0 and r = 0 are the same us two Pixels UYVY in the order (102,62,239,62)

so, thanks again for your help & best regards

Markus

edit flag offensive delete link more
0

answered 2019-09-08 02:05:59 -0600

LBerger gravatar image

Opencv throws an exception (problem is not with UYVY) :

Mat x(200, 100, CV_8UC2, Scalar(0));
imshow("test", x);
waitKey();

Exception is

OpenCV(4.1.1-dev) Error: Unspecified error (> Invalid number of channels in input image:
'VScn::contains(scn)'
where
'scn' is 2
) in __cdecl cv::impl::`anonymous-namespace'::CvtHelper<struct cv::impl::`anonymous namespace'::Set<3,4,-1>,struct cv::impl::A0x62372b14::Set<3,4,-1>,struct cv::impl::A0x62372b14::Set<0,2,5>,2>::CvtHelper(const class cv::debug_build_guard::_InputArray &,const class cv::debug_build_guard::_OutputArray &,int), file g:\lib\opencv\modules\imgproc\src\color.simd_helpers.hpp, line 92

May be you should try cvtColorTwoPlane :

Mat frame = Mat(300, 100, CV_8UC2, data),dst; 
vector<Mat> p;

split(frame,p);
cvtColorTwoPlane(p[0],p[1],dst,COLOR_YUV2BGR_NV12);

I cannot test this code. I haven't got any image in UYVY format

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2019-09-07 13:34:12 -0600

Seen: 4,651 times

Last updated: Sep 10 '19