1. Opencv中的KeyPoint类介绍
KeyPoint类的构造函数如下:
KeyPoint();
KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
主要用来存储找到的特征点, 其包含的信息为, 特征点的坐标(包括横坐标x, 纵坐标y), 特征点的尺寸,或者也叫尺度, 特征点的角度或者朝向, 特征点的响应, 以及对应的层级; 这里重点说一下尺度, 响应,和层级;
- 特征点的尺度scale,或尺寸size
主要与特征点提取时算子的窗口大小有关; 比如SURF特征提取时 ,如果使用的是11*11的Hessian Operator, 那么这个特征点对应的size就是11/2, 也就是half the length of the approximated Hessian operator;
或者再以FAST特征为例, 在FAST特征的实际提取过程中,opencv的源码如下:
keypoints.push_back(KeyPoint((float)j, (float)(i-1), 7.f, -1, (float)score));
也就是最后返回的特征点们 对应的size都固定为7.f; 猜想这里的特征提取的patch默认为7;
但是在ORBSLAM中在提取特征完成之后,有下面的操作:
const int nkps = keypoints.size();
for (int i = 0; i < nkps; i++) {
keypoints[i].pt.x += minBorderX;
keypoints[i].pt.y += minBorderY;
keypoints[i].octave = level;
keypoints[i].size = scaledPatchSize;
}
每个特征点的size设置为'''PATCH_SIZE*mScaleFactor[level]''', 也就是如果该特征点在原图层,即金字塔的第0层被提取, 那么其size为PatchSize = 31, 但是如果在金字塔的第一层为PatchSIze*1.2 = 30*1.2 =36; 个人感觉, 每个特征的默认模式不同, 好在这个size在后续的代码中也没有进一步使用;
- 特征点的层级octave
这个在特征中很好理解, 该数字代表了其所属的金字塔层级, 原图像中提取的特征点octave为0, 第一层octave为1; 以此类推. 这个值用于在面获取该点的置信度;
2. 特征点的响应 response
response具体指代什么, opencv的官网解释如下:
Response: keypoint detector response on the keypoint (that is, strength of the keypoint)
翻译来讲, 就是特征点检测器 在该特征点的 响应; 比较模糊, 这里想以moravec角点检测来说一说响应response, 有不对的地方还欢迎指正; 之所以以moravec为例是因为个人觉得这个特征提供了一个最基础的模板, 且很好理解; 关于moravec特征点的讲解可以参考 这里;
以下面的图像区域, 举例来说3x3窗口的角点检测步骤:
绿色的窗口为原窗口, 中心点即为(x,y) , 这里I(x,y) = 51; 角点检测的本质为检测像素的变化; 对于Harris角点, 最基本的计算点的兴趣值的公式为:
其中为窗口函数, 为坐标(x,y)处的像素值; 则表示了图像的变化程度;
Moravec角点在计算时, 需要计算四个方向, 也就是该点在0度方向, 45度方向, 90度方向,和135度方向, 这个四个方向的图像变化程度;
对应需要计算的值即为 , , , ;
最终的响应函数为
个人理解对应到response的值,也就是该R函数计算出来的值, 如果这个值大于一个阈值, 那么这个点便可以称作为特征点, 表示四个方向变化都很剧烈, 称之为角点;
3. Harri角点简单介绍response;
Harri角点在Moravec角点的基础上, 修改了原本的窗口函数, 角点检测函数, 以及最后的响应函数;
想要进一步了解FAST角点的response的,可以参考 这里, 对opencv中FAST角点提取做了比较详细的解释, 关键步骤在CornerScore() 函数中, 当前点的得分, 最为特征点的响应值;
参考: