
本文介绍python OpenCV学习笔记的直方图均衡化,并与所有人共享,如下所示:
正式文件–
请考虑其像素值仅限制在特定值范围内的图像. 例如,较亮的图像会将所有像素限制为较高的值. 但是,好的图像将具有图像所有区域的像素. 因此,您需要将此直方图拉伸到两端(如下图所示). 这是直方图均衡化的功能(简单来说). 通常,这可以提高图像的对比度.

建议阅读Wikipedia页面有关直方图均衡的直方图均衡opencv直方图均衡化,以了解更多信息. 它给出了很好的解释并提供了一些示例,以便您阅读后可以理解所有内容. 同样,我们将看到其Numpy实现. 之后,我们将看到OpenCV函数.

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = 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的mask数组的概念数组. 对于掩码数组opencv直方图均衡化,所有操作都在非掩码元素上执行.
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)) # 并排叠加图片
cv.imwrite('res.png', res)

因此,现在您可以在不同的光照条件下拍摄不同的图像,进行平衡并检查结果.

当图像的直方图限制在特定区域时,直方图均衡非常好. 在强度变化较大的地方,直方图会覆盖较大的区域,例如亮像素和暗像素,这不容易使用.
CLAHE(对比度受限的自适应直方图均衡化)
我们刚刚看到的第一个直方图均衡化考虑了图像的整体对比度. 在许多情况下,这不是一个好主意. 例如,下图显示了输入图像及其在全局直方图均衡后的结果.

在直方图均衡后,背景对比度得到了改善. 但是在两个图像中比较雕像的面孔. 由于亮度高,我们丢失了大部分信息. 这是因为它的直方图不限于特定区域,如我们在上一个示例中看到的那样.
为了解决这个问题,可以使用自适应直方图均衡. 在这一点上,图像被分为几个小块,称为“瓦片”(OpenCV中的默认值为8x8). 然后,每个正方形都像通常一样是直方图. 因此,直方图将被限制在较小的区域(除非有噪音). 如果有噪音,它将被放大. 为了避免这种情况,将应用对比度限制. 如果任何直方图bin超过指定的对比度限制(默认为40),则在应用直方图均衡之前,这些像素将被裁剪并均匀地分布到其他bin中. 均衡后,删除边界中的伪像,并使用双线性插值.
cv.createCLAHE([,clipLimit [,tileGridSize]])
import numpy as np
import cv2 as cv
img = cv.imread('tsukuba_1.png', 0)
# create a CLAHE object (Arguments are optional).
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv.imread('clahe_2.jpg', cl1)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-288929-1.html
风控好