OpenCV-Python(22):直方图的计算绘制与分析

发布时间:2023年12月30日

目标

  • 了解直方图的原理及应用
  • 使用OpenCV 或Numpy 函数计算直方图
  • 使用Opencv 或者Matplotlib 函数绘制直方图
  • 学习函数cv2.calcHist()、np.histogram()等

原理及应用

????????直方图是一种统计图形,是对图像的另一种解释,用于表示图像中各个像素值的频次分布。直方图的x 轴是灰度值(0 到255),y 轴是图片中具有同一个灰度值的点的数目。通过直方图你可以对整幅图像的灰度分布、对比度、亮度等有一个整体的了解。在计算机视觉中,直方图是一种常用的图像特征描述方法,可以用于图像处理、图像分割、图像匹配等应用,几乎所有的图像处理软件提供了直方图分析功能。

????????在图像处理中,直方图可以用于对图像进行增强、对比度调整、色彩均衡等操作。通过分析图像的直方图,可以了解图像的亮度分布情况,进而进行亮度调整,使图像更加清晰、明亮或暗淡。

????????在图像分割中,直方图可以用于选择合适的阈值进行图像分割。通过分析图像的直方图,可以找到合适的阈值,将图像分成不同的区域,达到目标检测和图像分割的目的。

????????在图像匹配中,直方图可以用于计算图像之间的相似度。通过比较两幅图像的直方图,可以得到它们的相似程度,从而实现图像的匹配和检索。

????????我们来分析上面幅图片和它的直方图(要记住:直方图是根据灰度图像绘制的,而不是彩色图像)。直方图的左边区域像是暗一点的像素数量,右侧显示了亮一点的像素的数量。从这幅图上你可以看到灰暗的区域比亮的区域大,而处于中间部分的像素点很少。?

参考以下连接获取更多相关信息:https://www.cambridgeincolour.com/tutorials/histograms1.htm

统计直方图?

????????现在我们知道什么是直方图了,那么我们应该怎样获得一副图像的直方图呢?OpenCV 和Numpy 有内置函数做这件事。在使用这些函数之前我们有必要了解一下直方图相关的术语。

  • BINS

????????上面的直方图显示了每个像素灰度值对应的像素数目。如果像素值为0到255,你就需要256 个数来显示上面的直方图。但是,如果你不需要知道每一个像素值的像素点数目,而只希望知道两个像素值之间的像素点数目怎么办呢?举例来说,我们想知道像素值在0 到15 之间的像素点的数目,接着是16 到31,....240 到255。我们只需要16 个值来绘制直方图即可。

? ? ? ? 那么到底要怎么做呢?你只需要把原来的256 个值等分成16 小组,取每组的总和。而这里的每一个小组就就成为BIN。第一个例子中有256 个BIN,第二个例子中有16 个BIN。在OpenCV 的文档中用histSize 表示BINS。

  • DIMS

????????表示我们收集数据的参数数目。在本例中,我们对收集到的数据只考虑一件事:灰度值。所以这里就是1。

  • RANGE

????????就是要统的灰度值范围,一般来说为[0-256],也就是所有的灰度值。

cv2.calcHist()函数是OpenCV中用于计算图像直方图的函数。函数原型为:

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

参数解释:

  • images:输入图像(图像格式为uint8 或float32)。它应该是一个包含图像的列表,每个图像都是一个NumPy数组。
  • channels:指定要计算直方图的通道。它是以0为基础的索引,例如,对于灰度图像,它的值为[0],对于彩色图像,可以传递[0],[1]或[2]来计算蓝色、绿色或红色通道的直方图。
  • mask:眼膜图像,可选参数,用于指定要计算直方图的区域。如果不需要,则传递None。。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像并使用它。
  • histSize:指定直方图的大小。它表示直方图中有多少个BIN(柱子),即分成多少个区间,应该用中括号括起来,例如[256]
  • ranges:指定像素值的范围。一般情况下,它的值为[0, 256],表示像素值的范围为0到255。

返回值:

  • hist:计算的直方图。它是一个一维数组,表示每个bin的频次。

我们从一副简单图像开始吧,示例代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('image.jpg')

# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 计算直方图,别忘了参数中的中括号,只有mask 没有中括号
hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256])

# 绘制直方图
plt.plot(hist)
plt.show()

????????上述代码中,首先使用cv2.imread()函数读取图像,然后使用cv2.cvtColor()函数将图像转换为灰度图像。接着,调用cv2.calcHist()函数计算灰度图像的直方图,其中channels参数为[0]表示只计算灰度通道的直方图,mask参数为None表示计算整个图像的直方图,histSize参数为[256]表示直方图分成256个bin,ranges参数为[0, 256]表示像素值的范围为0到255。最后,使用matplotlib库中的plt.plot()函数绘制直方图。

使用Numpy 中的函数np.histogram() 也可以帮我们统计直方图。你也可以尝试以下代码:

#img.ravel() 将图像转换成一维数组,这里没有中括号。
hist,bins = np.histogram(img.ravel(),256,[0,256])

hist 与上面计算的一样。但是这里的bins 是257,因为Numpy 计算bins 的方式为:0-0.99,1-1.99,2-2.99 等。所以最后一个范围是255-255.99。为了显示它,所以在bins 的结尾加上了256。但是我们不需要256,到255就够了。?

绘制直方图

文章来源:https://blog.csdn.net/mzl_18353516147/article/details/135305970
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。