Question

I've started editing the RaspiStillYUV.c code. I eventually want to process the image I receive, but for now, I'm just working to understand it. Why am I working with YUV instead of RGB? So I can learn something new. I've made minor changes to the function camera_buffer_callback. All I am doing is the following:

fprintf(stderr, "GREAT SUCCESS! %d\n", buffer->length);

The line this is replacing:

bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle);

Now, the dimensions should be 2592 x 1944 (w x h) as set in the code. Working off of Wikipedia (YUV420) I have come to the conclusion that the file size should be w * h * 1.5. Since the Y component has 1 byte of data for each pixel and the U and V components have 1 byte of data for every 4 pixels (1 + 1/4 + 1/4 = 1.5). Great. Doing the math in Python:

>>> 2592 * 1944 * 1.5
7558272.0

Unfortunately, this does not line up with the output of my program:

GREAT SUCCESS! 7589376

That leaves a difference of 31104 bytes.

I figure that the buffer is allocated in fixed size chunks (the output size is evenly divisible by 512). While I would like to understand that mystery, I'm fine with the fixed size chunk explanation.

My question is if I am missing something. Are the extra bytes beyond the expected size meaningful in this format? Should they be ignored? Are my calculations off?

Was it helpful?

Solution

The documentation at this location supports your theory on padding: http://www.raspberrypi.org/wp-content/uploads/2013/07/RaspiCam-Documentation.pdf

Specifically:

Note that the image buffers saved in raspistillyuv are padded to a horizontal size divisible by 16 (so there may be unused bytes at the end of each line to made the width divisible by 16). Buffers are also padded vertically to be divisible by 16, and in the YUV mode, each plane of Y,U,V is padded in this way.

So my interpretation of this is the following. The width is 2592 (divisible by 16 so this is ok). The height is 1944 which is 8 short of being divisible by 16 so an extra 8*2592 are added (also multiplied by 1.5) thus giving your 31104 extra bytes.

Although this kindof helps with the size of the file, it doesn't explain the structure of the YUV output properly. I am having a look at this description to see if this provides a hint to start with: http://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversion

From this I believe it is as follows:

Y Channel:

2592 * (1944+8) = 5059584

U Channel:

1296 * (972+4) = 1264896

V Channel:

1296 * (972+4) = 1264896

Giving a sum of :

5059584 + 2*1264896 = 7589376

This makes the numbers add up so only thing left is to confirm if this interpretation is correct.

I am also trying to do the YUV decode (for image comparisons) so if you can confirm if this actually does correspond to what you are reading in the YUV file this would be much appreciated.

OTHER TIPS

You have to read the manual carefully. Buffers are padded to multiples of 16, but colour data is half-size, so your image size needs to be in multiples of 32 to avoid problems with padding breaking external software.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top