4. 直方图均衡化原理
直方图均衡化,说白了就是让一张图的灰度分布从「扎堆」变成「铺开」。我刚开始接触图像增强时,总觉得调亮度对比度就够了,直到有一次处理一张雾天拍的监控画面——整张图灰蒙蒙的,直方图全挤在中间一段。试了各种线性拉伸都不理想,最后用均衡化,效果立竿见影。嗯,从那以后我就把这招当成预处理的标准动作了。
4.1 为什么需要均衡化?
先看一个直观问题。一张曝光不足或过度的图像,它的直方图往往集中在某个狭窄区间。比如暗图,像素大多集中在低灰度区;亮图则集中在高灰度区。这种「集中分布」导致图像对比度低,细节看不清。
均衡化的目标很明确:把原始直方图映射成近似均匀分布。让每个灰度级上的像素数量大致相等,这样图像的动态范围就被充分利用了。
核心思想: 用累积分布函数(CDF)作为映射函数,将原始灰度值重新分配,使输出图像的直方图尽可能平坦。
4.2 累积分布函数(CDF)
要理解均衡化,必须先搞懂CDF。直方图是概率密度函数(PDF)的离散近似,而CDF就是PDF的积分。
对于灰度级 rk,其概率密度为:
p(r_k) = n_k / N
其中 nk 是灰度级 rk 的像素数,N 是总像素数。
CDF 定义为:
CDF(r_k) = Σ p(r_i) (i = 0 到 k)
说白了,CDF 就是「小于等于某个灰度值的像素占比」。它的值从 0 单调递增到 1。
我个人习惯: 在写代码前,先手动算一遍小图像的CDF。比如一张 4×4 的图,灰度范围 0-3,算一遍你就彻底理解映射关系了。纸上得来终觉浅嘛。
4.3 均衡化的数学推导
假设原始灰度 r 在 [0, 1] 区间,其PDF为 p(r)。我们希望找到一个变换 s = T(r),使得输出灰度 s 的PDF是均匀的。
关键定理来了:变换函数 T(r) 取原始图像的CDF,就能实现均衡化。
推导过程很简单:
s = T(r) = ∫ p(w) dw (从 0 到 r)
这个变换的导数 dT/dr = p(r)。根据概率论中变换后的PDF公式:
p_s(s) = p_r(r) · |dr/ds| = p_r(r) · 1/p_r(r) = 1
看,输出PDF恒等于1,完美均匀分布。数学上就是这么漂亮。
我曾经踩过的坑: 离散情况下,CDF是阶梯函数,映射后直方图不会完全平坦,只会「近似均匀」。别指望均衡化后直方图变成一条直线,那是不可能的。我刚开始做时总纠结这个,后来才明白——离散化带来的量化误差是固有的。
4.4 全局均衡化算法
实际工程中,我们处理的是离散灰度级(比如0-255)。算法步骤如下:
- 统计直方图: 计算每个灰度级 rk 的像素数 nk。
- 计算PDF: p(rk) = nk / N。
- 计算CDF: cdf(rk) = Σ p(ri),i=0..k。
- 映射到输出灰度: sk = round( cdf(rk) × (L-1) ),其中 L 是灰度级数(通常256)。
- 替换像素值: 将原图中灰度 rk 的像素替换为 sk。
代码实现非常直接:
def histogram_equalization(img):
# img: 灰度图, 0-255
hist = np.zeros(256, dtype=np.float32)
h, w = img.shape
N = h * w
# 1. 统计直方图
for i in range(h):
for j in range(w):
hist[img[i,j]] += 1
# 2. 计算PDF
pdf = hist / N
# 3. 计算CDF
cdf = np.zeros(256)
cdf[0] = pdf[0]
for k in range(1, 256):
cdf[k] = cdf[k-1] + pdf[k]
# 4. 映射
lut = np.round(cdf * 255).astype(np.uint8)
# 5. 替换
out = lut[img]
return out
工程优化: 实际项目中我会用 np.cumsum 一步算CDF,再用 np.interp 做映射,比手写循环快一个数量级。你想想看,处理一张4K图像,循环256次和循环几百万次,差别太大了。
4.5 算法效果与局限
| 特性 | 说明 |
|---|---|
| 对比度增强 | 显著拉伸图像动态范围,细节更清晰 |
| 自动化 | 无需人工参数,完全由数据驱动 |
| 可逆性 | 映射是单调的,理论上可逆(但量化会损失信息) |
| 噪声放大 | 均匀区域中的噪声会被放大,出现「颗粒感」 |
| 过度增强 | 某些图像会出现不自然的「块状」或「伪影」 |
避坑指南: 我曾经在医学X光片上用全局均衡化,结果骨骼边缘出现了明显的伪影。后来才意识到——医学图像往往有很长的平坦背景区域,均衡化会把背景噪声放大到肉眼可见。这种情况下,自适应均衡化(AHE)或限制对比度自适应直方图均衡化(CLAHE)才是正解。后面章节会详细讲。
4.6 知识结构图
下面这张图梳理了本章的核心逻辑链:
4.7 小结
直方图均衡化是图像增强的基石。它的数学基础是CDF变换,算法简单高效,效果立竿见影。但记住——它不是万能的。遇到噪声多、背景平坦的图像时,要谨慎使用。