1 直方图的概念
在图像处理中,经常用到直方图,如颜色直方图、灰度直方图等。
图像的灰度直方图就描述了图像中灰度分布情况,能够很直观的展示出图像中各个灰度级所
占的多少。
图像的灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像素的个数:其中,横
坐标是灰度级,纵坐标是该灰度级出现的频率。如下图所示:
绘制图像直方图的代码如下:
# 获取灰度图像
img = cv2.imread("lenna.png", 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#cv2.imshow("image_gray", gray)
# 直方图
hist = cv2.calcHist([dst],[0],None,[256],[0,256])
plt.figure()
plt.hist(dst.ravel(), 256)
plt.show()
2 直方图的性质
① 直方图反映了图像中的灰度分布规律。它描述每个灰度级具有的像素个数,但不包含
这些像素在图像中的位置信息。图像直方图不关心像素所处的空间位置,因此不受图
像旋转和平移变化的影响,可以作为图像的特征。
② 任何一幅特定的图像都有唯一的直方图与之对应,但不同的图像可以有相同的直方图。
③ 如果一幅图像有两个不相连的区域组成,并且每个区域的直方图已知,则整幅图像的
直方图是该两个区域的直方图之和
3 直方图的应用
下图展示了四种常见的直方图,它们描述了四种不同灰度级别的分布情况。
图 (a)图像中的像素在各个灰度级别上均匀分布,没有明显的偏向。这通常对应着图像的整体亮度适中,没有过于明亮或暗淡的区域。
图 (b) 图像中的大部分像素分布在较低的灰度级别上,而较少的像素分布在较高的灰度级别上。这意味着图像整体比较暗淡,亮度较低,可能会导致细节不够清晰。
图 © 图像中的像素分布在较高的灰度级别上,而较少的像素分布在低灰度级别上。这意味着图像整体比较明亮,亮度较高,可能会导致细节丢失或过曝的情况。
图 (d) 图像中的像素主要分布在某个特定的灰度级别或灰度范围上,其他灰度级别上的像素数量较少。这可能导致图像的亮度过于集中,造成细节丢失或局部对比度过高。
如果我们想要将上图中的灰度分布调整为灰度均匀分布,我们可以使用直方图均衡化算法。
4 直方图均衡化
4.1 直方图均衡化的概念
直方图均衡化是将原图像的直方图通过变换函数变为均匀的直方图,然后按均匀直方图修改原
图像,从而获得一幅灰度分布均匀的新图像。直方图均衡化就是用一定的算法使直方图大致平
和的方法
直方图均衡化的作用是图像增强
4.2 直方图均衡化的步骤
① 依次扫描原始灰度图像的每一个像素,计算出图像的灰度直方图H
② 计算灰度直方图的累加直方图
③ 根据累加直方图和直方图均衡化原理得到输入与输出之间的映射关系。
④ 最后根据映射关系得到结果:dst(x,y) = H’(src(x,y))进行图像变换
4.3 直方图均衡化的公式推导
对于输入图像的任意一个像素p, p∈[0,255], 总能在输出图像里有对应的像素q, q∈[0,255] 使得下面等式成
立(输入和输出的像素总量相等):
其中,输出图像每个灰度级的个数:
代入累加直方图公式:
4.4 例子
参考下面这个例子可以更直观的理解直方图均衡化的原理及过程
5 均衡化代码实现
5.1 灰度图像直方图均衡化
# 获取灰度图像
img = cv2.imread("lenna.png", 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#cv2.imshow("image_gray", gray)
# 灰度图像直方图均衡化
dst = cv2.equalizeHist(gray)
# 直方图
hist = cv2.calcHist([dst],[0],None,[256],[0,256])
cv2.imshow("Histogram Equalization", np.hstack([gray, dst]))
cv2.waitKey(0)
代码运行结果如下:
5.2 彩图像直方图均衡化
img = cv2.imread("lenna.png", 1)
cv2.imshow("src", img)
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst_rgb", result)
#cv2.imwrite("dst_rgb.png", result)
cv2.waitKey(0)
代码运行结果如下: