直方图均衡化
1. 图像直方图
图像直方图,是指对整个图像在灰度范围内的像素值(0-255)统计出现频率次数,据此生成的直方图,称为图像直方图或直方图。直方图反映了图像灰度的分布情况,是图像的统计学特征。也可以说,直方图是图像中像素强度分布的图形表达方式,它统计了每一个强度值所具有的像素个数。
2. 直方图均衡化
直方图均衡化是以累计分布函数为核心,将原始图像灰度直方图从比较集中的某个灰度区间,非线性地映射为在全部灰度范围内的较均匀分布,从而增强对比度。
直方图均衡化的数学原理如下:
首先作原始图像灰度的概率直方图, 然后设输入像素灰度值为rk,累计分布函数为
其中ni为图像中灰度值为ri的像素频数,n为图像像素总数。设输出像素灰度值为sk,像素范围为smin-smax。期望输出灰度直方图是均匀分布,即
令C(sk)=C(rk),即得
所以最终直方图均衡化的点算子为
3. 直方图均衡化的Python实现
根据直方图均衡化的数学原理,用Python实现代码如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 计算累计分布函数
def C(rk):
# 读取图片灰度直方图
# bins为直方图直方柱的取值向量,hist为bins各取值区间上的频数取值
hist, bins = np.histogram(rk, 256, [0, 256])
# 计算累计分布函数
return hist.cumsum()
# 计算灰度均衡化映射
def T(rk):
cdf = C(rk)
# 均衡化
cdf = (cdf - cdf.min()) * (255 - 0) / (cdf.max() - cdf.min()) + 0
#cdf = 255.0 * cdf / cdf[-1]
return cdf.astype('uint8')
# 读取图片
img = cv.imread('lenna.jpg', 0)
# 将二维数字图像矩阵转变为一维向量
rk = img.flatten()
# 原始图像灰度直方图
plt.hist(rk, 256, [0, 255], color = 'r')
# 直方图均衡化
imgDst = T(rk)[img]
plt.hist(imgDst.flatten(), 256, [0, 255], color = 'b')
plt.legend(['Before Equalization','Equalization'])
plt.show()
# 展示前后对比图像
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Gray')
plt.subplot(122), plt.imshow(imgDst, cmap='gray'), plt.title('Histogram Equalization')
plt.show()
均衡前后图像灰度直方图如下所示:
直方图均衡化前后的图像对比如下所示:
4. opencv-python中直方图均衡化的应用
opencv-python中使用cv.equalizeHist函数即可实现直方图均衡化,其函数原型如下:
dst=cv.equalizeHist(src[, dst])
注意:输入需是灰度图像。
测试代码如下:
img = cv.imread('lenna.jpg', 0)
dst = cv.equalizeHist(img)
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Gray'), plt.axis('off')
plt.subplot(122), plt.imshow(dst, cmap='gray'), plt.title('Histogram Equalization'), plt.axis('off')
plt.show()
效果如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)