I have a 10bit raw image (input.yuv) and would like to read it in Matlab. To do so, I am using the following commands:
fid = fopen('input.yuv','r');
a = fread(fid,'uint16');
fclose(fid);
When I get the max(a(:)), it is 730. However, I have white pixels in the image. My question is that:
  1. To get the image data between 0 and 1, should I divid them by (2^16-1) or (2^10-1). The original content is 10bit.
  2. Why I don't get (2^10-1 or 2^16-1) for the white pixels?

 Réponse acceptée

Walter Roberson
Walter Roberson le 17 Mar 2020
Modifié(e) : Walter Roberson le 17 Mar 2020

0 votes

You have not decoded the yuv to its 4:4:2 components.
YUV with 8 bits per channel does not use the full range of values for any component. Also, white is not encoded as the largest possible value: white is U component and V component 0 (they are signed) which gets stored as YCrCb with Cr and Cb = 128 each https://en.m.wikipedia.org/wiki/YUV

13 commentaires

WhiteFlower
WhiteFlower le 17 Mar 2020
Modifié(e) : WhiteFlower le 17 Mar 2020
The image is a frame of a clip encoded as yuv420p10le (extracted using ffmpeg).
WhiteFlower
WhiteFlower le 17 Mar 2020
I would like to preserve 10 bits, not reducing to 8bits. Is frame = fread(fid,'uint16') a right way to read this data before converting to RGB?
There is a possibility that you might need
frame = fread(fid,'*uint16', 0, 'ieee-be');
WhiteFlower
WhiteFlower le 17 Mar 2020
Thank you this works!
WhiteFlower
WhiteFlower le 17 Mar 2020
And one more question. Is this now 10 bits just stored in 16bits? How can I verify that? Is there anyway to handle 10bits in Matlab?
Walter Roberson
Walter Roberson le 17 Mar 2020
There are two possibilities for storing 10 bits in 16. One of the ways is to put the 10 bits into the most significant bits, leaving the bottom 6 bits 0. The other is to put the 10 bits into the least significant bits, leaving the top 6 bits 0. Both are valid methods. It is typically easy to tell which scheme is being used: if any value is 2^10 or more then you are stuffing into the top bits for sure. (There is a marginal case that is not decideable, in the situation where both the top 6 and bottom 6 bits are clear.)
Putting the information into the top (most significant) bits is common for work with sensors like analog to digital work: if you put it into the top then you can substitute sensors with higher resolution without affecting the code.
WhiteFlower
WhiteFlower le 17 Mar 2020
I appreciate your detailed response. Is this something that I can do with the following command?
frame = fread(fid,'*uint10', 0, 'ieee-be');
Is this correct?
No, there is no uint10 precision for fread()
You could do
frame = fread(fid,'ubit10->uint16', 0, 'ieee-be');
but what that would mean is that it would read groups of 10 bits at a time, regardless of word boundaries. The first group of 10 bits would go into the first value, the second group of 10 bits would go into the second value, and so on. some encodings do that, but .yuv files do not tend to do so: they tend to use the full 16 bits of file for each entry.
If you have 10 bits of data in the most significant bits, you can (if you need to) extract the bits using bitget() . Or you could divide by 2^6 to move the bits to the bottom.
WhiteFlower
WhiteFlower le 17 Mar 2020
Thanks a lot again! Here is a summary of my outputs:
frame = fread(fid,'ubit10=>uint16', 0, 'ieee-be') did not work, i.e. the outcome displayed image (after converting yuv to RGB) is scrambled.
The output of frame = fread(fid,'*uint16', 0, 'ieee-be') is 16 bits as I wished, and the max(frame(:)) = 65281 that is very close to my expectation for the white but the displayed image is mostly purple. I probably did not a right conversion or maybe did not correctly imshow 16bit data.
The output of frame = fread(fid,'uint16') is double (however I would like to work with 10bits) and max(frame(:)) = 730 (that does not make sense to me). But the displayed image after conversion to RGB is correct (color wise). However, I am not sure if this is the right way of reading 10bit raw data.
frame = fread(fid,'*uint16');
Would be plausible.
WhiteFlower
WhiteFlower le 18 Mar 2020
The last command works pretty well. Thank you so much for all your help.
Walter Roberson
Walter Roberson le 18 Mar 2020
Routines I find in the file exchange such as https://www.mathworks.com/matlabcentral/fileexchange/6318-convert-yuv-cif-4-2-0-video-file-to-image-files and https://www.mathworks.com/matlabcentral/fileexchange/11318-transform-yuv-file read Y then U then V, but the Microsoft link says that the format is Y then U+V interleaved.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Convert Image Type dans Centre d'aide et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by