希望一幅图像的像素占有全部可能的灰度级并且分布均匀,能够具有高对比度。
使用的方法是灰度级变换。
基本思想是把原始图的直方图变换为均匀分布的形式,这样就增加了像素灰度值的动态范围,从而达到增强图像整体对比度的效果。
随便测试一张图片的直方图:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def cv_show(name, img):
'''
显示图像
'''
cv.imshow(name, img)
cv.waitKey()
cv.destroyAllWindows()
img = cv.imread("pictures/hisColor.jpg", 0)
plt.subplot(2, 2, 1), plt.imshow(img, 'gray'), plt.title("img"), plt.xticks(
[]), plt.yticks([])
plt.subplot(2, 2, 2), plt.hist(img.ravel(), 256), plt.title("hist"), plt.xticks(
[]), plt.yticks([])
plt.show()
可以看到该图片的灰度级都集中在低灰度的区域,所以图像看起来很暗并且对比去较低。
opencv为我们提供了一个直方图均衡化的函数equalizeHist(),该函数可以帮我们自动进行直方图均衡化从而达到图像增强的目的。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def cv_show(name, img):
'''
显示图像
'''
cv.imshow(name, img)
cv.waitKey()
cv.destroyAllWindows()
img = cv.imread("pictures/hisColor.jpg", 0)
plt.subplot(2, 2, 1), plt.imshow(img, 'gray'), plt.title("img"), plt.xticks(
[]), plt.yticks([])
plt.subplot(2, 2, 2), plt.hist(img.ravel(), 256), plt.title("hist"), plt.xticks(
[]), plt.yticks([])
img_equal = cv.equalizeHist(img)
plt.subplot(2, 2, 3), plt.imshow(img_equal, 'gray'), plt.title("img_equal"), plt.xticks(
[]), plt.yticks([])
plt.subplot(2, 2, 4), plt.hist(img_equal.ravel(), 256), plt.title("img_equal_hist"), plt.xticks(
[]), plt.yticks([])
plt.show()
可以看到,直方图分布更均匀了,同时图像也变亮,对比度也增强了。但是,直方图均衡化没考虑到局部图像区域,只是将整体进行均衡化,由于整体亮度的提升,使得局部图像的细节变得模糊。
所以提出了自适应均衡化的想法:自适应直方图均衡化是在均衡化过程中只利用局部区域窗口内的直方图分布来构建映射函数。
opencv提供了自适应均衡化的函数createCLAHE。
cv2.createCLAHA(clipLimit, titleGridSize)
clipLimit颜色对比度的阈值, titleGridSize进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作。
使用过程:首先用createCLAHA实例化均衡直方图函数,然后用apply进行均衡化操作。
自适应两个改进:
1.设置阈值 超过部分裁剪并分配 可以避免过度增强噪声点。
2.双线性插值 考虑附近的四个窗口。
(具体算法可以参考其他资料)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def cv_show(name, img):
'''
显示图像
'''
cv.imshow(name, img)
cv.waitKey()
cv.destroyAllWindows()
img = cv.imread("pictures/hisColor.jpg", 0)
plt.subplot(3, 2, 1), plt.imshow(img, 'gray'), plt.title("img"), plt.xticks(
[]), plt.yticks([])
plt.subplot(3, 2, 2), plt.hist(
img.ravel(), 256), plt.title("hist"), plt.xticks([]), plt.yticks([])
img_equal = cv.equalizeHist(img)
plt.subplot(3, 2, 3), plt.imshow(
img_equal, 'gray'), plt.title("img_equal"), plt.xticks([]), plt.yticks([])
plt.subplot(3, 2, 4), plt.hist(img_equal.ravel(),
256), plt.title("img_equal_hist"), plt.xticks(
[]), plt.yticks([])
clahe = cv.createCLAHE(clipLimit=10.0, tileGridSize=(8, 8))
img_clahe = clahe.apply(img)
plt.subplot(3, 2, 5), plt.imshow(
img_clahe, 'gray'), plt.title("img_clahe"), plt.xticks([]), plt.yticks([])
plt.subplot(3, 2, 6), plt.hist(img_clahe.ravel(),
256), plt.title("img_clahe_hist"), plt.xticks(
[]), plt.yticks([])
plt.show()