OpenCV 从零学习 · 第 11 讲:直方图与均衡化
函数:cv2.calcHist / cv2.equalizeHist / cv2.createCLAHE | 难度:★★☆☆☆
"直方图"就是每个亮度值出现了多少次的统计。一张发暗的图,它的像素亮度全挤在低值区;一张对比度差的图,亮度集中在一小段。直方图均衡化就是把这些"挤在一起"的亮度拉开铺满整个 0~255,从而让暗部细节浮现出来。本讲讲怎么画直方图、做全局均衡,以及更稳的局部均衡 CLAHE。
一、计算直方图 cv2.calcHist
hist = cv2.calcHist(images, channels, mask, histSize, ranges)
| 参数 | 含义 |
images | 原图列表,如 [gray] |
channels | 通道索引列表,灰度图用 [0] |
mask | 掩膜,None 表示全图 |
histSize | 直方图 bin 数量,如 [256] |
ranges | 像素值范围,[0,256] |
返回形状为 (256, 1) 的数组,每个元素是对应亮度的像素计数。它是 NumPy 数组,可用 matplotlib 的 plot(hist) 画出来(注意 matplotlib 显示前若用 OpenCV 读图,需先转 RGB,见第 3 讲)。
场景 A · 先看"病根"再处理
一张发暗的图,画直方图会发现像素全堆在左侧(低值区)。看清分布,才知道该用均衡化"拉开",而不是盲目调亮度。直方图是诊断工具,不是处理工具。
一张发暗的图,画直方图会发现像素全堆在左侧(低值区)。看清分布,才知道该用均衡化"拉开",而不是盲目调亮度。直方图是诊断工具,不是处理工具。
二、全局均衡化 equalizeHist
dst = cv2.equalizeHist(src)
| 参数 | 含义 |
src | 必须是8 位单通道灰度图 |
它把整张图的亮度分布"拉伸"成近似均匀,暗部变亮、对比度拉满。返回同样是 8 位灰度图。
场景 B · 过暗照片 / 监控夜景增强
夜晚监控截屏一片黑、细节看不见:
夜晚监控截屏一片黑、细节看不见:
eq = cv2.equalizeHist(gray) 后,暗部的墙角、车牌开始浮现。也常用于OCR 前的预处理,把模糊文档拉清楚。
场景 C · 彩色图怎么办?
equalizeHist 只吃灰度图。彩色图要均衡,先 split 成 B/G/R 三个通道分别均衡再 merge——但这样容易改变原图色相。更稳妥的是转 YCrCb 或 HSV,只对亮度通道均衡(见下方提示)。
⚠ 新手必踩坑
- 输入必须是单通道灰度图,传彩色三通道会报错。
- 全局均衡是"一刀切"——它会把背景噪点也一起放大,脸部肤色也可能失真发灰。背景复杂的图慎用,改用 CLAHE。
三、局部均衡 CLAHE(更稳)
CLAHE(限制对比度自适应直方图均衡)把图切成小块,每块单独均衡,并限制对比度放大倍数,避免噪点爆炸。是实际工程首选。
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
dst = clahe.apply(gray)
| 参数 | 含义 |
clipLimit | 对比度上限,越大越"猛",默认 40(OpenCV 单位是 256 分之一尺度下的阈值) |
tileGridSize | 分块大小 (行,列),块越小越局部 |
场景 D · 医学影像 / 人脸局部增强
X 光、眼底照这类"局部细节很重要、背景又暗"的图,CLAHE 比全局均衡化更干净——局部对比度上来了,噪点没被放大。人脸检测前也常用它提亮五官。
X 光、眼底照这类"局部细节很重要、背景又暗"的图,CLAHE 比全局均衡化更干净——局部对比度上来了,噪点没被放大。人脸检测前也常用它提亮五官。
import cv2
img = cv2.imread('dark.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) # 诊断用
eq = cv2.equalizeHist(gray) # 全局均衡
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
local = clahe.apply(gray) # 局部均衡
⚠ 新人常混淆
calcHist 只是"数数画统计",不修改图像;equalizeHist / CLAHE 才真正"改图"。别把两者当一回事。
本讲要点
- 直方图 = 亮度分布统计,
calcHist是诊断工具,输出(256,1)数组。 equalizeHist全局拉开对比度,只吃灰度图;会放大噪点、可能偏色。CLAHE分块局部均衡 + 限幅,工程更稳,是首选。- 彩色图均衡建议只对亮度通道(YCrCb/HSV)做,避免色相失真。
下一讲可进阶:第 12 讲 · 模板匹配(cv2.matchTemplate)——在一张大图里"找小图",做最简单的目标定位。
