How can I read in a RAW image in MATLAB?

I want to open and read a .raw image in MATLAB. My file can be downloaded here. I have tried the following three code snippets, but neither gives the expected results.

Code Snippet #1

    row=576;  col=768;
    fin=fopen('m-001-1.raw','r');
    I=fread(fin,row*col,'uint8=>uint8'); 
    Z=reshape(I,row,col);
    Z=Z';
    k=imshow(Z);

It shows this picture:

first

Code Snippet #2

    f=fopen('m-001-1.raw');
    a=fread(f);
    input_img = reshape(a,768, 576, 3);
    input_img = imrotate(input_img, -90);
    imwrite(input_img, 'm-001-1.jpg'); 

This saves a blank (just white) image in .jpg format.

Code Snippet #3

    id = fopen('m-001-1.raw', 'r');
    x = fread(id, [576,768], 'short');

When I use imshow(x), this picture shows:

third

How do I read this picture correctly?


Your row/col sizes are reversed. Since MATLAB arrays are column-major, and raster images are usually stored row-major, you need to read the image as a [col row] matrix, then transpose it.

row=576;  col=768;
fin=fopen('m-001-1.raw','r');
I=fread(fin, [col row],'uint8=>uint8'); 
Z=I';
k=imshow(Z)

The image replication is happening because you're short 768-576 = 192 pixels per line, so each line is progressively off that amount. After 4 lines, you've made up the difference (4*192 = 768), so you have a 4-image replication.


Peter's code (thanks btw!) works assuming that your image is grayscale. For colour images, what you need to do is read in all of the bytes as a single 1D array as we can't use fread to read the data is in as a 3D matrix (at least not to my knowledge...). After, we then reshape it so that it becomes a 3D matrix. After we reshape the matrix, notice that this is the transposed result. As such, we will have to either transpose each channel independently, or you can cleverly combine flipdim and imrotate to do the 3D transpose for us. I would rotate the image so that it's 90 degrees clockwise, but this would make the image mirror reflected across the columns. I then use flipdim with the second parameter as 2 as I want to mirror reflect across the columns to get the original image back.

As such, what you would actually have to do is this:

row=576;  col=768;
fin=fopen('m-001-1.raw','r');
I=fread(fin, col*row*3,'uint8=>uint8'); %// Read in as a single byte stream
I = reshape(I, [col row 3]); %// Reshape so that it's a 3D matrix - Note that this is column major
Ifinal = flipdim(imrotate(I, -90),2); % // The clever transpose
imshow(Ifinal);
fclose(fin); %// Close the file

What I get is this image:

enter image description here


Alternatively, you can certainly use Peter's code, but you would use it so that you would reconstruct the image one colour plane at a time. In other words, you can do this:

row=576;  col=768;
fin=fopen('m-001-1.raw','r');
I1=fread(fin, [col row],'uint8=>uint8'); %// Red channel
I2=fread(fin, [col row],'uint8=>uint8'); %// Green channel
I3=fread(fin, [col row],'uint8=>uint8'); %// Blue channel
I1 = I1.'; I2 = I2.'; I3 = I3.'; %// Transpose each channel separately
Ifinal = cat(3, I1, I2, I3); %// Create 3D matrix
imshow(Ifinal);
fclose(fin);

You'll get exactly the same image as above.