用NumPy图像绘制灰度值直方图

4

我将一张图片加载到了一个Numpy数组中,现在想把它的颜色值绘制成直方图。

import numpy as np

from skimage import io
from skimage import color

img = io.imread('img.jpg')
img = color.rgb2gray(img)

unq = np.unique(img)
unq = np.sort(unq)

当我们检查unq的值时,会看到类似以下的内容。
array([  5.65490196e-04,   8.33333333e-04,   1.13098039e-03, ...,
         7.07550980e-01,   7.09225490e-01,   7.10073725e-01])

这段代码涉及的值对于 matplotlib 来说太多了,所以我的想法是循环遍历 unq ,并删除每个值,只要它与前一个值之间的差距为 x

dels = []

for i in range(1, len(unq)):
    if abs(unq[i]-unq[i-1]) < 0.0003:
        dels.append(i)

unq = np.delete(unq, dels)

虽然这种方法可行,但效率非常低,因为它没有使用numpy的优化实现。

是否有一种可以使用numpy实现的功能来完成这个任务?

刚刚注意到我的算法丢失了关于颜色出现频率的信息。让我试着修复一下。


2
为什么不使用 np.histogram(img, bins) (或者 plt.hist(img.ravel(), bins) 如果你只是想绘制它)? - ali_m
@ali_m 是的,这会回答我的问题。 - bodokaiser
1个回答

13

如果你只想计算直方图,你可以使用np.histogram

bin_counts, bin_edges = np.histogram(img, bins, ...)

这里的bins可以是箱子的数量,也可以是指定上下边缘的向量。

如果你想绘制直方图,最简单的方法是使用plt.hist

bin_counts, bin_edges, patches = plt.hist(img.ravel(), bins, ...)

注意,在计算直方图之前,我使用了img.ravel()来将图像数组展平。如果您将2D数组传递给plt.hist(),它会将每一行视为单独的数据系列,这并不是你在这里想要的。


2
谢谢你提供plt.hist(img.ravel())的好建议!请问如何从直方图中读取灰度值(因为刻度只到0.8)? - bodokaiser
不确定您的意思。x轴表示灰度值,y轴表示频率。如果x轴范围从0到0.8,则所有灰度值都在0到0.8之间,这与您在“unq”中显示的值一致。 - ali_m
啊,是的,这很有道理。 - bodokaiser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接