3. 特征点提取:角点检测、亚像素优化、边缘响应抑制
好,咱们进入第三章。特征点提取,说白了就是给相机找「地标」。你想想看,相机在动,场景在变,如果没有一些稳定的、可重复的「锚点」,那后续的匹配和位姿估计根本没法玩。
我个人习惯把特征点比作「棋盘的十字交叉」。为什么?因为棋盘格角点天然就是几何上的稳定结构。你从左边看、右边看、斜着看,那个交叉点始终在那里。嗯,这就是我们做外参标定时最爱的特征。
3.1 角点检测:从直觉到算法
角点检测,说白了就是找「像素值变化剧烈」的位置。但怎么定义「剧烈」?
我记得刚入行时,导师让我手动标定相机。我拿着鼠标在图像上点角点,点得手都酸了。后来才知道,有成熟的算法可以自动做。
最经典的当属 Harris 角点检测。它的核心思想很简单:
- 在一个小窗口内,如果往任何方向移动窗口,像素灰度都变化很大 → 这就是角点
- 如果只在一个方向变化大(比如边缘)→ 这不是角点
- 如果怎么移动都没变化 → 平坦区域,忽略
数学上,Harris 构造了一个矩阵 M,然后计算响应值 R:
R = det(M) - k * (trace(M))²
其中 k 是经验常数,一般取 0.04~0.06。R 大于某个阈值,就认为是角点。
关键点:Harris 角点具有旋转不变性,但不具备尺度不变性。不过对于棋盘格标定来说,尺度变化通常不大,所以够用了。
我在项目中遇到过一个问题:用 Harris 检测棋盘格时,如果棋盘格倾斜角度太大,角点响应会变弱。后来我加了一个自适应阈值策略,效果好了很多。
3.2 亚像素优化:把精度推到极限
好,角点检测出来了。但问题是,像素是离散的。你检测到的角点坐标是 (100, 200),但真实的角点可能在 (100.35, 200.62)。
这就是亚像素精度。为什么要做?
- 外参标定对角度误差极其敏感。0.1 像素的误差,可能导致几度的旋转偏差
- 棋盘格角点本身是几何交点,理论上可以无限精确
常用的亚像素优化方法有两种:
- 基于梯度的方法:利用角点附近梯度正交的特性,迭代求解
- 基于多项式拟合的方法:对响应曲面做二次拟合,找到极值点
我个人更推荐第一种。为什么?因为它利用了图像的几何约束,鲁棒性更好。
OpenCV 里直接提供了 cornerSubPix() 函数。用法很简单:
cv::cornerSubPix(
gray_img, // 输入灰度图
corners, // 初始角点坐标(整数)
cv::Size(5,5), // 搜索窗口大小
cv::Size(-1,-1), // 死区(一般设为 -1)
cv::TermCriteria(
cv::TermCriteria::EPS + cv::TermCriteria::COUNT,
30, // 最大迭代次数
0.001 // 精度要求
)
);
我的经验:搜索窗口不要太大,5x5 或 7x7 就够了。太大反而会引入噪声。迭代次数 30 次基本足够,精度设到 0.001 像素就非常好了。
我曾经遇到一个坑:在低光照条件下,亚像素优化会发散。后来我加了一个前置检查——如果角点附近的梯度幅值太小,就跳过优化,直接用整数坐标。这招很管用。
3.3 边缘响应抑制:别把边缘当角点
这是新手最容易忽略的一步。你想想看,Harris 检测器对边缘也有响应。如果棋盘格旁边有一根笔直的线条,算法很可能把它误判为角点。
边缘响应抑制,说白了就是「把那些长得像角点、但其实是边缘的点剔除掉」。
怎么做?核心思想是分析 M 矩阵的两个特征值 λ₁ 和 λ₂:
- 如果 λ₁ 和 λ₂ 都很大且相近 → 角点
- 如果 λ₁ 很大,λ₂ 很小 → 边缘
- 如果 λ₁ 和 λ₂ 都很小 → 平坦区域
所以我们可以定义一个质量指标:
quality = min(λ₁, λ₂) / max(λ₁, λ₂)
这个比值越接近 1,说明越像角点。一般设个阈值,比如 0.1,低于这个值的就扔掉。
注意:阈值设得太高会丢掉真正的角点,设得太低又滤不干净边缘。我一般从 0.05 开始试,根据实际效果调整。
嗯,这里还要提一个 OpenCV 里的细节。在 goodFeaturesToTrack() 函数中,有一个参数 qualityLevel,它做的就是这件事。但很多人不知道,这个参数其实是在做边缘响应抑制。
我曾经在一个项目中,标定板旁边放了一个黑色的矩形框。结果每次检测都会在那个矩形框的角上多出几个「假角点」。后来加了边缘响应抑制,问题立刻解决了。
3.4 本章知识体系
下面这张图总结了本章的核心逻辑。你可以看到,三个步骤是串联的:先粗检测,再精优化,最后去伪存真。
3.5 实战建议
最后,给你几个我在实际项目中总结的经验:
| 步骤 | 常见问题 | 我的建议 |
|---|---|---|
| 角点检测 | 检测不到角点 | 检查图像对比度,适当降低阈值 |
| 亚像素优化 | 优化结果发散 | 减小搜索窗口,增加梯度幅值检查 |
| 边缘响应抑制 | 误检边缘为角点 | 调低 quality 阈值,或手动标注 ROI |
好了,这一章就到这里。特征点提取是外参标定的基石,基础打牢了,后面的事情就顺了。
可可精品资料库