13. 图像中的直方图

概述:

您可以将直方图视为图形或绘图,它可以让您全面了解图像的强度分布。它是一个图,其中 X 轴上的像素值(范围从 0 到 255,不总是)和 Y 轴上图像中相应的像素数。这只是理解图像的另一种方式。通过查看图像的直方图,可以直观地了解该图像的对比度、亮度、强度分布等。今天几乎所有的图像处理工具都提供直方图功能。
在这里插入图片描述
您可以看到图像及其直方图。 (请记住,此直方图是为灰度图像绘制的(单通道),而不是为彩色图像绘制的)。直方图的左侧区域显示图像中较暗像素的数量,右侧区域显示较亮像素的数量。从直方图中,您可以看到暗区多于亮区,并且中间色调(中间范围的像素值,例如 127 左右)的数量非常少。

1.OpenCV中的直方图

所以现在我们使用 cv.calcHist()函数来查找直方图。让我们熟悉一下函数及其参数:
python中用法:

cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
参数描述
images它是 uint8 或 float32 类型的源图像。它应该放在方括号中,即“[img]”
channels它也在方括号中给出。它是我们计算直方图的通道索引。例如,如果输入是灰度图像,则其值为 [0]。对于彩色图像,您可以通过 [0]、[1] 或 [2] 分别计算蓝色、绿色或红色通道的直方图。
mask掩码图像。要找到完整图像的直方图,将其指定为“无”。但是如果你想找到图像特定区域的直方图,你必须为此创建一个蒙版图像并将其作为蒙版。 (下面会展示一个示例。)
histSize这代表我们的 BIN 计数。需要在方括号中给出。对于全尺寸,我们通过 [256]
ranges这是我们的范围。通常,它是 [0,256]
hist = cv.calcHist([gray], [0], None, [256], [0, 256])
plt.plot(hist)
plt.show()

在这里插入图片描述

在这里插入图片描述

2. numpy中的直方图用法

# ndarray[].ravel()可以将多维数组降为一维数组
hist, bins = np.histogram(gray.ravel(), 256, [0, 256])
# Numpy 有另一个函数,np.bincount(),它比(大约 10 倍)np.histogram() 快得多。所以对于一维直方图,你可以更好地尝试。
# hist = np.bincount(gray.ravel(), minlength=256, ) 
plt.plot(hist)
plt.show()

结果和上图一样

3. 使用Matplotlib

Matplotlib 带有一个直方图绘图函数:matplotlib.pyplot.hist()它直接找到直方图并绘制它。您不需要使用 calcHist() 或 np.histogram() 函数来查找直方图。请参阅下面的代码:

plt.hist(gray.ravel(), 256, [0, 256])
plt.show()

结果如下
在这里插入图片描述

4. 画出图像的三个通道的直方图

或者您可以使用 matplotlib 的普通图,这对 BGR 图有好处。为此,您需要先找到直方图数据。参考下面的代码:

color = ("b", "g", "r")
for i, col in enumerate(color):
    histr = cv.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
    plt.xticks([0, 256])
plt.show()

在这里插入图片描述
从上图中可以推断,蓝色在图像中有一些高值区域(显然应该是天空造成的)

5. 掩膜在直方图的应用

img = cv.imread("../../file/photos/home.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 创建一个掩膜矩阵,类型为8位无符号整型
mask = np.zeros(gray.shape[0:2], np.uint8)
rows, cols = mask.shape[:2]
mask[(rows//2-60):(rows//2+60), (cols//2-100):(cols//2+100)] = 255

mask_img = cv.bitwise_and(gray, gray, mask=mask)  # 位与操作
# mask
hist_full = cv.calcHist([gray], [0], None, [256], [0, 256])  # 不带掩膜的直方图
hist_mask = cv.calcHist([gray], [0], mask, [256], [0, 256])  # 带掩膜的直方图
# 画出相应图形
plt.subplot(221), plt.imshow(gray, 'gray'), plt.title("Oringal image")
plt.axis('off')
plt.subplot(222), plt.imshow(mask, 'gray'), plt.title("mask")
plt.axis('off')
plt.subplot(223), plt.imshow(mask_img, 'gray'), plt.title("mask image")
plt.axis('off')
plt.subplot(224), plt.plot(hist_mask, color='r'), plt.plot(hist_full, color='b'), plt.title("histgram")
plt.show()

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值