我正在尝试将一张黑白的.jpg
图像转换为列表,然后可以将其调制成音频信号。
我已经导入了PIL模块,并尝试调用内置函数:list(im.getdata())
。当我调用它时,Python崩溃了。有没有一种方法将图像(始终为320x240)分解成240行,以便更轻松地进行计算?或者我只是调用了错误的函数?
我正在尝试将一张黑白的.jpg
图像转换为列表,然后可以将其调制成音频信号。
我已经导入了PIL模块,并尝试调用内置函数:list(im.getdata())
。当我调用它时,Python崩溃了。有没有一种方法将图像(始终为320x240)分解成240行,以便更轻松地进行计算?或者我只是调用了错误的函数?
当您调用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)]
list(im.getdata())
的调用导致 Python 崩溃。该代码片段用于将图像数据转换为列表形式。 - SilentGhostpixels=im.getdata()
(它返回一种特殊的、简化的列表类型),一切都很好。但是如果我添加了强制转换,Python就开始使用大量RAM,如果可用的PC不足,它就开始交换,最终崩溃。也许使用一个python列表来保存数百万个像素值有点过头了。 - jesjimherpixels = np.array(im.getdata()).reshape((im.size[1], im.size[0]))
- Bill如果您已经安装了numpy,您可以尝试以下命令:
data = numpy.asarray(im)
我这里使用“尝试”(try)一词是因为不清楚为什么您的getdata()
方法无法正常工作,也不确定asarray
方法是否使用了getdata()
方法,但进行测试是值得的。
我猜你遇到了这样的错误:TypeError: 'PixelAccess' object is not iterable
,对吗?
查看Image.load文档以了解如何访问像素。
基本上,使用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)
这将每个像素附加到all_pixels
列表中 - 如果该文件是RGB图像(即使它只包含黑白图像),则每个像素都将表示为元组,例如:
(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)
或者获取亮度(加权平均值):
cpixel = pixels[x, y]
luma = (0.3 * cpixel[0]) + (0.59 * cpixel[1]) + (0.11 * cpixel[2])
all_pixels.append(luma)
或者是纯粹的一位黑白:
cpixel = pixels[x, y]
if round(sum(cpixel)) / float(len(cpixel)) > 127:
all_pixels.append(255)
else:
all_pixels.append(0)
在PIL中可能有更快的方法来进行RGB到二值图像的转换,但这个方法可以工作,并且不是特别慢。
如果你只想对每一行执行计算,你可以跳过将所有像素添加到一个中间列表的步骤。例如,计算每一行的平均值:
from PIL import Image
i = Image.open("myfile.png")
pixels = i.load() # this is not a list
width, height = i.size
row_averages = []
for y in range(height):
cur_row_ttl = 0
for x in range(width):
cur_pixel = pixels[x, y]
cur_pixel_mono = sum(cur_pixel) / len(cur_pixel)
cur_row_ttl += cur_pixel_mono
cur_row_avg = cur_row_ttl / width
row_averages.append(cur_row_avg)
print "Brighest row:",
print max(row_averages)
虽然不是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
scipy.misc.imread
is now deprecated, use`import imageioim=imageio.imread('sogreche.jpg')` - Alessandro Jacopson如果你想计算白色或黑色像素,以下是解决方案:
这也是一种解决方法:
from PIL import Image
import operator
img = Image.open("your_file.png").convert('1')
black, white = img.getcolors()
print black[0]
print white[0]
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)]
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)
tostring()
改为 tobytes()
。 当我尝试提取 RGBA 像素以将它们放入 OpenGL 纹理中时,以下代码适用于我(在 glTexImage2D
调用内,我省略了它的长度)。from PIL import Image
img = Image.open("mandrill.png").rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
# use img.convert("RGBA").tobytes() as texels