How to loop over histogram to get the color of the picture?

倾然丶 夕夏残阳落幕 提交于 2020-01-25 00:53:33

问题


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]

    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)
>>> 

回答1:


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


来源:https://stackoverflow.com/questions/7563315/how-to-loop-over-histogram-to-get-the-color-of-the-picture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!