OpenCV 4.11.0
开源计算机视觉库
|
在本节中,
考虑一个图像,其像素值仅限于某个特定值范围内。例如,较亮的图像将所有像素限制在较高的值。但是,良好的图像将具有来自图像所有区域的像素。因此,您需要将此直方图拉伸到两端(如下面的维基百科图像所示),这就是直方图均衡化所做的(简单来说)。这通常会提高图像的对比度。
我建议您阅读维基百科关于直方图均衡化的页面,以了解更多详细信息。它有一个非常好的解释和实际例子,这样您在阅读后几乎可以理解所有内容。在这里,我们将看到它的Numpy实现。之后,我们将看到OpenCV函数。
您可以看到直方图位于较亮的区域。我们需要全光谱。为此,我们需要一个变换函数,将较亮区域的输入像素映射到全区域的输出像素。这就是直方图均衡化所做的。
现在我们找到最小的直方图值(不包括 0),并应用维基百科页面中给出的直方图均衡化方程。但我在这里使用了 Numpy 的掩码数组概念。对于掩码数组,所有操作都在非掩码元素上执行。您可以从 Numpy 关于掩码数组的文档中了解更多信息。
现在我们有了查找表,它告诉我们每个输入像素值的输出像素值是什么。所以我们只需要应用变换。
现在我们像以前一样计算它的直方图和 cdf(您可以自己做),结果如下所示
另一个重要特征是,即使图像是较暗的图像(而不是我们使用的较亮图像),均衡后我们将得到与之前几乎相同的图像。因此,这被用作“参考工具”,使所有图像具有相同的照明条件。这在许多情况下非常有用。例如,在人脸识别中,在训练人脸数据之前,人脸图像会进行直方图均衡化,以使它们都具有相同的照明条件。
OpenCV 有一个函数可以做到这一点,cv.equalizeHist()。它的输入只是一个灰度图像,输出是我们的直方图均衡化图像。
下面是一个简单的代码片段,显示了它对我们使用的相同图像的用法
因此,现在您可以拍摄具有不同光照条件的不同图像,对其进行均衡化并检查结果。
当图像的直方图限制在特定区域时,直方图均衡化效果很好。在存在较大强度变化且直方图覆盖较大区域(即同时存在明亮和黑暗像素)的地方,它效果不佳。请查看附加资源中的 SOF 链接。
我们刚刚看到的第一个直方图均衡化考虑了图像的全局对比度。在许多情况下,这不是一个好主意。例如,下图显示了输入图像及其全局直方图均衡化后的结果。
诚然,直方图均衡化后背景对比度有所提高。但是,比较两幅图像中雕像的脸部。由于过度明亮,我们丢失了大部分信息。这是因为它的直方图不像我们之前看到的例子那样局限于特定区域(尝试绘制输入图像的直方图,您会获得更多直觉)。
因此,为了解决这个问题,使用了自适应直方图均衡化。在此方法中,图像被分成称为“块”的小块(在 OpenCV 中,tileSize 默认值为 8x8)。然后,像往常一样对这些块中的每一个进行直方图均衡化。因此,在一个小区域内,直方图将限制在一个小区域内(除非存在噪声)。如果存在噪声,它将被放大。为了避免这种情况,应用了对比度限制。如果任何直方图 bin 高于指定的对比度限制(在 OpenCV 中默认为 40),则在应用直方图均衡化之前,这些像素将被剪裁并均匀地分布到其他 bin。均衡化后,为了去除块边界上的伪影,应用双线性插值。
下面的代码片段显示了如何在 OpenCV 中应用 CLAHE
查看下面的结果,并将其与上面的结果进行比较,尤其是雕像区域
还可以查看这些关于对比度调整的 SOF 问题