图像直方图与均衡化

图像直方图

图像直方图即对图像中每个像素值出现次数的统计直方图。

image.png

OpenCV:cv2.calcHist(images, channels, mask, histSize, ranges)

  • images:输入图像;
  • channels:输入一个包含[0, 1, 2]的列表选择通道,全选表示BGR,[0]表示灰度图;
  • mask:与images对齐的掩码,用于标记需要统计的像素,全选则输入None;
  • histSize:直方图横坐标的个数;
  • ranges:像素值范围,默认为[0, 256]
1
2
3
4
5
6
img = cv2.imread('cat.jpg')
color = ('b', 'g', 'r')
for i, col in enumerate(color):
hist = cv2.calcHist([img], [i], None, [256], [0, 256])
plt.plot(hist, color=col)
plt.xlim([0, 256])

image.png

直方图均衡化

直方图均衡化是将原图像通过某种变换,得到一幅灰度直方图为均匀分布的新图像的方法。其基本思想是对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。从而达到清晰图像的目的。

image.png

image.png

步骤:

  1. 确定图像的灰度级(通常情况下,如果我们的图像是彩色。需要将其转换为灰度图像,其灰度级一般是0-255);
  2. 统计每一个灰度在原始图像上的像素所占总体的比例,即每个灰度的概率;
  3. 计算累加概率(将低灰度级的概率累加到高灰度级的概率上);
  4. 根据公式求映射结果:

image.png

OpenCV代码:cv2.equalizeHist(img)

虽然直方图均衡化后能让图像整体更加清晰,但有时候会使得原本突出的局部特征变得模糊(如图中的人脸)。

image.png

可以使用自适应直方图均衡化解决这个问题。将图像划分为多个小区域(在opencv中默认为8×8),对每一个划分子域分别进行直方图均衡化。最后使用双线性插值对每一个子域的边界进行拼接。

1
2
3
# create a CLAHE object (Arguments are optional).
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
img = clahe.apply(img)
-------------本文结束感谢您的阅读-------------