How to loop over histogram to get the color of the picture?
In this answer about detecting the color of an image olooney
said that "loop over the histogram and take the average of pixel color weighed by the pixel count".
I ran the histogram like this:
class ImageResize(webapp.RequestHandler):
def get(self):
q = HomePage.all()
q.filter("firm_name", "noise")
qTable = q.get()
id = qTable.key().id()
if id:
homepage = HomePage.get_by_id(id)
if homepage:
img = images.Image(homepage.thumbnail)
hist = img.histogram()
then in IDLE, for each color of the histogram hist2
, I tried to get the average and divided by pixel count, but I get the same number. What am I doing wrong?
>>> average_red = float(sum(hist2[0]))/len(hist2[0])
>>> average_red
789.2578125
>>> average_green = float(sum(hist2[1]))/len(hist2[1])
>>> average_green
789.2578125
>>> average_blue = float(sum(hist2[2]))/len(hist2[2])
>>> average_blue
789.2578125
>>>
Update
Thanks to Saxon Druce for the answer. Here's the code I used:
>>> def hist_weighed_average(hist):
red_hist = hist[0]
green_hist = hist[1]
blue_hist = hist[2]
开发者_Go百科
red_weighed_sum = float(sum(i * red_hist[i] for i in range(len(red_hist))))
green_weighed_sum = float(sum(i * green_hist[i] for i in range(len(green_hist))))
blue_weighed_sum = float(sum(i * blue_hist[i] for i in range(len(blue_hist))))
red_num_pixels = float(sum(red_hist))
green_num_pixels = float(sum(green_hist))
blue_num_pixels = float(sum(blue_hist))
red_weighed_average = red_weighed_sum / num_pixels
green_weighed_average = green_weighed_sum / num_pixels
blue_weighed_average = blue_weighed_sum / num_pixels
return red_weighed_average, green_weighed_average, blue_weighed_average
>>> hist = hist3
>>> hist_weighed_average(hist)
(4.4292897797574859, 4.8236723583271468, 5.2772779015095272)
>>> hist = hist2
>>> hist_weighed_average(hist)
(213.11471417965851, 220.01047265528334, 214.12880475129919)
>>>
Assuming hist2[0]
is the histogram of the red pixels, then it is a histogram of pixel counts indexed by the red component. That means that sum(hist2[0])
is always going to be the number of pixels in the image, and len(hist2[0])
is always going to be 256. This will always give you the same answer, for all three of red, green and blue.
You need to multiply the pixel counts (the values in the histogram) by the pixel values (the index in the list), then add them, to get a weighted sum. Then divide by the number of pixels to get the weighted average. Maybe something like this:
red_hist = hist2[0]
weighted_sum = sum(i * red_hist[i] for i in range(len(red_hist)))
num_pixels = sum(red_hist)
weighted_average = weighted_sum / num_pixels
精彩评论