文章目录
- 一、函数作用
- 二、源码及注释
- 三、函数讲解
-
- 1.什么是仿函数
- 2. 判断图像是否为空,不空则将其转换为灰度图像
- 3. 调用函数[ComputePyramid](https://blog.csdn.net/uzi_ccc/article/details/142750378?spm=1001.2014.3001.5501)预先构建函数金字塔
- 4. 调用函数[ComputeKeyPointsOctTree](https://blog.csdn.net/uzi_ccc/article/details/142768805?spm=1001.2014.3001.5501),使用八叉树 (OctTree) 方法计算每一层的特征点
- 5. 统计每层特征点数量,并准备一些容器,在后续处理特征点时使用
- 6. 处理特征点
- 四、总结
一、函数作用
此函数为特征点提取中的主函数,也是最重要的一个函数,这是一个仿函数,会在下文中讲到。之所以说本函数是主函数,因为他直接或间接的调用了除构造函数外的所有函数,它完整的实现了特征提取功能(金字塔构建、给每层金字塔分配特征点数、给金字塔每层图像扩充图像边界,提取/分配/筛选特征点,计算特征点的方向信息和描述子等)
二、源码及注释
void ORBextractor::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,
OutputArray _descriptors)
{
// 判断图像是否为空
if(_image.empty())
return;
// 将输入的 _image 转换为 Mat 类型,并确保它是灰度图像 (CV_8UC1)
Mat image = _image.getMat();
// 括号内的为真则继续进行,为假则输出报错信息
assert(image.type() == CV_8UC1 );
// Pre-compute the scale pyramid
// 预先计算图像的金字塔 (图像金字塔用于多尺度特征检测)
ComputePyramid(image);
// 用于存储所有金字塔层的特征点
vector < vector<KeyPoint> > allKeypoints;
// 使用八叉树 (OctTree) 方法计算每一层的特征点
ComputeKeyPointsOctTree(allKeypoints);
//ComputeKeyPointsOld(allKeypoints);
// 初始化描述子矩阵
Mat descriptors;
// 统计所有金字塔层中的关特征点总数
int nkeypoints = 0;
for (int level = 0; level < nlevels; ++level)
nkeypoints += (int)allKeypoints[level].size();
// 如果没有找到特征点,释放描述子矩阵并返回
if( nkeypoints == 0 )
_descriptors.release();
else
{
// 为描述子矩阵分配空间,描述子的大小为 nkeypoints × 32,类型为 CV_8U
_descriptors.create(nkeypoints, 32, CV_8U);
descriptors = _descriptors.getMat();
}
// 清空并准备特征点容器
_keypoints.clear();
_keypoints.reserve(nkeypoints);
// 用于描述子的偏移量,用于遍历金字塔层时对每层的关键点处理
int offset = 0;
// 遍历每一层的金字塔
for (int level = 0; level < nlevels;