【发布时间】:2011-05-15 07:36:18
【问题描述】:
如何为 pgm 纯 ascii 格式 (P2) 的 python 成像库编写过滤器。这里的问题是基本 PIL 过滤器假定每个像素的字节数是恒定的。
我的目标是用 Image.open() 打开feep.pgm。请参阅http://netpbm.sourceforge.net/doc/pgm.html 或以下。
另一种解决方案是我找到了 PIL 和所有主要图形程序支持的其他有据可查的 ascii 灰度格式。有什么建议吗?
feep.pgm:
P2
# feep.pgm
24 7
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
编辑:感谢您的回答,它可以工作... 但是我需要一个使用 Image.open() 的解决方案。大多数 python 程序都使用 PIL 进行图形操作(谷歌:python image open)。因此,我需要能够向 PIL 注册一个过滤器。然后,我可以使用任何使用 PIL 的软件。我现在想的主要是scipy、pylab等依赖程序。
编辑好的,我想我现在明白了。下面是包装器 pgm2pil.py:
import Image
import numpy
def pgm2pil(filename):
try:
inFile = open(filename)
header = None
size = None
maxGray = None
data = []
for line in inFile:
stripped = line.strip()
if stripped[0] == '#':
continue
elif header == None:
if stripped != 'P2': return None
header = stripped
elif size == None:
size = map(int, stripped.split())
elif maxGray == None:
maxGray = int(stripped)
else:
for item in stripped.split():
data.append(int(item.strip()))
data = numpy.reshape(data, (size[1],size[0]))/float(maxGray)*255
return numpy.flipud(data)
except:
pass
return None
def imageOpenWrapper(fname):
pgm = pgm2pil(fname)
if pgm is not None:
return Image.fromarray(pgm)
return origImageOpen(fname)
origImageOpen = Image.open
Image.open = imageOpenWrapper
misha 的回答略有升级。必须保存 Image.open 以防止永无止境的循环。如果 pgm2pil 返回 None 包装调用 pgm2pil 返回 None 调用 pgm2pil...
下面是测试函数(feep_false.pgm 是格式错误的 pgm,例如 "P2" -> "FOO" 而 lena.pgm 只是 图像文件):
import pgm2pil
import pylab
try:
pylab.imread('feep_false.pgm')
except IOError:
pass
else:
raise ValueError("feep_false should fail")
pylab.subplot(2,1,1)
a = pylab.imread('feep.pgm')
pylab.imshow(a)
pylab.subplot(2,1,2)
b = pylab.imread('lena.png')
pylab.imshow(b)
pylab.show()
【问题讨论】:
-
谢谢。但是,为什么要返回 numpy.flipud(data)?我只需要返回数据。
-
很久以前我这样做了...原因是图像不在笛卡尔坐标系中(反转y轴)。恕我直言,图像应该在没有翻转的笛卡尔系统中(或者有翻转,我不记得是哪种方式)。最后,使用 imread 和 imshow 时,上面正确显示了图像。
-
啊……这很有道理。我早该想到的。再次感谢。
标签: python image image-processing python-imaging-library