【基础】直方图均衡化

1. 什么是直方图的均衡化?

直方图均衡化是通过拉伸像素强度的分布范围,使得在0~255灰阶上的分布更加均衡,改善图像了全局亮度和对比度,达到改善图像主观视觉效果的目的。对比度较低的图像适合使用直方图均衡化方法来增强图像细节。

image.png

2. openCV实现直方图均衡化

  • 灰度图均衡,直接使用cv2.equalizeHist(gray)

  • 彩色图均衡,分别在不同的通道均衡后合并

import cv2
import matplotlib.pyplot as plt

gray = cv2.imread('lena_non_equ.jpg', cv2.IMREAD_GRAYSCALE)
gray_equalize = cv2.equalizeHist(gray)  # 直方图均衡化

hist = cv2.calcHist([gray], [0], None, [256], [0, 255])
hist_equalize = cv2.calcHist([gray_equalize], [0], None, [256], [0, 255])

plt.subplot(2, 2, 1), plt.imshow(gray, 'gray')
plt.subplot(2, 2, 2), plt.imshow(gray_equalize, 'gray')
plt.subplot(2, 2, 3), plt.plot(hist)
plt.subplot(2, 2, 4), plt.plot(hist_equalize)

plt.show()

效果如下:

image.png

可以很明显地看到均衡化后图片的亮度和对比度效果都要明显好于原图。

3. 直方图自适应均衡化

但是,有时,直方图均衡化会分散图中某些部分的信息,如下图:image.png

可以看到对原图进行直方图均衡化之后,效果反而不好了,尤其对于局部。

如果我们对局部进行均衡化,而不是全局均衡化的话,图像能保留局部纹理信息:

image.png

(左:原图 中:直方图均衡化 右:直方图自适应均衡化)

此时,我们需要使用自适应直方图均衡化,将整张图片分成几个部分来分别均衡化,然后再组合在一起。用于生成自适应均衡化图像的函数为:

cv2.createCLAHA(clipLimit, titleGridSize)

  • clipLimit:颜色对比度的阈值。

  • titleGridSize:进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作。

import cv2
import numpy as np

gray = cv2.imread('img_1.png', cv2.IMREAD_GRAYSCALE)

# 实例化自适应直方图均衡化函数
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 进行自适应直方图均衡化
res_clahe = clahe.apply(gray)
# 进行图像的展示
res = np.hstack((gray, res_clahe))
cv2.imshow('res', res)
cv2.waitKey()
cv2.destroyAllWindows()

请自行试验。