理解Pillow中的histogram()

6 投票
3 回答
11726 浏览
提问于 2025-04-17 22:41

根据文档:

im.histogram() => list

这个函数会返回一张图片的直方图。直方图的结果是一个像素计数的列表,每个像素值在源图像中都有一个对应的计数。如果这张图片有多个颜色通道(比如红、绿、蓝),那么所有通道的直方图会合并在一起(例如,一张“RGB”图片的直方图会有768个值)。

我明白红色、绿色和蓝色各有256个值(256 * 3 = 768)。

for i, value in enumerate(im.histogram()):
    print i, value

生成的结果是:

0 329
1 145
... (skipping some)
256 460
... (skipping some)
767 3953

我的问题是:这是不是意味着有:
329个像素的值是 R = 0, G = 0, B = 0,还有
145个像素的值是 R = 1, G = 0, B = 0,还有
460个像素的值是 R = 256, G = 1, B = 0,还有
3953个像素的值是 R = 256, G = 256, B = 256,等等?

我应该这样理解这个输出吗?

3 个回答

-1

如果模式是RGB来打开一张图片,768的意思是红色灰度列表(0到255的像素数量)加上绿色灰度列表(0到255的像素数量)再加上蓝色灰度列表(0到255的像素数量)。

im是一个RGB格式的图像对象。

在[59]这一行:x = reduce(lambda x,y:x+y,im.histogram())

在[60]这一行:x的值是47191725。

在[61]这一行:im.size显示的是图片的大小。

在[62]这一行:4731乘以3325的结果是15730575。

在[63]这一行:4731乘以3325再乘以3的结果是47191725。

在[64]这一行:

或者用另一种方法:

r, g, b = im.split(),这行代码是把图像分成红色、绿色和蓝色三个部分。

len(r.histogram()) = 256,表示红色部分的灰度值有256个。

len(g.histogram()) = 256,表示绿色部分的灰度值也有256个。

len(b.histogram()) = 256,表示蓝色部分的灰度值同样有256个。

3

不,你不知道有多少个像素的颜色是(例如)R=0,G=0,B=0。要知道这一点,你需要一个包含大约1600万个条目的直方图。

你只能知道有多少个像素的R值是0,有多少个像素的G值是0,还有多少个像素的B值是0,这些都是单独计算的。

所以,R=0的像素可能有很多不同的G和B值。

13

我没有测试过,但从文档来看,描述的意思似乎是直方图只适用于每个通道(比如红色、绿色、蓝色)单独处理。

如果图像有多个通道,那么所有通道的直方图会连接在一起(例如,一个“RGB”图像的直方图包含768个值)。

所以,不,你给出的例子并不完全正确。768个值其实就是256 * 3,这是可能的红色值数量,加上可能的绿色值数量,再加上可能的蓝色值数量,这些都是独立计算的。它并不代表红色、绿色和蓝色的所有可能组合,后者的计算方式是256 ^ 3 == 16777216

根据我所看到的,你的例子中直方图值的解释应该是:

329  pixels with value of R = 0, G = ?, B = ? and
145  pixels with value of R = 1, G = ?, B = ? and
...
460  pixels with value of R = ?, G = 1, B = ? and
...
3953 pixels with value of R = ?, G = ?, B = 256

撰写回答