python opencv直方图_【python opencv】直方图均衡

搜索热词

考虑这样一个图像,它的像素值仅局限于某个特定的值范围。例如,较亮的图像将把所有像素限制在高值上。但是一幅好的图像会有来自图像所有区域的像素。因此,您需要将这个直方图拉伸到两端(如下图所示,来自wikipedia),这就是直方图均衡化的作用(简单来说)。这通常会提高图像的对比度。

f3809141b2a0b3904b8ceca9ccb4a171.png

在这里我们将看到其Numpy实现。之后,我们将看到OpenCV功能。

importnumpy as npcv2 as cvfrom matplotlib 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,256],color = r)

plt.xlim([0,256])

plt.legend((cdf',histogram'),loc = upper left)

plt.show()

8c8aeefa950e5ce46d5681aebd1402a5.png 

6e2992812b5e6b0dd4135c0b3796f7b3.png

你可以看到直方图位于较亮的区域。我们需要全频谱。为此,我们需要一个转换函数,将亮区域的输入像素映射到整个区域的输出像素。这就是直方图均衡化的作用。

现在我们找到最小的直方图值(不包括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(您这样做),结果如下所示:

hist,bins = np.histogram(img.flatten(),1)">)

plt.show()

61a5701c42ed4a3eaebf8858ecfed48b.png

d2c5a0748ecf113370b13c0f3888e960.png

另一个重要的特征是,即使图像是一个较暗的图像(而不是我们使用的一个较亮的图像),经过均衡后,我们将得到几乎相同的图像。因此,这是作为一个“参考工具”,使所有的图像具有相同的照明条件。这在很多情况下都很有用。例如,在人脸识别中,在对人脸数据进行训练之前,对人脸图像进行直方图均衡化处理,使其具有相同的光照条件。

opencv中直方图均衡:

OpenCV具有执行此操作的功能cv.equalizeHist()。它的输入只是灰度图像,输出是我们的直方图均衡图像。 下面是一个简单的代码片段,显示了它与我们使用的同一图像的用法:

img = cv.imread(cv.equalizeHist(img)

res= np.hstack((img,equ)) #stacking images side-by-side

cv.imwrite(res.png6fcbe4e12c8d3fa5d052a08909748163.png

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

当图像的直方图限制在特定区域时,直方图均衡化效果很好。在直方图覆盖较大区域(即同时存在亮像素和暗像素)的强度变化较大的地方,效果不好。请检查其他资源中的SOF链接。

CLAHE:对比度受限的自适应直方图均衡

我们刚刚看到的第一个直方图均衡化考虑了图像的整体对比度。在许多情况下,这不是一个好主意。例如,下图显示了输入图像及其在全局直方图均衡后的结果。

006b64a938d9b02d7964a4a33dccd88e.png

直方图均衡后,背景对比度确实得到了改善。但是在两个图像中比较雕像的脸。由于亮度过高,我们在那里丢失了大多数信息。这是因为它的直方图不像我们在前面的案例中所看到的那样局限于特定区域(尝试绘制输入图像的直方图,您将获得更多的直觉)。

因此,为了解决这个问题,使用了自适应直方图均衡。在这种情况下,图像被分成称为“tiles”的小块(在OpenCV中,tileSize默认为8x8)。然后,像往常一样对这些块中的每一个进行直方图均衡。因此,在较小的区域中,直方图将限制在一个较小的区域中(除非存在噪声)。如果有噪音,它将被放大。为了避免这种情况,应用了对比度限制。如果任何直方图bin超出指定的对比度限制(在OpenCV中默认为40),则在应用直方图均衡之前,将这些像素裁剪并均匀地分布到其他bin。均衡后,要消除图块边界中的伪影,请应用双线性插值。

下面的代码片段显示了如何在OpenCV中应用CLAHE:

cv2 as cv

img= cv.imread(tsukuba_l.pngcreate a CLAHE object (Arguments are optional).

clahe = cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))

cl1=clahe.apply(img)

cv.imwrite(clahe_2.jpga2f27c22c36015d5a3772c014838d66d.png

附加资源:

Wikipedia page on Histogram Equalization:http://en.wikipedia.org/wiki/Histogram_equalization

Masked 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)

相关文章

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值