4. 累积分布函数计算
任务说明
本案例针对一幅8位灰度图像(灰度级0~255),完成以下任务:计算其归一化直方图,进而计算累积分布函数(CDF),并绘制CDF曲线。输入图像为单通道灰度图,输出为CDF数值表与可视化曲线,用于后续直方图均衡化映射。
核心实现
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
def compute_normalized_histogram(gray_img):
"""计算灰度图像的归一化直方图"""
hist = np.zeros(256, dtype=np.float64)
h, w = gray_img.shape
total_pixels = h * w
for i in range(h):
for j in range(w):
hist[gray_img[i, j]] += 1
return hist / total_pixels
def compute_cdf(norm_hist):
"""根据归一化直方图计算累积分布函数"""
cdf = np.zeros_like(norm_hist)
cumulative = 0.0
for i in range(256):
cumulative += norm_hist[i]
cdf[i] = cumulative
return cdf
def plot_cdf(cdf, title="CDF Curve"):
"""绘制CDF曲线"""
plt.figure(figsize=(8, 4))
plt.plot(np.arange(256), cdf, color='#1f77b4', linewidth=2)
plt.xlabel("Gray Level")
plt.ylabel("CDF Value")
plt.title(title)
plt.grid(True, alpha=0.3)
plt.xlim(0, 255)
plt.ylim(0, 1.0)
plt.tight_layout()
plt.show()
# 生成测试图像(64x64,包含暗、中、亮三个灰度带)
test_img = np.zeros((64, 64), dtype=np.uint8)
test_img[0:21, :] = 50 # 暗带
test_img[21:43, :] = 150 # 中带
test_img[43:64, :] = 220 # 亮带
# 计算并绘制
norm_hist = compute_normalized_histogram(test_img)
cdf = compute_cdf(norm_hist)
plot_cdf(cdf)
# 打印CDF关键值(灰度0、50、150、220、255处)
for g in [0, 50, 150, 220, 255]:
print(f"灰度 {g}: CDF = {cdf[g]:.4f}")
代码说明
代码首先用compute_normalized_histogram遍历图像像素,统计每个灰度级出现次数并除以总像素数,得到归一化直方图。随后compute_cdf从灰度0开始逐级累加归一化直方图值,得到单调不减的CDF数组,其取值范围为[0,1]。测试图像人为构造为三个等宽灰度带(50、150、220),便于直观验证CDF的阶梯状累积特性。
运行与验证
运行方式:确保已安装numpy、matplotlib、Pillow,直接执行上述脚本即可。
验证方法:观察弹出的CDF曲线,应呈现三段明显台阶:灰度0~49处CDF为0,灰度50~149处CDF约为1/3,灰度150~219处CDF约为2/3,灰度220~255处CDF为1.0。终端打印的CDF值应与曲线一致,例如灰度50处CDF≈0.3333,灰度220处CDF≈1.0000。
判定标准:若曲线在灰度50、150、220处出现三次跳变,且最终CDF(255)=1.0,则实现正确。