Мой код приведен ниже, я хочу распечатать средний пиксель, используя код .averagePixels в PIL, но возвращаемый объект «int» не является итерируемым. Любой может помочь в этом
from PIL import Image
class PixelCounter(object):
def __init__(self, imageName):
self.pic = Image.open(imageName)
self.imgData = self.pic.load()
def averagePixels(self):
r, g, b = 0, 0, 0
count = 0
for x in range(self.pic.size[0]):
for y in range(self.pic.size[1]):
tempr,tempg,clrs = self.imgData[x,y]
r += clrs[0]
g += clrs[1]
b += clrs[2]
count += 1
yield ((r/count)(g/count),(b/count), count)
if __name__ == '__main__':
x=[]
pc = PixelCounter(r"C:\Users\lena-gs.png")
print ("(red, green, blue, total_pixel_count)")
print (list(pc.averagePixels()))
вывод:
(red, green, blue, total_pixel_count)
TypeError Traceback (most recent call last)
<ipython-input-121-4b7fee4299ad> in <module>()
19 pc = PixelCounter(r"C:\Users\user\Desktop\lena-gs.png")
20 print ("(red, green, blue, total_pixel_count)")
---> 21 print (list(pc.averagePixels()))
22
23
<ipython-input-121-4b7fee4299ad> in averagePixels(self)
9 for x in range(self.pic.size[0]):
10 for y in range(self.pic.size[1]):
---> 11 tempr,tempg,clrs = self.imgData[x,y]
12 r += clrs[0]
13 g += clrs[1]
TypeError: 'int' object is not iterable






Это происходит потому, что self.imgData[x, y] — это int, а не то, что можно распаковать в три переменные; то есть это та же самая ошибка, которую вы получили бы, если бы попытались сделать что-то вроде a, b, c = 2. Поскольку ваше изображение называется lena-gs.png, я предполагаю, что это может происходить из-за того, что вы используете изображение в градациях серого без альфа-канала:
In [16]: pic = Image.open('test.png')
In [17]: data = pic.load()
In [18]: data[0, 0]
Out[18]: (44, 83, 140, 255)
In [19]: pic = Image.open('test-grayscale-with-alpha.png')
In [20]: data = pic.load()
In [21]: data[0, 0]
Out[21]: (92, 255)
In [33]: pic = Image.open('test-grayscale-without-alpha.png')
In [35]: data = pic.load()
In [36]: data[0, 0]
Out[36]: 92
Как видно из собственного примера, self.imgData[x, y] — это не int, а кортеж.
@DYZ: Честно, я использовал пример с альфа-каналом. Позвольте мне добавить пример, в котором его нет.
@fuglede это именно то, что я ищу, спасибо
@tfirinci: Отлично, если вы нашли ответ полезным, вы можете принять это.
Разные типы изображений имеют разные типы пикселей. Изображение RGB имеет три* канала на пиксель, а изображение в градациях серого — только один*. Вы можете переписать свою функцию достаточно надежным способом, преобразовав данные пикселей в массив Numpy и используя методы Numpy для вычисления средних значений:
import numpy as np
pic = ... # An RGB image
picgs = ... # A grayscale image
def averagePixels(pic):
if pic.mode=='L':
return [np.array(pic).mean()]
elif pic.mode=='RGB':
pixData = np.array(pic)
return [pixData[:,:,i].mean() for i in range(3)]
else:
raise Exception("Unsupported mode")
averagePixels(pic)
#[207.66529079861112, 199.11387297453703, 217.20738715277778]
averagePixels(picgs)
#[91.41583665338645]
* Можно добавить еще один канал для управления прозрачностью.
@tfirinci Также есть ошибка на
(r/count)(g/count). Это не должно запускаться. Убедитесь, что ваш код работает на вашей стороне, и скопируйте именно то, что, по вашему мнению, должно работать.