在 python 中读取一个 pgm 文件
Read a pgm file in python
我有兴趣阅读 python 中的 pgm 文件作为数字 file/matrix
现在我用
打开文件
f = open('/home/matthew/NCM/mdb001.pgm', 'rb')
当我阅读第一行时,它看起来符合预期
r.readline()
生产
'P5\n'
下一行就可以了
'1024 1024\n'
和下一个
'255\n'
但随后我收到了一系列乱码。它看起来像一些十六进制值与其他东西混合在一起。
我不想以图片形式查看文件,我只想以 this 格式查看它。
如您所示阅读 header 后,您得到了宽度 (1024)、高度(下一个 1024)和深度 (255)。要获取像素数据,最简单的方法是读取它们 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
此代码仅适用于 8 位深度图像,这就是存在 assert
语句的原因。
PGM 文件在一行中包含 header 信息是合法的,例如:
P5 1024 1024 15
如果你真的遇到这样的文件,read_pgm
就会失败;处理此类情况的代码留作 reader.
的练习
msw 的回答指导我编写了以下函数来读取 16 位 .pmg 图像,他描述的 header 类型:
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)
我希望这有助于阐明如何使用之前给出的答案
有趣的是,matplotlib 内置了这个功能。
以下内容应该会为您提供与@GodsFighter 的回答相同的输出。
import matplotlib.pyplot as plt
with open(f, 'rb') as pgmf:
im = plt.imread(pgmf)
我有兴趣阅读 python 中的 pgm 文件作为数字 file/matrix
现在我用
打开文件f = open('/home/matthew/NCM/mdb001.pgm', 'rb')
当我阅读第一行时,它看起来符合预期
r.readline()
生产
'P5\n'
下一行就可以了
'1024 1024\n'
和下一个
'255\n'
但随后我收到了一系列乱码。它看起来像一些十六进制值与其他东西混合在一起。
我不想以图片形式查看文件,我只想以 this 格式查看它。
如您所示阅读 header 后,您得到了宽度 (1024)、高度(下一个 1024)和深度 (255)。要获取像素数据,最简单的方法是读取它们 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
此代码仅适用于 8 位深度图像,这就是存在 assert
语句的原因。
PGM 文件在一行中包含 header 信息是合法的,例如:
P5 1024 1024 15
如果你真的遇到这样的文件,read_pgm
就会失败;处理此类情况的代码留作 reader.
msw 的回答指导我编写了以下函数来读取 16 位 .pmg 图像,他描述的 header 类型:
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)
我希望这有助于阐明如何使用之前给出的答案
有趣的是,matplotlib 内置了这个功能。
以下内容应该会为您提供与@GodsFighter 的回答相同的输出。
import matplotlib.pyplot as plt
with open(f, 'rb') as pgmf:
im = plt.imread(pgmf)