什么是角点?
简单说:
- 边缘(edge)
- 团块(flat)
- 角点(corner)
如何检测角点?
和边缘检测一样也有了成熟的算法。
- Harris算法
- Shi-Tomasi算法
- 亚像素级角点检测
Harris角点检测原理
思想是用小窗口在图像上平移,如果窗口内像素:
- 沿任意方向变化不明显(flat)
- 沿某一方向变化不明显(edge)
- 沿任意方向明显变化(corner)
通过移动前后窗口的自相关函数(对应位置的差平方)大小,可以衡量变化程度。下图中u, v为移动方向,取相互垂直的方向最佳。
窗口的权重可以取均值或者高斯权重,为下图中的w。
将I(x + u, y + v)进行一阶泰勒展开,得到:
因此E(u, v)化为:
E(u, v)变成一个二元二次函数:
此时回顾一下角点处,E(u, v)应满足对u, v变化而剧烈变化,如何用这个二元二次表达式来衡量这种变化程度呢?
利用几何,可知E(u, v)是椭圆形的表达式,因此原点到椭圆形的边缘可表示沿改方向的变化程度。
已知u, v方向垂直,通过坐标变换可以更新E(u, v)为E(x, y),相当于椭圆旋转为于x, y方向垂直,不改变椭圆的形状。
但这样做的原因是,我们可以将矩阵转换为对角矩阵的形式,其中特征值就是旋转后,x和y方向的变化程度的衡量。
设定一个阈值,就可以判断是conner、edge、flat了。
Harris角点性质
- 对亮度和对比度变化不敏感
- 具有旋转不变性,椭圆怎么转都行,u,v怎么取都行,计算的都是长轴和短轴的半径
- 不具备尺度不变性,边缘太小的话,就是角点了。原因是窗口的尺寸是固定的。
Harris角点检测实现
具体步骤:
- 计算图像梯度,梯度的计算和移动的步长相关的,移动的步长和分辨率相关的,可以看到一般默认移动两步。
- 利用上述结果和窗口权重,求出M矩阵
- 求出M矩阵
- 求响应值,不计算两个特征值了,用响应值判断是不是角点。
- 固定窗口(5*5)内进行非极大值抑制,筛选角点。
OpenCV中对应的函数是:
void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, intborderType = BORDER_DEFAULT )