I am interested in reading a pgm file in python as a numerical file/matrix
Right now I open the file with
f = open('/home/matthew/NCM/mdb001.pgm', 'rb')
When I read the first line, it looks as expected
r.readline()
produces
'P5\n'
and the next line is fine
'1024 1024\n'
and the next
'255\n'
but then I get a series of gibberish. It looks like some hex values mixed in with other stuff.
I don't want to view the file as an image picture, I just want to see it in this format.
Probabilistic Graphical Models(PGM) are a very solid way of representing joint probability distributions on a set of random variables. It allows users to do inferences in a computationally efficient way.
PGM (Portable Grey Map) files store grayscale 2D images. Each pixel within the image contains only one or two bytes of information (8 or 16 bits). While that might not sound like a lot of information, PGM files can hold tens of thousands of shades — ranging from pure black to white and every shade of grey in between.
msw's answer guided me to write the following function to read 16-bits .pmg images with the kind of header he described :
def read_pgm(pgmf):
"""Return a raster of integers from a PGM as a list of lists."""
header = pgmf.readline()
assert header[:2] == b'P5'
(width, height) = [int(i) for i in header.split()[1:3]]
depth = int(header.split()[3])
assert depth <= 65535
raster = []
for y in range(height):
row = []
for y in range(width):
low_bits = ord(pgmf.read(1))
row.append(low_bits+255*ord(pgmf.read(1)))
raster.append(row)
return raster
f = open(pgm_path, 'rb')
im = read_pgm(f)
f.close()
im = np.array(im)
I hope this helps clarify how to use the previously given answer
After reading the header as you've shown, you've got the width (1024) the height (the next 1024) and the depth (255). To get the pixel data it is easiest to read them byte-by-byte:
def read_pgm(pgmf):
"""Return a raster of integers from a PGM as a list of lists."""
assert pgmf.readline() == 'P5\n'
(width, height) = [int(i) for i in pgmf.readline().split()]
depth = int(pgmf.readline())
assert depth <= 255
raster = []
for y in range(height):
row = []
for y in range(width):
row.append(ord(pgmf.read(1)))
raster.append(row)
return raster
This code will only work for 8-bit depth images which is why the assert
statement is present.
It is legal for a PGM file to have the header information on one line as in:
P5 1024 1024 15
If you do encounter such a file, read_pgm
will fail noisily; the code to handle such cases is left as an exercise for the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With