1. 图像分割与阈值处理基础

第一次接触图像分割时,我被这个看似高深的概念吓到了。直到有一天,我用手机给身份证拍照存档,发现背景太杂乱影响识别效果,同事告诉我可以用"抠图"功能把背景变成纯白色——这其实就是最简单的图像分割应用。在计算机视觉中,图像分割就像是用不同颜色的马克笔给照片分区涂色,而阈值处理就是其中最基础的"涂色规则"。

OpenCV中的阈值处理本质上是通过设定一个门槛值,把图像的像素分为"通过"和"不通过"两类。想象你在流水线上分拣苹果,设定直径7厘米为阈值,大于7厘米的进入优质果通道,小于等于7厘米的进入普通果通道,这就是最直观的阈值分割。在数字图像中,这个"直径"变成了像素的灰度值,通常用0-255的数值表示。

我处理过的一个典型案例是生产线上的零件检测。当光照条件稳定时,简单的阈值分割就能准确区分零件和背景。但有一次车间换了照明设备,原先设定的阈值突然失效——这就是全局阈值最大的软肋:对光照变化过于敏感。下面这段代码展示了最基本的阈值分割操作:

import cv2
img = cv2.imread('parts.jpg', 0)  # 读取灰度图像
_, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

2. 全局阈值处理的五种招式

在OpenCV的threshold函数中,type参数就像武侠小说里的武功招式,不同的类型会产生完全不同的分割效果。我最常用的是以下五种:

2.1 二值化(THRESH_BINARY)

这招最简单直接,效果就像用黑白印章盖在图像上。处理规则是:像素值>阈值时设为最大值,否则设为0。在文档扫描时特别管用,能把模糊的铅笔字变成清晰的印刷体效果。但遇到反光严重的纸张就会出问题,我曾在处理会议纪要时把反光点误识别为文字。

_, binary = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)

2.2 反二值化(THRESH_BINARY_INV)

相当于把二值化的结果反转,白变黑、黑变白。在医学影像处理中很常见,比如X光片想要突出骨骼结构时。有次处理CT扫描图,反二值化后意外发现了一个微小的骨折痕迹,这个案例让我印象深刻。

2.3 截断处理(THRESH_TRUNC)

这个模式像给图像"封顶",超过阈值的像素被压扁到阈值高度。适合处理过度曝光的照片,我曾用它挽救过一批过曝的产品展示图,保留了高光区域的细节。但要注意,输出仍是灰度图而非二值图。

2.4 零处理(THRESH_TOZERO系列)

包含两种变化:TOZERO是低于阈值归零,TOZERO_INV是高于阈值归零。就像选择性失明,只关注特定亮度区间的信息。在分析热成像图时,我常用它来聚焦特定温度区间。

3. 自适应阈值:应对光照不均的利器

去年处理停车场监控画面时,我发现同一个画面中,阳光直射区域和阴影区域需要完全不同的阈值。这时全局阈值就力不从心了,自适应阈值应运而生。它就像个智能调节的探照灯,走到哪里就按当地亮度调整标准。

OpenCV提供两种自适应方法:

  • 均值法(ADAPTIVE_THRESH_MEAN_C):取邻域平均值减去常数C
  • 高斯法(ADAPTIVE_THRESH_GAUSSIAN_C):按高斯分布加权计算

实测发现,高斯法在保留细节方面更优,但计算量稍大。blockSize参数很关键,太小会引入噪声,太大又可能模糊边界。经过多次测试,我总结出一个经验公式:blockSize ≈ 图像短边长度/30 + 1(取奇数)。

adaptive = cv2.adaptiveThreshold(img, 255, 
                cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                cv2.THRESH_BINARY, 21, 5)

4. Otsu算法:自动找阈值的黑科技

Otsu算法是我最欣赏的阈值确定方法,它能自动找到最佳分割点。原理很巧妙:通过最大化类间方差来寻找阈值,相当于在两个灰度峰之间找到最佳分界线。但要注意几个使用细节:

  1. 图像必须是双峰直方图(有明显的前景和背景区分)
  2. 调用时要将阈值参数设为0
  3. 需要加上THRESH_OTSU标志

有次处理古代文献扫描件,墨迹深浅不一,手动调阈值费时费力。改用Otsu算法后,不仅效率提升,识别准确率还提高了15%。但遇到直方图单峰的情况(比如雾天照片),Otsu就会失效。

_, otsu = cv2.threshold(img, 0, 255, 
               cv2.THRESH_BINARY+cv2.THRESH_OTSU)

5. 实战对比:不同场景下的算法选择

通过一个实际案例来对比三种方法:我们要分割一张光照不均的工业零件图像。原始图像左侧有强光照射,右侧处于阴影中。

全局阈值(127)结果

  • 左侧:过曝区域完全丢失细节
  • 右侧:阴影区域误判为前景
  • 适用场景:光照均匀的文档扫描

自适应阈值(blockSize=31, C=5)结果

  • 左侧:保留了螺钉纹理
  • 右侧:正确识别了边缘
  • 适用场景:监控视频、医学影像

Otsu算法结果

  • 整体效果均衡但不够精细
  • 适用场景:双峰直方图的自然图像

在我的项目经验中,这三种方法常常需要组合使用。比如先用自适应阈值做初步分割,再用Otsu算法优化局部区域。对于特别复杂的场景,还需要结合边缘检测等方法。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐