本节摘要:SOURCE 4.1:全局阈值、Otsu 最大类间方差、自适应局部阈值。本节动手
threshold与adaptiveThreshold,对比光照不均文档。
import cv2 gray = cv2.imread('doc.jpg', 0) _, bin_fixed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) _, bin_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) print('Otsu T =', _)
Otsu 自动选 T 使类间方差最大 — 适合双峰直方图。
adapt = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
块大小 11、常数 C 控制局部对比 — 适合扫描件阴影。
| 方法 | 适用 |
|---|---|
| 固定 T | 光照均匀 |
| Otsu | 双峰灰度 |
| 自适应 | 光照渐变 |

⚠️ 常见坑:彩色图直接 threshold — 先转灰度或分通道。
💡 关键直觉:阈值分割 = 1 维分类 — 特征只有灰度。
下一节 Canny 边缘。
阈值分割把每个像素的灰度值和阈值比较,大于等于阈值的归为一类,否则归为另一类——这是最简单的一维分类器,特征只有一个:灰度值。它的成立前提是前景和背景在灰度上有明显分离。判断是否成立,画直方图看是否双峰即可。固定阈值适合光照均匀、前景背景灰度稳定的场景;当光照变化或前景本身灰度分布宽时,固定阈值就失效,需要更聪明的策略(Otsu 或自适应)。
import cv2 gray = cv2.imread('doc.jpg', 0) # Otsu 会自动算阈值并返回 t_otsu, bin_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 自适应:逐块计算局部阈值 adapt = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
Otsu 遍历所有可能的阈值,选一个让"类间方差最大"的 T。直觉理解:好的阈值应该让两类内部的灰度尽量集中(类内方差小)、两类之间尽量分开(类间方差大),Otsu 把这两者合成一个目标函数直接优化。它的失效场景:直方图只有一个峰(前景背景灰度混叠,如纹理复杂或光照渐变)、三类以上(需要多阈值)、前景占比极小(峰被淹没)。遇到这些情况,改用自适应阈值或换分割方法。
adaptiveThreshold 在每像素邻域内算局部阈值(均值或高斯加权),再减去常数 C。效果是"局部相对前景背景比较"——光照渐变(文档上的阴影、书本中间缝的暗带)被消除,因为每个区域都用自己的基准。参数上,blockSize 决定邻域大小(越大越平滑但可能吞掉细节),C 是减去的常数(越大阈值越低、前景越多)。适合"光照不均但有局部对比度"的场景,比如扫描件、拍照文档、标签表面。
阈值分割的输出(二值图)几乎从不直接使用,后面通常接:形态学开闭去噪、连通域分析过滤小目标、边缘提取或轮廓拟合得到几何参数。二值图还是很多算法的输入前提——求轮廓(findContours)、算面积和质心、做掩膜抠图。掌握"阈值、形态学、连通域"的固定套路,就能搭建工业视觉里最常见的检测流水线。彩色图像做阈值要谨慎:直接对 RGB 三通道分别阈值会割裂颜色信息,先转灰度或 HSV 再分割更合理。
实验建议:准备三张图——光照均匀的工件、带阴影的文档、直方图单峰的纹理图,分别跑固定阈值、Otsu、自适应,记录各自的表现。这个对比能直观说明"没有万能阈值,方法选择取决于直方图形状和光照情况"。
关于 Otsu 的一个实用补充:它也可以用于自动确定其他算法的参数初值,比如先 Otsu 得到大致的二值图,再根据连通域统计微调阈值。自动阈值加人工微调,是产线上兼顾效率与可控性的常用组合。本节核心一句话:阈值分割是最快、最可解释、也最容易受光照影响的分割方法,用前先看直方图,用后必接形态学与连通域后处理。最后,分割效果的量化评估要养成习惯:有真值标签时算 IoU 或像素准确率,没有真值时用连通域数量、前景占比等统计量辅助判断。数值加目视双轨,是评估分割质量的标准姿势。
补一个衔接深度学习的视角:阈值分割虽然古老,但它的思想依然活在现代算法里。语义分割网络输出的概率图,最后一步通常就是阈值化(0.5 截断)得到前景掩膜;自适应阈值的思想也演变成了注意力机制里的"局部归一化"。更重要的是,阈值分割是理解"像素分类"的最小案例——一个阈值就是一个单特征分类器,理解它的局限(对光照、类别重叠敏感),才能真正理解为什么需要特征工程和深度学习。作为第一个分割算法,它搭建了"分割 = 分类"的心智模型,后续所有分割方法都可以看作这个模型的扩展。