使用Python和PIL模块导入PPM图像

2 投票
6 回答
33918 浏览
提问于 2025-04-16 06:35

我需要一种方法,可以读取文件中的每一行,并提取像素信息到某种结构中,这样我就可以使用putpixel函数根据ppm p3文件创建一张图片。

我正在使用Python图像库(PIL),我想打开一张PPM格式的图片,并在屏幕上显示出来。

我该如何仅使用PIL来实现这个呢?

这是我的ppm图片。它只是我创建的一个7x1的图片。

P3
# size 7x1
7 1
255
0
0
0
201
24
24
24
201
45
24
54
201
201
24
182
24
201
178
104
59
14

6 个回答

4

一些背景概念,使用你的例子:

  • .ppm 是一种图像数据存储的文件格式,它让人更容易看懂。

  • 它的全称是可移植像素图格式(Portable PixMap format)。

  • 这些文件通常是以下格式:

# Optional Comments likes this one
# The first line is the image header which contains the format followed by width and height
P3 7 1
# Second line contains the maximum value possible for each color point
255
# Third line onwards, it contains the pixels represented in rows(7) and columns(1)
0 0 0
201 24 24 
24 201 45 
24 54 201
201 24 182 
24 201 178 
104 59 14

参考链接

所以你可以看到,你已经正确地重写了你的PPM文件(因为在彩色图像中,每个像素都考虑了RGB三元组)。

打开和查看文件

OpenCV(表现非常出色)

import cv2
import matplotlib.pyplot as plt
img = cv2.imread("\path to the image")
# Remember, opencv by default reads images in BGR rather than RGB
# So we fix that by the following
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
# Now, for small images like yours or any similar ones we use for example purpose to understand image processing operations or computer graphics
# Using opencv's cv2.imshow()
# Or google.colab.patches.cv2_imshow() [in case we are on Google Colab]
# Would not be of much use as the output would be very small to visualize
# Instead using matplotlib.pyplot.imshow() would give a decent visualization
plt.imshow(img)

Pillow(我们也称它为PIL)

虽然文档上说我们可以直接打开.ppm文件,使用:

from PIL import Image
img = Image.open("path_to_file")

参考链接

但是,当我们进一步检查时,我们会发现它们只支持二进制版本(也叫P6的PPM),而不支持ASCII版本(也叫P3的PPM)。

参考链接

因此,对于你的使用情况,使用PIL并不是一个理想的选择❌。

使用matplotlib.pyplot.imshow()进行可视化的好处仍然适用。

6

如果你喜欢使用 np.array 这种对象,那就这样做:

>>> from scipy.misc import imread
>>> img = imread(path_to_ppm_file)
>>> img.shape
>>> (234, 555, 3)
2

编辑:在你修改了问题并允许大家只看内容后,可以查看下面的链接。它解释了如何写一个包装器来加载文件。我也准备自己测试一下,应该是可以的……


目前(2010年11月),你无法用PIL打开普通的PPM图像。这里的普通指的是ascii格式。不过,二进制格式是可以的。主要原因是ascii文件每个像素的位数不固定,而PIL中的图像加载器是基于每个像素位数固定的假设。关于这个问题,我还有一个相关的问题:

如何为普通的pgm格式编写PIL图像过滤器?

我计划为普通的PPM格式写一个PIL过滤器,但我时间不够。如果你有兴趣帮忙,请告诉我。

祝好,
Juha

撰写回答