【OpenCV 例程300篇】46. 直方图处理之直方图均衡化(cv2.equalizeHist)
直方图均衡化是一种简单有效的图像增强技术。根据直方图的形态可以判断图像的质量,通过调控直方图的形态可以改善图像的质量。直方图均衡化是将原始图像通过函数变换,调控图像的灰度分布,得到直方图分布合理的新图像,以此来调节图像亮度、增强动态范围偏小的图像的对比度。OpenCV 提供了函数 **cv2. equalizeHist**可以实现直方图均衡化。...
『youcans 的 OpenCV 例程300篇 - 总目录』
【youcans 的 OpenCV 例程300篇】46. 直方图处理之直方图均衡化(cv2.equalizeHist)
图像直方图是反映图像像素分布的统计表,横坐标代表像素值的取值区间,纵坐标代表每一像素值在图像中的像素总数或者所占的百分比。 灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数。
直方图均衡化是一种简单有效的图像增强技术。根据直方图的形态可以判断图像的质量,通过调控直方图的形态可以改善图像的质量。
直方图均衡化是将原始图像通过函数变换,调控图像的灰度分布,得到直方图分布合理的新图像,以此来调节图像亮度、增强动态范围偏小的图像的对比度。
由于人眼视觉特性,直方图均匀分布的图像视觉效果较好。直方图均衡化的基本思想是对图像中占比大的灰度级进行展宽,而对占比小的灰度级进行压缩,使图像的直方图分布较为均匀,扩大灰度值差别的动态范围,从而增强图像整体的对比度。
因此,直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,本质上是根据直方图对图像进行线性或非线性灰度变换。
例如,直方图均衡化可以把原始图像的直方图调整到均匀分布,增加像素之间灰度值差别的动态范围,从而增强图像整体的对比度。
通过累积分布函数(cumulative distribution function, CDF)可以实现将原图像 r 的分布转换成 s 的均匀分布,累计分布函数(CDF)就是是概率密度函数(probability density function, PDF)的积分。
若
p
r
(
r
)
p_r(r)
pr(r) 和 $p_s(s) $表示原图像 r 和新图像 s 的概率密度函数,则:
s
=
T
(
r
)
=
(
L
−
1
)
∫
0
r
p
r
(
r
)
d
r
s=T(r)= (L-1) \int _0 ^r p_r(r) dr
s=T(r)=(L−1)∫0rpr(r)dr
其离散形式为:
s
k
=
T
(
r
k
)
=
(
L
−
1
)
∑
j
=
0
k
p
r
(
r
j
)
=
(
L
−
1
)
∑
j
=
0
k
n
j
N
s_k = T(r_k) = (L-1) \sum_{j=0}^k p_r(r_j) = (L-1) \sum_{j=0}^k \frac{n_j}{N}
sk=T(rk)=(L−1)j=0∑kpr(rj)=(L−1)j=0∑kNnj
于是,可以通过原图像的直方图直接求出均衡化后各像素的灰度级
s
k
s_k
sk,得到实现直方图均衡的转换函数:
(1)计算原始灰度图像的直方图;
(2)通过直方图累加计算原始图像的累计分布函数 CDF;
(3)基于累计分布函数 CDF,通过插值计算得到新的灰度值。
OpenCV 提供了函数 cv2. equalizeHist 可以实现直方图均衡化。
函数说明:
cv2.qualizeHist(src[, dst]) → dst
参数说明:
- src:输入图像
- 返回值 dst:输出图像,直方图均衡化
例程:1.58 直方图均衡
# 1.58 直方图均衡
img = cv2.imread("../images/Fig0310b.tif", flags=0) # flags=0 读取为灰度图像
imgEqu = cv2.equalizeHist(img) # 使用 cv2.qualizeHist 完成直方图均衡化变换
# histogram equalization image
# histImg, bins = np.histogram(img.flatten(), 256) # 计算原始图像直方图
# cdf = histImg.cumsum() # 计算累积分布函数 CDF
# cdf = cdf * 255 / cdf[-1] # 累计函数 CDF 归一化: [0,1]->[0,255]
# imgEqu = np.interp(img.flatten(), bins[:256], cdf) # 线性插值,计算新的灰度值
# imgEqu = imgEqu.reshape(img.shape) # 将压平的图像数组重新变成二维数组
fig = plt.figure(figsize=(7,7))
plt.subplot(221), plt.title("Original image (youcans)"), plt.axis('off')
plt.imshow(img, cmap='gray', vmin=0, vmax=255) # 原始图像
plt.subplot(222),plt.title("Hist-equalized image"), plt.axis('off')
plt.imshow(imgEqu, cmap='gray', vmin=0, vmax=255) # 转换图像
histImg, bins = np.histogram(img.flatten(), 256) # 计算原始图像直方图
plt.subplot(223, yticks=[]), plt.bar(bins[:-1], histImg) # 原始图像直方图
plt.title("Histogram of original image"), plt.axis([0,255,0,np.max(histImg)])
histEqu, bins = np.histogram(imgEqu.flatten(), 256) # 计算原始图像直方图
plt.subplot(224, yticks=[]), plt.bar(bins[:-1], histEqu) # 转换图像直方图
plt.title("Histogram of equalized image"), plt.axis([0,255,0,np.max(histImg)])
plt.show()
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125112487)
Copyright 2022 youcans, XUPT
Crated:2021-11-18
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)