OpenCV中CV_EXPORTS类别KeyPoint与KeyPointsFilter头文件分析
用OpenCV一段时间了,说实话KeyPoint接触也算比较多,一直没有时间对其数据结构进行分析。今天打开源码对其keypoint.cpp文件进行简单分析一下:keypoint.cpp主要包含两个类KeyPoint与KeyPointsFilter。其中KeyPoint包含基础的功能函数:读写存储keypoint函数、KeyPoint与Point2f转换函数、计算keypoint点覆盖率函数。KeyPointsFilter类主要是针对KeyPoint数据矢量存储附加一些功能函数:比如runByImageBorder()移除keypoint处于图像边缘的情况等等,下面会逐一进行分析其每个功能函数。首先来看一下KeyPoint类的声明:
其中KeyPoint存储类型已经在上面代码中进行简单注释,一般keypoint坐标属于必须存储参数,而class_id、response等其它属于非必须存在,如果没有保存值一般为-1。
再来看一下KeyPointsFilter类函数:
KeyPointsFilter包含5个功能函数:分别为runByImageBorder()、runByKeyPointSzie()、runByPixelsMask()、removeDuplicated()、retainBest(),其每个函数主要功能已在注释中说明。
下面看一下源码实现KeyPoint::overlap()函数:
overlap()函数主要计算keypoint矢量集中两个kp(点集)覆盖率为多少,其实就是计算两个特征点ovrl = 交集/并集。该函数可以用来进行特征点稳定评估、或者根据ovrl进行重复点判断也是可以的。基础IO接口功能read()与write()函数为静态函数只作用于该keypoint.cpp文件下:
关于KeyPoint与Point2f功能结构矢量集转换模块已经在OpenCV学习之Data Structure Conversion写过,可以进行查看参考。
Ok,下面阅览一下KeyPointsFilter类附加的功能函数:
根据KeyPoint存储的response响应值进行排序,retainBest()函数获取最佳的npoints个点。
runByImageBorder()移除keypoints处于图像边缘的点,这里图像边缘指的是图像边界信息。将keypoint处于borderSize范围的点进行删除。
KeyPoint检测到的size直径可能大小不一,设置[minSize maxSize]对其进行限制,超过范围的进行删除。好处在于大尺度下特征点在进行尺度归一化情况下会偏差较大(插值),同时尺度变化太大keypoints进行匹配难度较大。删除这些点集会提升提取keypoints点集的正确点占比率。
根据输入mask矩阵来进行移除像素偏移超过0.5f的keypoints,主要应用在亚像素插值判断上面。
KeyPointsFilter::removeDuplicate()函数主要移除keypoints距离相聚较近的情况下,一般尺度空间检测的keypoints在最后进行尺度归一化的时候,会出现大量的重复点(可能会有轻微坐标偏移)。这种情况下需要对位置很近的keypoints进行筛选,例如可以对其response进行排序来筛选等等。
小结
今天简单总结一下keypoint.cpp下面的基础功能函数,其中许多函数貌似平常用到很少:比如runByImageSize()、retainBest()等等。其实,这些函数在SIFT、ORB源码下面都会有部分涉及。当然,平时我们使用最多的还是KeyPoint这个数据结构用来存储提取的特征信息。自己梳理一遍,清晰了不少!
如有错误,还请指正,谢谢!
参考
OpenCV源码中Keypoint.cpp