随着技术的发展,图像对比度增强技术在过去几十年中不断演进,以满足其目标需求。增强图像对比度的主要目标有两个:一是提升图像的外观,便于视觉解读;二是提高后续任务(如图像分析、目标检测和图像分割)的性能。大多数对比度增强技术依赖于直方图修改,可以全局应用或局部应用。对比度限制自适应直方图均衡化(CLAHE)方法克服了全局方法的局限性,通过增强局部对比度来实现。
CLAHE,即对比度限制自适应直方图均衡化,是一种图像均衡化方法。它是自适应直方图均衡化(AHE)的一个变种,通过限制对比度放大来防止对比度过度增强。在考虑图像中像素值被限制在指定范围内的情况下,一个更亮的图像将所有像素值限制在高值,而一个优秀的图像将包含图像所有部分的像素值。因此,需要将直方图拉伸到两端,这正是直方图均衡化所做的事情(简而言之)。这通常会增加图像的对比度。
CLAHE在图像的小区域,称为瓦片,上工作,而不是整个图像。周围的瓦片使用双线性插值混合,以消除假边界。这个算法可以用来提高图像对比度。CLAHE也可以应用于彩色图像,通常应用于亮度通道。仅对HSV图像的亮度通道进行均衡化的结果优于对BGR图像的所有通道进行均衡化的结果。
让来看一个例子。上面的图像可以看到分割,尽管它不如它可能的那样清晰。因此,让看看直方图并利用均衡化将其拉伸到阈值。CLAHE算法最初用于改善低对比度的医学图像。与普通AHE不同,CLAHE限制了对比度。为了解决噪声放大问题,CLAHE实现了一个剪切限制。在计算累积分布函数之前,CLAHE通过在预定义值(CDF)处剪切直方图来限制放大。CLAHE技术将输入原始图像划分为不重叠的上下文区域,称为子图像、瓦片或块。
CLAHE由两个参数定义:块大小(BS)和剪切限制(CL)。这两个参数主要控制改善后的图像质量。当CL增加时,图像变得更亮,因为输入图像的强度非常低,更大的CL使其直方图更平坦。随着BS的增加,动态范围扩大,图像对比度增加。在最大熵曲率点确定的两个参数在图像熵使用时产生主观上良好的图像质量。
以下是使用Python实现CLAHE的代码示例。首先,导入必要的库:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("testing_image.jpeg", 0)
equ = cv2.equalizeHist(img)
print(img)
print(equ)
首先,读取灰度图像并将其赋值给变量image。可以使用cv2.equalizeHist来均衡化直方图(图像)。让看看测试照片的直方图。可以看到,它向右倾斜。
plt.hist(img.flat, bins=100, range=(0, 255))
让看看均衡化后的图像的直方图。直方图也扩展到255。
plt.hist(equ.flat, bins=100, range=(0, 255))
直方图均衡化后的图像如下所示。由于考虑了图像的全局对比度而不仅仅是局部对比度,因此上述图像有很多噪声。因此,在图像上执行全局均衡化可能效果不佳。在这种情况下,可以使用自适应直方图均衡化,也称为CLAHE。
对比度限制的自适应直方图均衡化(CLAHE)是自适应直方图均衡化的一个变种,它限制了对比度放大以减少噪声放大。简而言之,CLAHE在小补丁或小瓦片上执行直方图均衡化,具有高精度和对比度限制。
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl_img = clahe.apply(img)
如上图所示,CLAHE的结果比标准均衡化图像要好得多。但是,仍然有很多噪声。让看看阈值处理如何获得更好的结果。
使用.tiff文件格式而不是.jpeg文件格式可以获得更好的图像结果。在开始阈值处理之前,必须首先检查CLAHE图像的直方图。
plt.hist(cl_img.flat, bins=100, range=(100, 255))
如上图的直方图所示,在160和200之间有一个凹陷,可以选择一个接近的数字来分离这两个峰值。在选择了一个接近的数字之后(选择了190),可以进行阈值处理。
ret, thresh1 = cv2.threshold(cl_img, 190, 150, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(cl_img, 190, 255, cv2.THRESH_BINARY_INV)
忽略第一个ret参数。可以得到阈值图像变量thresh1和变量thresh2。图像是上述代码部分的第一个参数,其次是选择的阈值,一个值用于所有阈值化的像素,最后是一个方法。分离了变量THRESH BINARY和THRESH BINARY INV。
第一个阈值图像(thresh1)的灰度级别是150,第二个阈值图像(thresh2)的灰度级别是255。这只是基于直方图的阈值处理。
使用直方图,确定190是前面例子中的最佳值。然而,有一种更简单的方法可以找到最佳值,即使用OTSU。
ret, thresh3 = cv2.threshold(cl_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
可以使用OTSU自动分割。如果使用二值阈值,OTSU是找到最佳值的最佳方式。如果需要,可以使用K-means。
本文到此结束。如果图像有噪声,请先去噪。然后,可以执行所有这些练习。
当创建图像处理流程并确定需要直方图均衡化时,建议从使用cv2.equalizeHist进行简单的直方图均衡化开始。然而,如果结果不佳,希望增加输入图像中的噪声,那么应该尝试使用cv2.createCLAHE进行自适应直方图均衡化。
对比度拉伸的目标是增加图像中最大和最小强度值之间的差异。其余的强度值分布在这个范围内。
直方图均衡化是修改图像中所有像素的强度值,使直方图“变平”的过程。
在对比度拉伸中,源图像和目标图像之间存在强度值的一一对应关系,这意味着可以从对比度拉伸的图像中恢复原始图像。
然而,一旦应用了直方图均衡化,就无法恢复原始图像。