本节摘要:阈值按灰度把像素分成两类或多类,是最快的分割探针。全局阈值用固定 T,自适应阈值按局部统计,Otsu 自动选使类间方差最大的 T。原文示例里 127、窗口 11、常数 2 与 Otsu 标志位,是起点不是教条。直方图不双峰时,换方法比死拧 T 更有用。
阅读完本节,你应当能够:
阈值的直觉是:目标与背景在亮度上能分开。分开,就在缝上砍一刀。看不看直方图直接设 127,等于闭眼砍。双峰清晰,刀落在谷底;单峰或多峰纠缠,任何一刀都会误伤。这就是为什么本节是第 3 章第一站:几行代码告诉你数据有没有「灰度可分性」。没有,去改第 2.3 节的颜色空间或改采集,不要开始堆网络。
全局阈值对整张图一个 T。实现就是逐像素比较。原文用 127 和二值化类型。亮前景暗背景用大于 T 为前景;反过来用小于。多类阈值是多个刀,工业上有时用。全局方法的失败模式单一:光照渐变时,同侧物体一半过线一半不过。
_, t_fix = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) adapt = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2) _, t_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) print("Otsu 选出的 T", _)
自适应:每个像素的 T 来自邻域均值或高斯加权均值再减常数 C。窗口 11 必须为奇数。窗口太小跟噪声走,太大接近全局。C 用来压过轻微纹理。扫描件阴影、侧光金属,自适应通常明显好于 Otsu。
Otsu 遍历可能的 T,让「类间方差」最大,等价于两类分得最开。假设大致是两类、两类方差别极端畸形。细胞染色均匀时很好用。前景只占 1% 时,最大类间方差可能把 T 推到只切出噪声,因为「两类」在面积上极不对称。这时先用形态学或 ROI 限制范围,或改用带权重的变体,不要迷信自动。
Otsu 的 T 应当打印到日志。突然从 90 跳到 160,说明这张图分布变了:曝光变了或空视野。产线可用 T 的滑动作为异常探针,比等模型分数掉下来更早。
| 方法 | 假设 | 强项 | 弱项 |
|---|---|---|---|
| 固定 T | 光照稳定已知 | 最快、可解释 | 曝光一变全军覆没 |
| Otsu | 大致双峰 | 免手调 T | 面积悬殊、多峰、渐变 |
| 自适应均值 | 局部对比足够 | 阴影、渐变 | 大空洞内部乱切 |
| 自适应高斯 | 局部对比且中心更可信 | 边界稍稳 | 更慢一点 |
⚠️ 常见坑:在已二值化的图上再 Otsu。第二刀没有灰度信息,结果无意义。
💡 关键直觉:阈值是在一维亮度轴上切。轴上分不开,任何 T 都是政治妥协。
把阈值掩码与真值算交并比或 Dice,记为基线。后面 U-Net 若低于这条线,先查数据对齐,再查损失。很多项目深度模型输给 Otsu,因为标签和预处理不一致,不是因为卷积不够深。
多类阈值少见但有用:把直方图分成背景、工件、高光。高光单独一类可避免把反光当缺陷。实现上可用连续两个 T。评估时高光可并入背景或当忽略,按伤害定。
窗口 11、C=2 来自原文示例。我的做法是在验证小集上扫一组奇数窗口和 C,选基线最好的,然后冻结。不要每张图手调——那就不是算法,是手工分割。

失败不是调 T 到 126 或 128。检查:是否该用单通道以外的颜色轴;是否先做第 2.2 节去噪;是否应用 ROI 挡住无关高亮。仍失败,记录「灰度不可分」,交给聚类或学习方法。阈值的价值包括否定:它证明问题不在 T,在表示。
二值输出后接开运算去斑、闭运算补洞,再评估。把形态学核也记入基线配置。否则你无法复现那次「还不错」的演示。
Otsu 每张图选出的 T 应写入日志。产线视野里突然空了(没放工件),直方图单峰,T 会跳到奇怪的位置,二值图变成噪声。用 T 的滑动窗口做异常探针,比等缺陷漏检更早发现「这张图不该分割」。自适应方法没有单一 T,可监控前景占比:占比崩了同样报警。
多阈值:高光单独切出来当忽略或当第三类,避免反光被当成裂纹。实现上先在高灰度端切一刀,再对剩余做 Otsu。评估时高光若当忽略,要与第 4.3 节忽略口径一致。原文全局 127 只适合演示图;你的相机 8 位还是 12 位,有效灰度范围不同,127 可能根本不在缝上。
和颜色空间配合:在 H 或 a 通道上做 Otsu,等于换了一根更好的轴。轴上仍双峰,阈值就能当产线方案。轴上单峰,记录「一维不可分」,交给聚类或学习,不要把自适应窗口拧到 99。窗口过大时自适应退化成近似全局,阴影问题会回来。
演示可以,算法不可以。手调无法复现,也无法当基线。验证小集上扫一组参数,冻结,测试只跑冻结组。深度模型同样遵守:测试集不搜参。
基线入库格式:方法名、参数、形态学核、Dice、mIoU、日期、数据版本。第 5 章任何一次「提升」都要能指出打败的是表里哪一行。没有表,提升是口头的。
每天抽几张看直方图是否仍双峰。峰被填平,先查曝光和脏镜头,再查是否有人把滤波核加大。Otsu 的 T 滑动超出历史分位,报警停机,不要把坏图送进深度模型当「难例」。空视野单峰是合法异常,应用层应拒绝分割而不是输出满屏噪声。
自适应窗口必须奇数。偶数会在实现里被拒或被悄悄减一,复现对不上。C 过大等于把局部对比压没,细裂纹消失;C 过小等于把纹理当目标。在验证小集扫窗口与 C,冻结一对,测试不搜。和深度学习一样,测试集没有第二次发言权。多阈值把高光切成忽略时,评估脚本必须认识该忽略值,否则高光会当假阳性惩罚模型。
基线表一行一个方法,列里有参数、核、Dice、mIoU、日期、数据版本。深度实验必须引用行号。没有行号的「我们比传统好」是口头禅。原文 127、窗口 11、常数 2、Otsu 标志位都是钉子,用来证明调用写对,不是产线默认。12 位相机不要假装 8 位的 127 还在缝上。
直方图值班与 T 滑动报警进产线,空视野应拒绝分割。窗口奇数、C 与窗口在验证冻结。多阈值高光当忽略时评估必须认识该值。基线表行号被第 5 章引用,没有行号不准声称超过传统。12 位相机重新量缝,禁止抄 127。和颜色轴配合:轴上仍单峰则记录一维不可分,交给聚类或学习,不要把窗口拧到 99 假装自适应还能救。
产线值班把直方图和 T 放在同一屏。T 超出历史分位先停分割再查曝光,不要把空视野当难例送进网络。窗口与 C 的冻结对写进契约,测试集禁止重搜。高光忽略值出现在评估函数签名里,缺了就当发布失败。基线表禁止原地改单元格,新参数新行号,第 5 章引用行号说话。12 位数据单独一页参数,抄 127 视为事故。轴上单峰记录「一维不可分」并链到聚类或学习,窗口拧到 99 的实验打作废标。形态学核与 T 同一天冻结,拆开冻结会导致「那天还不错」无法复现。把 Otsu 选出的 T 序列当传感器,比只看 Dice 更早发现采集漂了。原文三种调用留作接口钉子,产线数字以冻结对为准。
反例档案:空视野 T 乱跳仍输出满屏斑,现场当缺陷。加上 T 分位报警后停机查空视野。第二份:测试集上重搜窗口,报告漂亮不可复现。冻结对写入契约后禁止重搜。12 位抄 127 的事故写进新人必读。基线表只读行号被引用后,深度实验终于有参照物。
口令卡:直方图与 T 同屏、窗口奇数冻结、高光忽略进签名、行号只读、12 位另页、单峰记不可分。空视野停机。测试禁搜。形态学与 T 同日冻。Otsu 序列当传感器。三种调用是钉子不是默认。
值班同屏、冻结对、行号只读、12 位另页,四条写成产线作业指导书首页。空视野停机优先于任何模型。单峰记不可分并链到下一节聚类,禁止把窗口拧到极限充数。形态学与 T 必须同一天冻结,拆开就无法复现「那天还不错」。Otsu 的 T 序列进监控,采集漂移会先于 Dice 报警。原文三种调用留在接口测试,产线数字以契约为准。
产线作业指导书首页四条可抽问:同屏、冻结、只读行号、12 位另页。抽问答不出不准上机。空视野停机演练每班一次。单峰样本必须留下「不可分」标记并禁止再拧窗口。T 与形态学核的冻结日期必须相同,不同则实验无效。监控里没有 T 序列的工位视为未接入传感器。接口测试仍跑原文三种调用,但报告数字只引用契约行号。
现场抽问:空视野现在会停机吗?T 和核是不是同一天冻的?报告引用的是行号还是口头 127?12 位图有没有另页?单峰有没有不可分标记?答不全今晚不得改窗口。监控没有 T 序列就去接传感器,不要先开深度实验。
失败演练甲:故意送空视野,应停机而不是出斑。故意用 12 位图套 127,应走另页或失败。故意报告引用口头 127 而不是行号,评审打回。三场演练过了,这一节的基线才配签字。
演练不过,基线节不准签字。空视野、12 位套用、口头 127 三场都要留下记录。
全局阈值、Otsu、自适应阈值三种调用都要在同一张简单图上出封闭区域,再比 IoU。三种都碎,先查照明和对比度,不要立刻上网络。阈值基线的 IoU 写进实验日志首页,后面任何网络若低过它,优先查标签与损失,而不是加层。
下一节处理粘连:区域生长与分水岭,专门对付「阈值糊成一块」的目标。