最近在搞三维的点云拼接,正好发现也有Harris关键点提取,索性将2D与3D做个归纳。后面应该还会有点云特征描述ISS、FPFH等的介绍,敬请期待......
遇到公式显示有问题的刷新一下网页,知乎的解析器偶尔有bug,本文Notion版本,排版会比较好一些:
Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.www.notion.so一、特征定义
-
- 轮廓之间角点
- 视角变化,仍然能被识别
- 梯度变化大
二、提取思想
使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前后窗口中像素灰度变化程度,若任意方向滑动都有较大灰度变化,则认为该窗口内存在角点。这里自定义的变量是滑动的步长与滑动窗口的大小。
三、推导计算
窗口滑动前后的像素灰度变化:
参数分析:
-
- (x,y)是窗口对应的像素坐标位置;
- (u,v)是窗口的偏移量;
- I(x,y)是像素坐标位置(x,y)的图像灰度值;
- w(x,y)是窗口函数,相当于不同类型的权重算子,高斯or平均;能表示窗口不同的贡献度;
化简
根据泰勒公式一阶展开
则
化简后:
四、但事实并非如此
如上就是判断角点的理论方法,而实际上,是通过对窗口内的每个像素在xy方向上的梯度统计分析做判断。
-
- 特征值都比较大时,即窗口中含有角点;
- 特征值一个较大,一个较小,窗口中含有边缘;
- 特征值都比较小,窗口处在平坦区域;
对每一个窗口计算得到一个分数R,根据R的大小来判定窗口内是否存在harris特征角。
R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的|R|为负值,同时设定R的阈值进行角点判断。
五、总流程:
- 计算图像在xy方向的梯度
- 计算梯度乘积
- 使用窗口函数对梯度乘积进行加权,计算M矩阵
- 计算每个像素点的Harris响应值R
- 过滤
六、Harris3D思想
Harris3D 确定角点的方法是方块体内点云的数量变化。
在Harris2D里,我们使用了图像梯度构成的协方差矩阵。
想象一下,如果在 点云中存在一点p,在p上建立一个局部坐标系:z方向是法线方向,x,y方向和z垂直,在p上建立一个小正方体。
-
- 如果小正方体沿z方向移动,那小正方体里的点云数量应该不变
- 如果小正方体位于边缘上,则沿边缘移动,点云数量几乎不变,沿垂直边缘方向移动,点云数量改
- 如果小正方体位于角点上,则有两个方向都会大幅改变点云数量
由二维的M矩阵想到用法向量x,y,z构成协方差矩阵,那么它应该是一个对称矩阵,该矩阵的特征向量有一个方向是法线方向,另外两个方向和法线垂直,那么直接用协方差矩阵替换掉图像里的M矩阵,就得到了点云的Harris算法。其中,半径r可以用来控制角点的规模,r小,则对应的角点越尖锐(对噪声更敏感),r大,则可能在平缓的区域也检测出角点。
在一阶信息量的情况下描述了两个相邻像素的关系。显然这个思想可以轻易的移植到点云上来。
2D中的M矩阵也有相应的3D形式,2D使用梯度,拓展到3D中则使用法向量(包含法线和方向两个信息)。
-
- 计算每个像素点的Harris响应值R
- 计算每个像素点的Harris响应值R
在PCL源码中,也能看到是此设计思路,只摘取部分
template
七、代码样例
-
- Harris2DDIY,按逻辑一步步来,用的是https://www.cnblogs.com/zyly/p/9508131.html的程序
# -*- coding: utf-8 -*-
-
- Harris2D 用opencv接口实现
# -*- coding: utf-8 -*-
-
- Harris3D 用pcl接口实现
static
-
- 效果图
八、本节参考来源于以下网友,十分感谢
-
- 第十一节、Harris角点检测原理(附源码)
- 协方差wiki百科解释
- 机器人三维视觉 pcl 点云库,云关键点 /Keypoints,Harris3D、 NARF
欢迎来我的Notion本文链接评论:链接在这里
https://www.notion.so/blazarlin/Harris-2D-3D-47cc455885a1478a829e577f55362e31www.notion.so求求你改一改文档导入的自动识别把知乎老哥。
2020-0817-22:20