学习直方图均衡化的概念并使用它来改善我们图像的对比度。
考虑像素值仅限于某些特定值范围的图像。例如,更亮的图像会将所有像素限制为高值。但是一个好的图像将包含来自图像所有区域的像素。因此,您需要将此直方图拉伸到两端(如下图所示,来自维基百科),这就是直方图均衡的作用(简单来说)。这通常会提高图像的对比度。
阅读有关直方图均衡化Histogram Equalization的维基百科页面以获取更多详细信息。它有一个很好的解释,并附有示例,因此您在阅读之后几乎可以理解所有内容。这里我们将看到OpenCV 功能。
1. 全局均值化
img = cv.imread("../../file/photos/wiki.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 全局均匀化
equ = cv.equalizeHist(gray)
# 连接初始图像和均值化之后的图像
merge = np.hstack((gray, equ))
plt.imshow(merge, 'gray'), plt.axis('off')
plt.show()
所以现在您可以在不同的光线条件下拍摄不同的图像,对其进行均衡并检查结果。
当图像的直方图限于特定区域时,直方图均衡化效果很好。在直方图覆盖大区域的强度变化很大的地方,它不会很好地工作,即存在亮像素和暗像素。请检查附加资源中的 SOF 链接。
2. 区域均值化
我们刚刚看到的第一个直方图均衡考虑了图像的全局对比度。在大多数情况下,这不是一个好主意。例如,下图显示了输入图像及其全局直方图均衡化后的结果。
equ = cv.equalizeHist(gray)
merge = np.hstack((gray, equ))
plt.imshow(merge, 'gray'), plt.axis('off')
plt.show()
左边为初始图像,右边为均值化之后的图像
2.区域均值化
确实,在直方图均衡化后背景对比度有所改善。但是比较两个图像中雕像的脸。由于亮度过高,我们丢失了那里的大部分信息。这是因为它的直方图并不像我们在之前的案例中看到的那样局限于特定区域(尝试绘制输入图像的直方图,您将获得更多直觉)。
所以为了解决这个问题,使用了自适应直方图均衡化。在这种情况下,图像被分成称为“tiles”的小块(在 OpenCV 中,tileSize 默认为 8x8)。然后像往常一样对这些块中的每一个进行直方图均衡。所以在一个小区域中,直方图会限制在一个小区域内(除非有噪声)。如果有噪音,它会被放大。为了避免这种情况,应用了对比度限制。如果任何直方图 bin 高于指定的对比度限制(在 OpenCV 中默认为 40),则在应用直方图均衡化之前,这些像素将被剪裁并均匀分布到其他 bin。均衡后,为了去除瓦片边界中的伪影,应用双线性插值。
clahe = cv.createCLAHE(clipLimit=2, tileGridSize=(4, 4))
cl1 = clahe.apply(gray)
merge = np.hstack((gray, cl1))
plt.imshow(merge, 'gray'), plt.axis('off')
plt.show()
cv.createCLAHE()用于实现上面的功能,将像素裁剪并均匀分不到其他bin。
其他资源
还要检查这些关于对比度调整的 SOF 问题: