OpenCV-Python 直方图-2:直方图均衡 | 二十七_直方图_图像
我建议您阅读直方图均衡化上的Wikipedia页面,以获取有关它的更多详细信息。它很好地阐明了示例,使您在阅读完之后险些可以理解所有内容。相反,在这里我们将看到其Numpy实现。之后,我们将看到OpenCV功能。
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg = cv.imread('wiki.jpg',0)hist,bins = np.histogram(img.flatten(),256,[0,256])cdf = hist.cumsum()cdf_normalized = cdf float(hist.max()) / cdf.max()plt.plot(cdf_normalized, color = 'b')plt.hist(img.flatten(),256,[0,256], color = 'r')plt.xlim([0,256])plt.legend(('cdf','histogram'), loc = 'upper left')plt.show()
你可以看到直方图位于较亮的区域。我们须要全频谱。为此,我们须要一个转换函数,将亮区域的输入像素映射到全体区域的输出像素。这便是直方图均衡化的浸染。
现在我们找到最小的直方图值(不包括0),并运用wiki页面中给出的直方图均衡化方程。但我在这里用过,来自Numpy的掩码数组观点数组。对付掩码数组,所有操作都在非掩码元素上实行。您可以从Numpy文档中理解更多关于掩码数组的信息。
cdf_m = np.ma.masked_equal(cdf,0)cdf_m = (cdf_m - cdf_m.min())255/(cdf_m.max()-cdf_m.min())cdf = np.ma.filled(cdf_m,0).astype('uint8')
现在我们有了查找表,该表为我们供应了有关每个输入像素值的输出像素值是什么的信息。因此,我们仅运用变换。
img2 = cdf[img]
现在,我们像以前一样打算其直方图和cdf(您这样做),结果如下所示:
另一个主要的特色是,纵然图像是一个较暗的图像(而不是我们利用的一个较亮的图像),经由均衡后,我们将得到险些相同的图像。因此,这是作为一个“参考工具”,使所有的图像具有相同的照明条件。这在很多情形下都很有用。例如,在人脸识别中,在对人脸数据进行演习之前,对人脸图像进行直方图均衡化处理,使其具有相同的光照条件。
OpenCV中的直方图均衡OpenCV具有实行此操作的功能cv.equalizeHist()。它的输入只是灰度图像,输出是我们的直方图均衡图像。 下面是一个大略的代码片段,显示了它与我们利用的同一图像的用法:
img = cv.imread('wiki.jpg',0)equ = cv.equalizeHist(img)res = np.hstack((img,equ)) #stacking images side-by-sidecv.imwrite('res.png',res)
因此,现在您可以在不同的光照条件下拍摄不同的图像,对其进行均衡并检讨结果。
当图像的直方图限定在特定区域时,直方图均衡化效果很好。在直方图覆盖较大区域(即同时存在亮像素和暗像素)的强度变革较大的地方,效果不好。请检讨其他资源中的SOF链接。
CLAHE(比拟度受限的自适应直方图均衡)我们刚刚看到的第一个直方图均衡化考虑了图像的整体比拟度。在许多情形下,这不是一个好主张。例如,下图显示了输入图像及其在全局直方图均衡后的结果。
直方图均衡后,背景比拟度确实得到了改进。但是在两个图像中比较雕像的脸。由于亮度过高,我们在那里丢失了大多数信息。这是由于它的直方图不像我们在前面的案例中所看到的那样局限于特定区域(考试测验绘制输入图像的直方图,您将得到更多的直觉)。
因此,为理解决这个问题,利用了自适应直方图均衡。在这种情形下,图像被分成称为“tiles”的小块(在OpenCV中,tileSize默认为8x8)。然后,像往常一样对这些块中的每一个进行直方图均衡。因此,在较小的区域中,直方图将限定在一个较小的区域中(除非存在噪声)。如果有噪音,它将被放大。为了避免这种情形,运用了比拟度限定。如果任何直方图bin超出指定的比拟度限定(在OpenCV中默认为40),则在运用直方图均衡之前,将这些像素裁剪并均匀地分布到其他bin。均衡后,要肃清图块边界中的伪影,请运用双线性插值。
下面的代码片段显示了如何在OpenCV中运用CLAHE:
import numpy as npimport cv2 as cvimg = cv.imread('tsukuba_l.png',0)# create a CLAHE object (Arguments are optional).clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))cl1 = clahe.apply(img)cv.imwrite('clahe_2.jpg',cl1)
查看下面的结果,并将其与上面的结果进行比较,尤其是雕像区域:
附加资源Wikipedia page on Histogram Equalization:http://en.wikipedia.org/wiki/Histogram_equalizationMasked Arrays in Numpy:http://docs.scipy.org/doc/numpy/reference/maskedarray.html)
有关比拟度调度的问题:
如何在C中的OpenCV中调度比拟度? http://stackoverflow.com/questions/10549245/how-can-i-adjust-contrast-in-opencv-in-c如何利用opencv均衡图像的比拟度和亮度?http://stackoverflow.com/questions/10561222/how-do-i-equalize-contrast-brightness-of-images-using-opencv)本文系作者个人观点,不代表本站立场,转载请注明出处!