重要说明:本文从网上资料整理而来,仅记录博主学习相关知识点的过程,侵删。
一、参考资料
直方图均衡化的原理及实现
图像处理之直方图均衡化
二、直方图
1. 直方图的概念
图像的灰度直方图,描述了图像中灰度分布情况,能够很直观的展示出图像中各个灰度级所占的多少。图像的灰度直方图是灰度级的函数, 描述的是图像中具有该灰度级的像素的个数: 其中, 横坐标是灰度级, 纵坐标是该灰度级出现的次数。如下图所示:
2. 直方图的性质
- 直方图反映了图像中的灰度分布规律。 它描述每个灰度级具有的像素个数, 但不包含这些像素在图像中的位置信息。 图像直方图不关心像素所处的空间位置, 因此不受图像旋转和平移变化的影响, 可以作为图像的特征。
- 任何一幅特定的图像都有唯一的直方图与之对应, 但不同的图像可以有相同的直方图。
3. cv2.calcHist()
函数原型:calcHist(images,channels,mask,histSize,ranges,hist=None,accumulate=None)
功能:计算图像直方图。
参数解释
images
:图像矩阵,例如:[image];channels
:通道数,例如:0;mask
:掩膜,一般为:None;histSize
:直方图大小,一般等于灰度级数;ranges
:横轴范围。
4. 示例代码
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 获取灰度图像
img = cv2.imread("lena_std.tif", 0)
# cv2.imshow("src", img)
# 灰度图像的直方图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.figure() #新建一个图像
plt.hist(img.ravel(), 256)
plt.show()
绘制直方图,如下图所示:
三、直方图均衡化
1. 引言
假如图像的灰度分布不均匀,其灰度分布集中在较窄的范围内,使图像的细节不够清晰,对比度较低。通常采用直方图均衡化及直方图规定化两种变换,使图像的灰度范围拉开或使灰度均匀分布,从而增大反差,使图像细节清晰,以达到图像增强的目的。
直方图均衡化,对图像进行非线性拉伸,重新分配图像的灰度值,使一定范围内图像的灰度值大致相等。这样,原来直方图中间的峰值部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较为平坦的直方图。
2. 均衡化算法
直方图的均衡化实际也是一种灰度的变换过程,将当前的灰度分布通过一个变换函数,变换为范围更宽、灰度分布更均匀的图像。也就是将原图像的直方图修改为在整个灰度区间内大致均匀分布,因此扩大了图像的动态范围,增强图像的对比度。通常均衡化选择的变换函数是灰度的累积概率,直方图均衡化算法的步骤:
- 依次扫描原始灰度图像的每一个像素, 计算出图像的灰度直方图;
- 计算灰度直方图的累积分布函数;
- 根据累积分布函数和直方图均衡化原理得到输入与输出之间的映射关系;
- 最后根据映射关系得到结果进行图像变换。
举例说明,如下图所示,可直观的理解直方图均衡化的原理及过程:
3. cv2.equalizeHist()
函数原型:equalizeHist(src, dst=None)
功能:计算直方图均衡化。
参数解释
src
:图像矩阵(单通道图像);dst
:默认即可。
4. 代码示例
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 获取灰度图像
img = cv2.imread("lena_std.tif", 0)
cv2.imshow("src", img)
# 灰度图像的直方图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.figure() #新建一个图像
plt.hist(img.ravel(), 256)
plt.show()
# 灰度图像直方图均衡化
dst = cv2.equalizeHist(img)
# 直方图
hist = cv2.calcHist([dst],[0],None,[256],[0,256])
plt.figure()
plt.hist(dst.ravel(), 256)
plt.show()
cv2.imshow("dst", dst)
cv2.waitKey(0)
src图像的直方图
直方图均衡化之后的直方图
src源图像与dst图像对比
彩色直方图均衡化
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 彩色图像直方图均衡化
img = cv2.imread("lena_std.tif", 1)
cv2.imshow("src", img)
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst_rgb", result)
cv2.waitKey(0)
src源图像与dst图像对比