How I can read image with PPM format without imread and design PPM reader ?

I want to read test.ppm image without imread and design PPM reader and open it with fopen and extract data from it after that show it with imshow.
Can you help me?

7 Comments

Find the format specification:
Read the file with fread() or something
split the header, etc from the raster data
based on the information in the header, do whatever needs to be done to convert the raster data into a MxNx3 numeric array.
I can't find any code example for read ppm file. I attached my file.
Could you please help me with code example?
Why do you not want to use the built-in imread() and try to write your own ppm reader (or actually have us write it for you)? What's wrong with using imread()????
I want to understand how i can read this format file without imread function.
We know that. You already said that earlier. I was curious as to why.
And DGM already gave you a start, so just continue on with that. You accepted it (thanks), so I guess that's what you're planning on.
What is the reason that you cannot use imread() ?

Sign in to comment.

 Accepted Answer

Again, the documentation
As an example for this one image, consider the following.
% open the file and read the whole thing
fid = fopen('Barbara.pgm', 'r');
B = fread(fid,inf,'uint8=>char')';
fclose(fid);
% find header delimiters
ws = find(isspace(B),4,'first')
% get file parts (assuming no comments)
magicnum = B(1:ws(1)-1) % this is expected to be P5
% if P2, P3, or P6, do whatever is needed
imgeometry = [str2double(B(ws(1)+1:ws(2)-1)) str2double(B(ws(2)+1:ws(3)-1))]
maxgval = str2double(B(ws(3)+1:ws(4)-1)) % expected to be 255
imgdata = permute(reshape(double(B(ws(4)+1:end)),imgeometry),[2 1 3]);
% normalize the image for convenience
imgdata = imgdata/maxgval;
imshow(imgdata)
Note that this code is not robust and does not accomodate the existence of inline comments in the file. You'll have to deal with that.
This code also assumes that the max gray value stays below 256. If maxgval>255, then you'll have to do some reshaping and simple math because each pixel will be represented by byte pairs instead of single bytes.
If your project needs to read both PGM and PPM files of both types, then you'll have to conditionally handle those cases based on the magic number.
If you want an integer-class numeric array as output instead of a normalized floating-point array, you'll have to conditionally look at the max gray value and cast the image data accordingly.

4 Comments

Thanks a lot. for ppm format i got this error Number of elements must not change. Use [] as one of the size inputs to automatically calculate .
Error in test (line 15)
imgdata = permute(reshape(double(B(ws(4)+1:end)),imgeometry),[2 1 3]);
Could you please explain for me the above code in line 15?
How i can do this for ppm format?
I attached ppm file and i want to use this code for that.
Please explain these three lines of code.
imgeometry = [str2double(B(ws(1)+1:ws(2)-1)) str2double(B(ws(2)+1:ws(3)-1))]
maxgval = str2double(B(ws(3)+1:ws(4)-1)) % expected to be 255
imgdata = permute(reshape(double(B(ws(4)+1:end)),imgeometry),[2 1 3]);
Like I said; that example is only made to handle the specific subset of options presented by that particular image. It assumes that the image is a P5 (regular PGM) image. For other types of images in the same family, you'll have to write some conditional statement to check the magic number and deal with the data accordingly. For a P6 PPM, each pixel is represented by a sequence of either three or six bytes (as opposed to only one or two bytes in a P5 PGM file).
When the file is read, the result stored in B is a single long character vector. The following lines simply index into the vector B and extract the relevant subvectors.
% extract image width and height, convert from char to numbers
imgeometry = [str2double(B(ws(1)+1:ws(2)-1)) str2double(B(ws(2)+1:ws(3)-1))]
% extract maximum pixel value, convert from char to number
maxgval = str2double(B(ws(3)+1:ws(4)-1)) % expected to be 255
% extract image data as a vector, reshape into a 2D array according to the specified geometry, transpose
imgdata = permute(reshape(double(B(ws(4)+1:end)),imgeometry),[2 1 3]);
For a P6 PPM with maxgval<256, everything is similar. The only difference is in the array reshaping.
% open the file and read the whole thing
fid = fopen('Brain.ppm', 'r');
B = fread(fid,inf,'uint8=>char')';
fclose(fid);
% find header delimiters
ws = find(isspace(B),4,'first')
% get file parts (assuming no comments)
magicnum = B(1:ws(1)-1) % this is expected to be P6
% if P2, P3, or P5, do whatever is needed
imgeometry = [str2double(B(ws(1)+1:ws(2)-1)) str2double(B(ws(2)+1:ws(3)-1))]
maxgval = str2double(B(ws(3)+1:ws(4)-1)) % assumed to be <256
imgdata = reshape(double(B(ws(4)+1:end)),3,[]); % reshape into 3x(M*N) list of color tuples
imgdata = reshape(permute(imgdata,[2 3 1]),[imgeometry 3]); % reshape into MxNx3 array
imgdata = permute(imgdata,[2 1 3]); % transpose
% normalize the image for convenience
imgdata = imgdata/maxgval;
imshow(imgdata)
Again, this is still not robust and doesn't cover everything.

Sign in to comment.

More Answers (2)

fopen the file and read it as a series of uint8. fclose(). Now use loadlibrary() to make a call to the libnetpbm library to decode the uint8 into an image.
By the way, is it a P3 or P6?

2 Comments

I don't know . How i can understand that?
I attached my file. How i can use loadlibrary() with this file?
PPM files do not all have exactly the same layout. The very first item inside a PPM file gives information about which of the formats the rest of the file is in. Two of the most common formats are known by the codes P3 and P6.
If you need to be able to handle all possible PPM files, then you have to do notably more work than if you only have to handle one particular kind of PPM file.

Sign in to comment.

Categories

Find more on Convert Image Type in Help Center and File Exchange

Asked:

on 25 Nov 2021

Commented:

on 26 Nov 2021

Community Treasure Hunt

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

Start Hunting!