赞
踩
声明:本系列博客是我在学习OpenCV官方教程中文版(For Python)(段力辉 译)所做的笔记。所以,其中的绝大部分内容引自这本书,博客中的代码也是其配套所附带的代码或书中的代码,侵删。其中部分代码可能会因需要而改动。在本系列博客中,其中包含书中的引用,也包括我自己对知识的理解,思考和总结。本系列博客的目的主要有两个,一个是可以作为我自己的学习笔记,时常复习巩固。第二个是可以为想学习python下的opencv 3 相关知识的朋友提供一些参考。
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。
直方图均衡化要做的事情就是,当一副图像中的大多是像素点的像素值都集中在一个像素值范围之内时,例如,如果一幅图片整体很亮,那所有的像素值应该都会很高。但是一副高质量的图像的像素值分布应该很广泛。所以你应该把它的直方图做一个横向拉伸(如下图),这个横向拉伸的过程就是直方图均衡化要做的要做的事情,通常情况下这种操作会改善图像的对比度。
OpenCV中的直方图均衡化:
OpenCV中的直方图均衡化函数为cv2.equalizeHist(),这个函数的输入图片仅仅是一副灰度图像,输出结果是直方图均衡化之后的图像。来看看代码:
import cv2
import numpy as np
img = cv2.imread('jianzhu2.jpg',0)
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
cv2.imwrite('jianzhu2_1.png',res)
这是原图:
这是运行结果:
当直方图中的数据集中在某一个灰度值范围内时,直方图均衡化很有用。
我们使用上边这个函数做的直方图均衡化会改变整个图像的对比度,但是在很多情况下,这样做的效果并不好。例如,下图分别是输入图像和进行直方图均衡化之后的输出图像。
的确在进行完直方图均衡化之后,图片背景的对比度被改变了。但是你再对比一下两幅图像中雕像的面图,由于太亮我们丢失了很多信息。造成这种结果的根本原因在于这幅图像的直方图并不是集中在某一个区域(如果不明白,试着画出它的直方图,你就明白了)。
为了解决这个问题,我们需要使用自适应的直方图均衡化。这种情况下,整幅图像会被分成很多小块,这些小块被称为“tiles”(在 OpenCV 中 tiles 的大小默认是 8x8),然后再对每一个小块分别进行直方图均衡化(跟前面类似)。
所以在每一个的区域中,直方图会集中在某一个小的区域中(除非有噪声干扰)。如果有噪声的话,噪声会被放大。为了避免这种情况的出现要使用对比度限制。对于每个小块来说,如果直方图中的 bin 超过对比度的上限的话,就把其中的像素点均匀分散到其他 bins 中,然后在进行直方图均衡化。最后,为了去除每一个小块之间“人造的”(由于算法造成)边界,再使用双线性差值,对小块进行缝合。
下面的代码显示了如何使用OpenCV中的CLAHE。
这次同样使用刚那张图片,我们可以清晰地看到这两种不同方法的差别。
import cv2
import numpy as np
img = cv2.imread('jianzhu2.jpg',0)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv2.imwrite('jianzhu2_2.jpg',cl1)
运行结果:
可以看到,在很亮的地方有了很大的改善。
这个方法的确效果很好,以下是更多的例子:
这是原图:
经过CLAHE 有限对比适应性直方图均衡化后:
这是原图:
经过CLAHE 有限对比适应性直方图均衡化后:
效果真的很棒!
如有错误,欢迎批评指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。