Python,OpenCV直方图均衡化以提高图像对比度

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python,OpenCV直方图均衡化以提高图像对比度相关的知识,希望对你有一定的参考价值。

这篇博客将介绍直方图均衡化(全局 & 自适应直方图均衡化),以及如何使用它来提高图像的对比度。

  • 均衡化是指将亮区的输入像素映射到全局的输出像素。

  • 均衡化作用:1)可以提升图像的对比度;2)使所有图像具有相同的照明条件;

1. 效果图

原始图如下:
在这里插入图片描述
全局均衡化效果图如下:
红色线:直方图效果图(可以看到像素大多分布在靠近0以及200左右,暗色和亮色基本均衡,中间值的像素要少一些,对比原始图也是一致的)
绿色线:全局均衡化后结果(中间像素也有了对应的分布)
在这里插入图片描述
全局直方图均衡化优化后效果图如下:
使用掩码数组去掉了0像素,会发现绿色线均衡后更加平均了
在这里插入图片描述
应用到原始图上也可以看到像素分布更均衡了;
在这里插入图片描述
自适应直方图均衡化效果图如下:
可以看到自适应直方图均衡化的效果要比全局直方图均衡化效果图好很多.
在这里插入图片描述

2. 原理

2.1 直方图均衡化应用

提升对比度 & 使所有图像具有相同的照明条件;

  • 即使图像是较暗的图像(而不是较亮的图像),均衡后也会得到几乎相同的图像。因此它被用作“参考工具”以使所有图像具有相同的照明条件。 例如,在人脸识别中,在训练人脸数据之前,对人脸图像进行直方图均衡化处理,使其具有相同的光照条件。

  • 当图像的直方图仅限于某一特定区域时,直方图均衡化是很好的。如果直方图覆盖了一个很大的区域,即同时存在亮像素和暗像素,那么它在强度变化很大的地方就不起作用。

2.2 直方图均衡化分类

  • 全局直方图均衡化
  • 对比度受限自适应直方图均衡化(CLAHE Contrast Limited Adaptive Histogram Equalization),简称自适应直方图均衡化

图像的全局对比度不一定能取得很好的结果,自适应直方图均衡化是它的优化版本。自适应直方图均衡化会把图像分成称为“tiles”的小块(在OpenCV中,tileSize默认为8x8)。然后像全局直方图均衡化一样对每个块进行直方图均衡。

因此在一个很小的区域,直方图会局限在一个很小的区域(除非有噪声)。如果有噪音,它就会被放大。为了避免这种情况,应用了对比度限制。如果任何直方图单元高于指定的对比度限制(OpenCV中默认为40),则在应用直方图均衡化之前,这些像素将被剪裁并均匀分布到其他单元。均衡后,为了消除瓷砖边界中的伪影,应用双线性插值。

3. 源代码

# 直方图均衡化(全局直方图均衡化 VS CLAHE对比度受限自适应直方图均衡化)

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

img = cv2.imread('ym2.jpg', 0)
cv2.imshow("origin", img)

# 法一:numpy计算直方图并均衡化
hist, bins = np.histogram(img.flatten(), 256, [0, 256])

cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()

# 红色线:直方图像素分布情况,绿色线全局直方图均衡化结果图
plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 256, [0, 256], color='r')
plt.xlim([0, 256])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.show()

# 引入掩码数组,优化均衡化直方图
cdf_m = np.ma.masked_equal(cdf, 0)  # 标识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]
plt.plot(img2, color='b')
plt.hist(img.flatten(), 256, [0, 256], color='r')
plt.xlim([0, 256])
plt.legend(('cdf2', 'histogram'), loc='upper left')
plt.show()

# # 法二:opencv计算直方图并均衡化
img = cv2.imread('ym2.jpg', 0)
equ = cv2.equalizeHist(img)
res = np.hstack((img, equ))  # 并排显示图像
# cv2.imwrite('ym2_equ.jpg', res)
cv2.imshow("grayimg VS hist_equalization", res)
cv2.waitKey(0)

# 自适应直方图均衡化
img = cv2.imread('ym2.jpg', 0)
# 创建自适应直方图均衡化对象
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
cv2.imwrite('ym2_clahe_2.jpg', np.hstack([img,cl1]))
cv2.imshow("grayimg VS clahe", np.hstack([img, cl1]))
cv2.waitKey(0)

参考

以上是关于Python,OpenCV直方图均衡化以提高图像对比度的主要内容,如果未能解决你的问题,请参考以下文章

利用OpenCV的函数equalizeHist()对图像作直方图均衡化处理

OpenCV使用python实现限制对比度的自适应直方图均衡化

OpenCV图像增强---灰度变换直方图均衡化

(转)OpenCV图像增强算法实现(直方图均衡化拉普拉斯LogGamma)

OpenCV 完整例程47. 图像增强—直方图匹配

OpenCV实战——直方图详解