如何遍历直方图获取图片颜色?
在这段关于检测图像颜色的回答中,用户 olooney
提到“遍历直方图,计算每种颜色的平均值,并根据像素数量进行加权”。
我这样运行了直方图:
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()
然后在 IDLE 中,对于直方图中的每种颜色 hist2
,我试着计算平均值并除以像素数量,但我得到的结果总是一样。我哪里做错了呢?
>>> 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
>>>
更新
感谢 Saxon Druce 提供的 答案。这是我使用的代码:
>>> 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 个回答
3
假设 hist2[0]
是红色像素的直方图,那么它就是一个按照红色成分来统计像素数量的图表。这意味着 sum(hist2[0])
总是会等于图像中的像素总数,而 len(hist2[0])
总是会是 256。这对于红色、绿色和蓝色三个颜色来说,结果都是一样的。
你需要把像素数量(直方图中的值)乘以像素值(列表中的索引),然后把这些结果加起来,这样就得到了加权和。接着再用这个加权和除以像素总数,就能得到加权平均值。可以像这样做:
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