Edge detector
边缘是图像中沿某一方向强度发生剧烈变化的位置。边缘检测是一种基础的图像处理操作,其核心成分——图像梯度——同样是角点检测、光流以及直接法 SLAM 的基础。
首先是灰度化和平滑
边缘检测(和大多数 SLAM 前端处理一样)作用于灰度图像:梯度只需要强度信息,一个通道的处理速度比三个通道快 3 倍,而且颜色在不同光照条件下并不一致。标准的转换方式是亮度公式 。
由于求导会放大噪声,图像在计算梯度之前会先用高斯模糊进行平滑——即与如下核进行卷积
的选择决定了你所检测边缘的尺度:小的 保留细节(也保留噪声),大的 只保留粗略的结构。
Sobel 算子
Sobel 算子通过与两个 核的卷积来计算图像梯度:
梯度大小为 ,梯度方向为 。Sobel 算子把求导( 模式)和与之垂直方向上的平滑( 权重)结合起来,因此比朴素的有限差分更能抵抗噪声。
Canny 边缘检测器
Canny 检测器是一个多阶段算法,能把原始梯度转化为细而定位良好的边缘曲线:
- 高斯平滑以抑制噪声。
- Sobel 梯度计算(大小和方向)。
- 沿梯度方向进行非极大值抑制,把脊线细化为单像素宽度:只有当某像素的梯度大小在沿梯度方向的两个邻居中都最大时,该像素才会被保留。
- 双阈值滞后处理,设置一个高阈值和一个低阈值:强边缘(高于高阈值)被保留,弱边缘(介于低阈值和高阈值之间)只有在与强边缘相连时才被保留。这样可以保留连续的轮廓,同时剔除孤立的噪声响应。
import cv2
edges = cv2.Canny(gray, threshold1=50, threshold2=150) # low, high
这两种检测器在 OpenCV 中都只需一行代码(cv::Sobel、cv::Canny),但值得从零实现一次,以便真正理解卷积和梯度的工作原理。
常见陷阱
- 跳过模糊步骤:在含噪的原始图像上直接运行 Canny 会产生斑驳、破碎的边缘;应将 (或内置的孔径大小)与阈值一起调优。
- 单一阈值的思维方式:两个 Canny 阈值正是该算法的核心所在——单一阈值要么会使轮廓破碎,要么会引入噪声;低阈值应设为高阈值的一个比例。
- 边缘不是特征:一个边缘点可以沿其轮廓滑动(孔径问题),因此它只在一个方向上约束几何关系——这正是为什么角点而不是边缘点被用作匹配的关键点,也是为什么基于边缘的 SLAM 把边缘视为一维约束的原因。
对SLAM的意义
Sobel 计算出的图像梯度是 Harris 结构张量以及 Lucas-Kanade 光流法的输入,因此边缘检测是通往 SLAM 前端特征机制的一块垫脚石。边缘本身也被直接使用:在纹理稀少的人工环境中,线/边缘特征可以对点特征形成补充(例如 PL-SLAM),而 LSD-SLAM 等直接法则隐式地依赖高梯度(类似边缘)的像素来进行光度对齐。