在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

边缘检测

边缘检测寻找亮度变化明显的位置。Sobel 比较局部区域两侧的亮度,计算变化强度,再用阈值筛选。均匀区域即使很亮也会相消,噪声也可能产生响应。

把滤波器想成两侧放着像素的天平:相同亮度抵消,明暗交界使它倾斜。交换两侧,符号反转,幅度不变。因此必须先保留有符号导数,再算边缘强度。

Sobel 怎样计算

本课用 7×7 合成灰度图,亮度从 0 到 8,对内部每个像素读取 3×3 窗口:

Kx = -1  0  1       Ky = -1 -2 -1
     -2  0  2             0  0  0
     -1  0  1             1  2  1

逐元素相乘后加总。Kx 为加权右列减左列,中行权重加倍;Ky 为下行减上行,中列加倍。这也沿差分的垂直方向做了平滑。

Gx 测量从左到右的变化,对应垂直边界;Gy 测量从上到下的变化,对应水平边界。导数方向与边缘方向垂直。

强度为 M = √(Gx² + Gy²),不是概率。负导数与同幅正导数贡献相同。保留规则为 M > 0 且 M >= threshold,所以阈值为零时也不保留平坦区域。

核不翻转,以滑动点积应用,数学上称互相关。行向下、列向右,未施加归一化因子,阈值单位就是未缩放响应。OpenCV 的 Sobel 说明给出相同核和欧氏幅度公式。

逐步演示

默认图像的七行都是:

0  0  0  8  8  8  8

阈值 16。坐标从零开始,只有源图行、列 1–5 能放下完整窗口,输出为 5×5。外圈被排除,不是默认为零。

  1. 中心 (3,1):九个像素全零,Gx = Gy = M = 0,写到输出 (2,0)。已计算的零与尚未计算不同。
  2. 移到 (3,2):每行是 [0,0,8],与 Kx 的乘积如下,总和 32。Ky 上行贡献 −8、下行 +8,相消为零。因此 M = √(32²+0²) = 32,写到 (2,1)。
0  0   8
0  0  16
0  0   8
  1. 完成其余 23 个位置:各输出行均为 [0,32,32,0,0]。中心 (3,2) 与 (3,3) 的窗口行分别为 [0,0,8]、[0,8,8],都跨边界;Kx 中列为零,两侧差未变,均有 Gx = 32、Gy = 0。更右侧虽亮,却因两侧相等输出零。
  2. 应用阈值 16:十个 32 通过,零失败,形成五行两列的响应带。阈值不会把它细化为单像素轮廓。
  3. 反转亮度 I → 8−I:(3,2) 的 Gx 变 −32,Gy 仍零,强度仍 32,全图掩码不变。因为每个核 ΣK = 0,G(8−I) = 8ΣK − ΣKI = −G(I),平方后幅度不变。
  4. 改成单个噪声点:只有 (3,3) 亮度为 8。中心 (2,2) 的窗口中,它在右下角,两个核该处权重都是 1,所以 Gx = Gy = 8,强度 8√2 ≈ 11.3。只看 |Gx| 会低估为 8。
  5. 移到轴向邻居 (2,3):亮点位于窗口下方中央,Kx 权重零、Ky 权重 2,因此 Gx = 0、Gy = 16、M = 16。阈值 12 去掉四个对角响应,保留四个轴向响应。一个噪声点也能产生四处检测。
  6. 比较失败情况:弱边缘在阈值 16 和 4 分别保留零与十格,噪声在阈值 12 保留四格。面板标明这些是比较样例,最后返回所选输入和阈值。

阈值选择

比较阈值时保持图像不变。弱阶跃将亮部从 8 改为 2,响应从 32 降至 8;阈值 16 全删,4 保留十格。边界一直存在,是决策丢弃了它。

噪声例四个轴向邻居为 16,四个对角邻居为约 11.31,阈值 12 仍留下四格,却没有延展的物体轮廓。提高阈值可能去噪,也可能删掉想要的弱边。去噪、细化和连接判断各解决不同问题。

使用范围与单位

Sobel 适合计算便宜、可检查的局部方向或强度,作为图像处理基线或后续特征输入。若后续需方向,应保留 Gx、Gy。单独的掩码无法区分物体边界、阴影和纹理。

需要细边缘与连接判断时,可看 Canny 的额外阶段:降噪、非极大值抑制、双阈值滞后。Canny 仍需参数,也不认识物体;类别或语义边界需要识别或分割模型。

固定核时,亮度乘正数 a,Gx、Gy、M 和等效阈值都乘 a;两个核同乘 s,强度与等效阈值乘 |s|。常量亮度偏移在 valid 窗口中相消。

例如把本图 0..8 映射到 0..255,倍率为 255/8,响应 32 变 1020,阈值 16 变 510;映射到 0..1,则为响应 4、阈值 2。这只是同一图像的等效缩放,不是任意照片的推荐阈值。转字节时的舍入也会改变响应。

导数缓冲区应使用有符号或浮点类型,未缩放 Sobel 可超出输入字节范围。先固定预处理、核大小、核缩放、幅度定义和边界策略,再调阈值。OpenCV 参数文档列出 scale、输出深度和边界选项。若改核大小或把欧氏幅度换成 |Gx|+|Gy|,单一阈值换算未必保留所有判断。

时间与空间

固定 3×3 核每个内部像素做常量次运算,时间 O(HW);存导数、强度、掩码用 O(HW)。核可分离为一维差分与垂直方向的 [1,2,1] 平滑,每个导数可用两次短滤波。反射、复制或 valid 裁剪需明确选择;去噪、细化、连接的成本另计。流式计算可减少工作行,动画还保存揭示快照以支持回拖。

边界情况

  • 均匀亮度:全暗和全亮都为零,测量的是差异。
  • 反向极性:同对比度的明暗交换只翻转符号。
  • 水平边界:Gx 单独会漏掉,需 Gy。
  • 等于阈值:非零且相等则保留,使用完整数值,不用舍入标签比较。
  • 阈值极端:零仍排除 M = 0;48 会排除本课所有支持图案的响应,不是 Sobel 通用上限。
  • 外圈:本例省略,其他实现的反射或复制会改变边界响应。

常见错误

  • 先把负导数裁成零,再算幅度。反转图的 Gx = −32 会因此消失;应先保留符号,再按定义平方或取绝对值。
  • 各图分别按最大响应归一化颜色,使弱边与强边看起来相同。本课强度固定 0..48,输入亮度和输出强度有独立图例。
  • 把掩码当物体识别。噪声、纹理、阴影都能触发亮度变化。CNN生成滤波响应,图像分类再对给定裁剪计算类别,这些是额外运算。

模型范围

本例用小型合成灰度图、固定未缩放 Sobel、valid 内部窗口和一个阈值,没有独立降噪、非极大值抑制、滞后或彩色处理。核自身的垂直方向平滑仍存在。输出可能宽且带噪,不等同完整 Canny 流程。

这些课程共享同一个技巧,或正好接到下一个概念。

锁标表示交互演示需付费。所有讲解文档均可免费阅读。

浏览主题

发现错误或有不清楚的地方? 提交反馈。