1. 直方图基础:图像直方图概念、性质与可视化
各位同学,咱们今天聊点实在的。图像直方图,说白了就是一张图的「像素户口本」。你想想看,一张图片里每个像素的亮度值是多少,分布得均匀不均匀,直方图一眼就能告诉你。我刚开始接触图像处理时,总觉得这玩意儿就是个统计图表,没什么大不了的。直到有一次做工业检测项目,产品表面瑕疵死活检测不出来,最后发现是光照不均导致直方图分布出了问题。嗯,从那以后我再也不敢小看它了。
1.1 什么是图像直方图?
图像直方图,本质上是一个离散函数。它统计了图像中每个灰度级出现的像素个数。对于一张 8 位灰度图,灰度级范围是 0~255,直方图就统计这 256 个值各自出现了多少次。
用数学语言表达就是:
h(r_k) = n_k
其中 r_k 是第 k 个灰度级,n_k 是该灰度级对应的像素数量。就这么简单。
但别小看这个简单的统计量。我在项目中见过太多人,上来就调各种高级算法,结果效果还不如先看一眼直方图来得直接。直方图就是图像的「体检报告」,哪里暗了、哪里亮了、哪里对比度不够,一目了然。
核心要点:直方图只统计像素出现的频率,不记录像素的空间位置。也就是说,两张内容完全不同的图,可能拥有完全相同的直方图。这一点很重要,后面我们会反复提到。
1.2 直方图的性质
直方图有几个关键性质,我建议大家记牢。这些性质在后续的均衡化和规定化操作中会反复用到。
| 性质 | 说明 | 实际意义 |
|---|---|---|
| 归一化性 | 所有灰度级的像素数之和等于图像总像素数 | ∑h(r_k) = 总像素数,可用于验证统计是否正确 |
| 可加性 | 多张图的直方图可以叠加 | 适合做批量图像统计,比如分析一个视频序列的整体亮度分布 |
| 平移不变性 | 图像平移后,直方图不变 | 直方图不关心物体在画面中的位置 |
| 旋转不变性 | 图像旋转后,直方图不变 | 同样,旋转也不影响像素值的统计分布 |
| 尺度不变性 | 图像缩放后,直方图形状基本不变(需归一化) | 适合做不同分辨率图像的对比分析 |
我的经验:归一化直方图在实际项目中更常用。把每个灰度级的像素数除以总像素数,得到的就是概率分布。这样不管图像多大,直方图都能直接对比。我曾经用这个方法快速筛选了一批不同分辨率的监控图像,找出曝光异常的帧,效率非常高。
1.3 直方图可视化方法
光看数字没意思,咱们得把直方图画出来。OpenCV 提供了 calcHist 函数,用起来非常顺手。我个人习惯用 Matplotlib 来展示,因为它的图表更美观,适合做汇报。
下面是一个完整的示例代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像(灰度模式)
img = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
# 计算直方图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
# 可视化
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.imshow(img, cmap='gray')
plt.title('原始图像')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.plot(hist, color='blue')
plt.title('灰度直方图')
plt.xlabel('灰度级')
plt.ylabel('像素数')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
这段代码会生成两张图:左边是原始灰度图,右边是它的直方图曲线。你一眼就能看出图像的亮度分布情况。
注意:cv2.imread 默认以 BGR 格式读取彩色图像。如果你直接对彩色图做灰度直方图,记得先转成灰度图,或者指定 cv2.IMREAD_GRAYSCALE 参数。我曾经在这个坑里摔过一次,调试了半天才发现是通道顺序搞错了。
1.4 直方图能告诉我们什么?
拿到一张直方图,你能读出哪些信息?我总结了几个常见模式:
- 偏暗图像:直方图集中在左侧(低灰度级区域),右侧几乎没数据。说明图像整体曝光不足。
- 偏亮图像:直方图集中在右侧(高灰度级区域),左侧几乎没数据。说明图像过曝。
- 低对比度图像:直方图集中在中间一段,两端没有延伸。图像看起来灰蒙蒙的,像蒙了一层雾。
- 高对比度图像:直方图分布均匀,从暗到亮都有覆盖。图像细节丰富,层次感强。
- 多峰分布:直方图出现多个波峰。通常意味着图像中有多个亮度差异明显的区域,比如前景和背景。
你想想看,这些信息对后续的图像增强有多重要?直方图均衡化,说白了就是把分布不均匀的直方图「拉平」,让像素分布更均匀。而直方图规定化,则是把直方图「塑形」成你想要的样子。这些操作的前提,都是你得先读懂直方图。
1.5 本章知识体系
为了让大家更直观地理解直方图在整个课程中的位置,我画了一张结构图:
这张图把本章的知识点串起来了。从直方图的基本概念出发,理解它的核心性质,掌握可视化方法,最后为后续的均衡化和规定化打下基础。每一步都环环相扣,缺一不可。
1.6 小结
直方图是图像处理中最基础、最直观的工具之一。它不复杂,但很重要。我建议你拿到一张图后,第一件事就是看看它的直方图。养成这个习惯,很多问题在动手之前就能发现。