从PIL获取像素值列表

时间:2009-07-10 13:08:07

标签: python image python-imaging-library

伙计们,我正在寻求一些帮助。我是一个新手程序员,我现在遇到的一个问题是试图转换黑色&将白色.jpg图像放入一个列表,然后我可以将其调制为音频信号。这是创建python SSTV程序的大项目的一部分。

我已导入PIL模块,并尝试调用内置函数:list(im.getdata())。当我调用它时,python崩溃了。有没有办法将图像(总是320x240)分解为240行,以使计算更容易?或者我只是说错了功能。

如果有人有任何建议请开火。如果有人有使用python生成调制音频音调的经验,我很乐意接受他们愿意传授的任何“智慧珍珠”。 提前致谢

9 个答案:

答案 0 :(得分:54)

调用getdata()时,Python不应该崩溃。图像可能已损坏或PIL安装有问题。尝试使用其他图像或张贴您正在使用的图像。

这应该按照你想要的方式分解图像:

from PIL import Image
im = Image.open('um_000000.png')

pixels = list(im.getdata())
width, height = im.size
pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)]

答案 1 :(得分:32)

如果您安装了numpy,可以尝试:

data = numpy.asarray(im)

(我在这里说“试试”,因为我不清楚为什么getdata()不适合你,我不知道asarray是否使用了getdata,但是值得一试。)< / p>

答案 2 :(得分:14)

我认为您收到的错误如{。{1}} ...?

请参阅Image.load文档,了解如何访问像素..

基本上,要使用TypeError: 'PixelAccess' object is not iterable

获取图像中的像素列表
PIL

将每个像素附加到from PIL import Image i = Image.open("myfile.png") pixels = i.load() # this is not a list, nor is it list()'able width, height = i.size all_pixels = [] for x in range(width): for y in range(height): cpixel = pixels[x, y] all_pixels.append(cpixel) - 如果文件是RGB图像(即使它只包含黑白图像),这些将是一个元组,例如:

all_pixels

要将图像转换为单色,您只需对三个值进行平均 - 因此,最后三行代码将变为..

(255, 255, 255)

或者获得亮度(加权平均值):

cpixel = pixels[x, y]
bw_value = int(round(sum(cpixel) / float(len(cpixel))))
# the above could probably be bw_value = sum(cpixel)/len(cpixel)
all_pixels.append(bw_value)

或纯粹的1位黑白色:

cpixel = pixels[x, y]
luma = (0.3 * cpixel[0]) + (0.59 * cpixel[1]) + (0.11 * cpixel[2])
all_pixels.append(luma)

PIL中可能有一些方法可以更快地进行此类cpixel = pixels[x, y] if round(sum(cpixel)) / float(len(cpixel)) > 127: all_pixels.append(255) else: all_pixels.append(0) 次转换,但这样做有效,并且速度不是特别慢。

如果您只想对每一行执行计算,则可以跳过将所有像素添加到中间列表中。例如,要计算每行的平均值:

RGB -> BW

答案 3 :(得分:3)

或者,如果您想计算白色或黑色像素

这也是一个解决方案:

from PIL import Image
import operator

img = Image.open("your_file.png").convert('1')
black, white = img.getcolors()

print black[0]
print white[0]

答案 4 :(得分:2)

不是PIL,但scipy.misc.imread可能仍然很有趣:

import scipy.misc
im = scipy.misc.imread('um_000000.png', flatten=False, mode='RGB')
print(im.shape)

给出

(480, 640, 3)

所以它是(高度,宽度,通道)。所以你可以通过

迭代它
for y in range(im.shape[0]):
    for x in range(im.shape[1]):
        color = tuple(im[y][x])
        r, g, b = color

答案 5 :(得分:1)

正如我上面评论的那样,问题似乎是从PIL内部列表格式转换为标准的python列表类型。我发现Image.tostring()更快,根据您的需要,它可能已经足够了。在我的情况下,我需要计算图像数据的CRC32摘要,它很适合。

如果您需要执行更复杂的计算,那么涉及numpy的tom10响应可能就是您所需要的。

答案 6 :(得分:1)

PILlow看起来可能已将primes (i:remNums) = x : primes (filter (\x -> mod x i /= 0) remNums) 更改为tostring()。当试图提取RGBA像素以使它们进入OpenGL纹理时,以下内容对我有效(在tobytes()调用中,为了简洁我省略了它。)

glTexImage2D

答案 7 :(得分:1)

data = numpy.asarray(im)

注意:在PIL中,img是RGBA。在cv2中,img是BGRA。

我的强大解决方案:

def cv_from_pil_img(pil_img):
    assert pil_img.mode=="RGBA"
    return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGBA2BGRA)

答案 8 :(得分:1)

pixVals = list(pilImg.getdata())

输出是图片中所有RGB值的列表:

[(248, 246, 247), (246, 248, 247), (244, 248, 247), (244, 248, 247), (246, 248, 247), (248, 246, 247), (250, 246, 247), (251, 245, 247), (253, 244, 247), (254, 243, 247)]