3. 边缘检测算法
边缘检测,说白了就是找到图像里亮度变化最剧烈的地方。你想想看,我们人眼是怎么认出物体的?靠的就是轮廓。机器也一样,边缘就是它理解世界的起点。
我刚开始做视觉项目时,第一个接触的就是边缘检测。那时候觉得这玩意儿简单,不就是算个梯度嘛。后来踩的坑多了才发现——选对算子,比调参更重要。
3.1 梯度与边缘的数学直觉
先聊点基础的。图像可以看作一个二维函数 f(x, y),像素值就是函数值。边缘在哪?在函数值突变的地方。
数学上怎么描述突变?用导数。一阶导数的极大值点,或者二阶导数的过零点,都对应着边缘位置。
核心思想:边缘 = 图像函数的局部剧烈变化。一阶导找极值,二阶导找过零。
实际图像是离散的,所以我们用差分代替微分。这就是所有边缘检测算子的数学基础。
3.2 Sobel算子:简单实用的梯度估计
Sobel算子是我个人用得最多的入门级算子。它用两个 3×3 的卷积核,分别计算水平和垂直方向的梯度。
// 水平方向 Gx
[-1, 0, 1]
[-2, 0, 2]
[-1, 0, 1]
// 垂直方向 Gy
[-1, -2, -1]
[ 0, 0, 0]
[ 1, 2, 1]
为什么中间权重大?因为离中心像素越近,贡献越大。这其实是一种加权平滑,能稍微抑制噪声。
计算完 Gx 和 Gy 后,梯度幅值用这个公式:
G = sqrt(Gx² + Gy²)
为了效率,实际项目中常用值近似:
G ≈ |Gx| + |Gy|
我的经验:在嵌入式设备上,用值近似能省掉开方运算,速度提升明显。精度损失在可接受范围内。
Sobel的特点:
- 计算简单,速度快
- 对噪声有一定抑制(加权平滑)
- 只能检测水平和垂直方向,对角边缘不敏感
- 边缘定位精度一般,容易出现双边缘
3.3 Laplacian算子:二阶导数的过零点
Laplacian 算子是二阶微分算子。它不关心梯度方向,只关心梯度变化率。数学形式是:
∇²f = ∂²f/∂x² + ∂²f/∂y²
离散形式常用的 3×3 核:
[ 0, -1, 0]
[-1, 4, -1]
[ 0, -1, 0]
或者带对角线的版本:
[-1, -1, -1]
[-1, 8, -1]
[-1, -1, -1]
注意:Laplacian 对噪声极其敏感。我曾经在一个光照不均匀的项目里直接用 Laplacian,结果边缘没找到,全是噪点。后来必须先做高斯滤波。
Laplacian的特点:
- 各向同性,不依赖方向
- 对孤立点、线端响应强烈
- 对噪声极度敏感,必须预处理
- 会产生双边缘,需要过零点检测
3.4 Canny算子:工业界的黄金标准
说实话,Canny 是我在工业项目中最常用的算子。它不是一个简单的卷积核,而是一套完整的边缘检测流程。
Canny的四个步骤:
- 高斯滤波:平滑图像,抑制噪声
- 计算梯度幅值和方向:通常用 Sobel
- 非极大值抑制:沿着梯度方向,只保留局部最大值
- 双阈值检测:高阈值确定强边缘,低阈值连接弱边缘
关键点:非极大值抑制让边缘变细,双阈值让边缘连续。这两个步骤是 Canny 的精髓。
双阈值怎么设?我一般这样调:
- 高阈值:梯度幅值直方图的 70%-80% 分位点
- 低阈值:高阈值的 0.4-0.5 倍
// OpenCV 示例
cv::Mat edges;
cv::Canny(src, edges, 50, 150); // 低阈值50,高阈值150
避坑指南:我曾经在一个反光工件检测项目里,Canny 参数调了三天。后来发现是高斯滤波的核大小没选对。核太小,噪声没滤干净;核太大,边缘被模糊。建议从 5×5 开始试。
3.5 三种算子的核心对比
| 对比维度 | Sobel | Laplacian | Canny |
|---|---|---|---|
| 数学基础 | 一阶微分 | 二阶微分 | 一阶微分 + 后处理 |
| 方向性 | 水平/垂直 | 各向同性 | 沿梯度方向 |
| 噪声敏感度 | 中等 | 高 | 低(先滤波) |
| 边缘定位 | 一般 | 较差(双边缘) | 精确 |
| 边缘连续性 | 差 | 差 | 好(双阈值) |
| 计算速度 | 快 | 快 | 较慢 |
| 适用场景 | 实时性要求高、边缘简单 | 斑点检测、零交叉 | 高精度、复杂场景 |
3.6 如何选择?我的实战建议
没有最好的算子,只有最合适的。我一般这样选:
- 实时性优先(比如 60fps 的产线):用 Sobel,配合简单的阈值
- 精度优先(比如 PCB 缺陷检测):用 Canny,花时间调参
- 需要检测孤立点或线端(比如晶圆划痕):用 Laplacian,但一定要先滤波
重要提醒:不管用哪种算子,预处理都别省。光照不均先做直方图均衡,噪声大先做高斯或中值滤波。我见过太多人直接拿原图跑边缘检测,结果一塌糊涂。
3.7 本章知识结构图
下面这张图总结了三种算子的核心逻辑和适用场景:
3.8 小结
三种算子各有各的脾气。Sobel 像一把快刀,简单直接;Laplacian 像一把手术刀,精准但娇气;Canny 像一套完整的工具箱,功能强大但需要耐心调校。
我个人建议初学者从 Canny 入手,理解边缘检测的完整流程。等用熟了,再根据实际场景去选 Sobel 或 Laplacian。记住一点:没有银弹,只有最合适的工具。