Reputation: 159
My code is below , I want to get print out average pixel by using .averagePixels code in PIL but the output return ‘int’ object is not iterable. Anyone can help on it
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()))
the output is:
(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
Upvotes: 1
Views: 61
Reputation: 57033
Different types of images have different types of pixels. An RGB image has three* channels per pixel, but a grayscale image has only one*. You can rewrite your function in a reasonably robust way by converting pixel data to a Numpy array and using Numpy methods to calculate the means:
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]
*Another channel may be added to handle transparency.
Upvotes: 0
Reputation: 18201
This is happening because self.imgData[x, y]
is an int
and not something that can be unpacked into three variables; that is, this is the same error you would get if you tried to do something like a, b, c = 2
. Since your image is called lena-gs.png
, I imagine this could be happening because you are using a grayscale image with no alpha channel:
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
Upvotes: 2