OpenCV学习18-直方图均衡化-Opencv方法

'''
直方图均衡化,如何使用它来改善图片的对比。
如果一副图像中的大多是像素点的像素值都集中在一个像素值范围之内会怎样
呢?例如,如果一幅图片整体很亮,那所有的像素值应该都会很高。但是一副
高质量的图像的像素值分布应该很广泛。所以你应该把它的直方图做一个横向
拉伸(如下图),这就是直方图均衡化要做的事情。通常情况下这种操作会改
善图像的对比度。
使用Opencv函数
'''

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
import matplotlib
#设置中文字体
matplotlib.rcParams['font.family'] = 'SimHei'

img = cv.imread('timg8.jpg',0)

#cv.equalizeHist对图像进行直方图均衡化
equ = cv.equalizeHist(img)

#np.hstack():在水平方向上平铺,np.vstack():在竖直方向上堆叠,把两个图像拼
#成一个图像
res = np.hstack((img,equ))
plt.subplot(121), plt.imshow(img, 'gray')
plt.title(u'原图'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(equ,'gray')
plt.title(u'均衡后'), plt.xticks([]), plt.yticks([])
plt.show()

OpenCV学习18-直方图均衡化-Opencv方法

'''
'''
CLAHE 有限对比适应性直方图均衡化
我们在上边做的直方图均衡化会改变整个图像的对比度,但是在很多情况下,这样做
的效果并不好。
的确在进行完直方图均衡化之后,图片背景的对比度被改变了。但是你再对比一下两
幅图像中雕像的面图,由于太亮我们丢失了很多信息。造成这种结果的根本原因在于
这幅图像的直方图并不是集中在某一个区域(试着画出它的直方图,你就明白了)。
为了解决这个问题,我们需要使用自适应的直方图均衡化。这种情况下,整幅图像会
被分成很多小块,这些小块被称为“tiles”(在 OpenCV 中 tiles 的大小默认是
 8x8),然后再对每一个小块分别进行直方图均衡化(跟前面类似)。所以在每一个
的区域中,直方图会集中在某一个小的区域中(除非有噪声干扰)。如果有噪声的
话,噪声会被放大。为了避免这种情况的出现要使用对比度限制。对于每个小块来
说,如果直方图中的 bin 超过对比度的上限的话,就把其中的像素点均匀分散到
其他 bins 中,然后在进行直方图均衡化。最后,为了去除每一个小块之间“人造
的”(由于算法造成)边界,再使用双线性差值,对小块进行缝合。
'''

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
import matplotlib

plt.rcParams['savefig.dpi'] = 150 #图片像素
plt.rcParams['figure.dpi'] = 150 #分辨率
#设置中文字体
matplotlib.rcParams['font.family'] = 'SimHei'

img = cv.imread('timg9.jpg',0)

#cv.equalizeHist对图像进行直方图均衡化
equ = cv.equalizeHist(img)

#创建一个CLAHE对象
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)


plt.subplot(131), plt.imshow(img,'gray')
plt.title(u'原图'), plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.imshow(equ,'gray')
plt.title(u'直方图均衡化'), plt.xticks([]), plt.yticks([])
plt.subplot(133), plt.imshow(cl1,'gray')
plt.title(u'CLAHE 直方图均衡化'), plt.xticks([]), plt.yticks([])

plt.show()

OpenCV学习18-直方图均衡化-Opencv方法