当前位置: 首页 > news >正文

ORB-SLAM2源码学习:ORBextractor.cc:ExtractorNode::DivideNode节点一分为四④

前言

该函数将当前节点所代表的图像区域划分为四个子区域,同时将该区域内的特征点分配到相应的子区域节点中。

1.函数的声明

/*将提取器节点分成4个子节点,同时也完成图像区域的划分、特征点归属的划分,以及相关标志位的置位n1  提取器节点1:左上n2  提取器节点1:右上n3  提取器节点1:左下n4  提取器节点1:右下*/
void ExtractorNode::DivideNode(ExtractorNode &n1, //提取器节点1:左上ExtractorNode &n2, //提取器节点1:右上ExtractorNode &n3, //提取器节点1:左下ExtractorNode &n4) //提取器节点1:右下
{....
}

2.函数定义

1.划分子节点的区域
//得到当前提取器节点所在图像区域的一半长宽,向上取整。const int halfX = ceil(static_cast<float>(UR.x-UL.x)/2);const int halfY = ceil(static_cast<float>(BR.y-UL.y)/2);//Define boundaries of childs//划分四个子节点的边界。//n1 存储左上区域的边界n1.UL = UL;n1.UR = cv::Point2i(UL.x+halfX,UL.y);n1.BL = cv::Point2i(UL.x,UL.y+halfY);n1.BR = cv::Point2i(UL.x+halfX,UL.y+halfY);//用来存储在该节点对应的图像网格中提取出来的特征点的vectorn1.vKeys.reserve(vKeys.size());//n2 存储右上区域的边界n2.UL = n1.UR;n2.UR = UR;n2.BL = n1.BR;n2.BR = cv::Point2i(UR.x,UL.y+halfY);n2.vKeys.reserve(vKeys.size());//n3 存储左下区域的边界n3.UL = n1.BL;n3.UR = n1.BR;n3.BL = BL;n3.BR = cv::Point2i(n1.BR.x,BL.y);n3.vKeys.reserve(vKeys.size());//n4 存储右下区域的边界n4.UL = n3.UR;n4.UR = n2.BR;n4.BL = n3.BR;n4.BR = BR;n4.vKeys.reserve(vKeys.size());
2.遍历节点中的特征点数,划分到对应节点区域中。

注:这里特征点坐标和节点边界坐标对比不在同一个坐标系下

//Associate points to childs//遍历当前提取器节点的vkeys中存储的特征点for(size_t i=0;i<vKeys.size();i++){//获取这个特征点对象const cv::KeyPoint &kp = vKeys[i];//判断这个特征点在当前特征点提取器节点图像的哪个区域//然后就将这个特征点追加到那个特征点提取器节点的vkeys中//这里也是直接进行比较的,但是特征点的坐标是在“半径扩充图像”坐标系下的,而节点区域的坐标则是在“边缘扩充图像”坐标系下的if(kp.pt.x<n1.UR.x){if(kp.pt.y<n1.BR.y)n1.vKeys.push_back(kp);elsen3.vKeys.push_back(kp);}else if(kp.pt.y<n1.BR.y)n2.vKeys.push_back(kp);elsen4.vKeys.push_back(kp);}//遍历当前提取器节点的vkeys中存储的特征点
3.判断节点区域是否能在分裂
 //判断每个子特征点提取器节点所在的图像中特征点的数目(就是分配给子节点的特征点数目),然后做标记//这里判断是否数目等于1的目的是确定这个节点还能不能再向下进行分裂if(n1.vKeys.size()==1)n1.bNoMore = true;if(n2.vKeys.size()==1)n2.bNoMore = true;if(n3.vKeys.size()==1)n3.bNoMore = true;if(n4.vKeys.size()==1)n4.bNoMore = true;

3.完整代码

/*将提取器节点分成4个子节点,同时也完成图像区域的划分、特征点归属的划分,以及相关标志位的置位n1  提取器节点1:左上n2  提取器节点1:右上n3  提取器节点1:左下n4  提取器节点1:右下*/
void ExtractorNode::DivideNode(ExtractorNode &n1, //提取器节点1:左上ExtractorNode &n2, //提取器节点1:右上ExtractorNode &n3, //提取器节点1:左下ExtractorNode &n4) //提取器节点1:右下
{//得到当前提取器节点所在图像区域的一半长宽,向上取整。const int halfX = ceil(static_cast<float>(UR.x-UL.x)/2);const int halfY = ceil(static_cast<float>(BR.y-UL.y)/2);//Define boundaries of childs//划分四个子节点的边界。//n1 存储左上区域的边界n1.UL = UL;n1.UR = cv::Point2i(UL.x+halfX,UL.y);n1.BL = cv::Point2i(UL.x,UL.y+halfY);n1.BR = cv::Point2i(UL.x+halfX,UL.y+halfY);//用来存储在该节点对应的图像网格中提取出来的特征点的vectorn1.vKeys.reserve(vKeys.size());//n2 存储右上区域的边界n2.UL = n1.UR;n2.UR = UR;n2.BL = n1.BR;n2.BR = cv::Point2i(UR.x,UL.y+halfY);n2.vKeys.reserve(vKeys.size());//n3 存储左下区域的边界n3.UL = n1.BL;n3.UR = n1.BR;n3.BL = BL;n3.BR = cv::Point2i(n1.BR.x,BL.y);n3.vKeys.reserve(vKeys.size());//n4 存储右下区域的边界n4.UL = n3.UR;n4.UR = n2.BR;n4.BL = n3.BR;n4.BR = BR;n4.vKeys.reserve(vKeys.size());//Associate points to childs//遍历当前提取器节点的vkeys中存储的特征点for(size_t i=0;i<vKeys.size();i++){//获取这个特征点对象const cv::KeyPoint &kp = vKeys[i];//判断这个特征点在当前特征点提取器节点图像的哪个区域//然后就将这个特征点追加到那个特征点提取器节点的vkeys中//这里也是直接进行比较的,但是特征点的坐标是在“半径扩充图像”坐标系下的,而节点区域的坐标则是在“边缘扩充图像”坐标系下的if(kp.pt.x<n1.UR.x){if(kp.pt.y<n1.BR.y)n1.vKeys.push_back(kp);elsen3.vKeys.push_back(kp);}else if(kp.pt.y<n1.BR.y)n2.vKeys.push_back(kp);elsen4.vKeys.push_back(kp);}//遍历当前提取器节点的vkeys中存储的特征点//判断每个子特征点提取器节点所在的图像中特征点的数目(就是分配给子节点的特征点数目),然后做标记//这里判断是否数目等于1的目的是确定这个节点还能不能再向下进行分裂if(n1.vKeys.size()==1)n1.bNoMore = true;if(n2.vKeys.size()==1)n2.bNoMore = true;if(n3.vKeys.size()==1)n3.bNoMore = true;if(n4.vKeys.size()==1)n4.bNoMore = true;
}

结束语

以上就是我学习到的内容,如果对您有帮助请多多支持我,如果哪里有问题欢迎大家在评论区积极讨论,我看到会及时回复。


http://www.mrgr.cn/news/69028.html

相关文章:

  • vue2项目中在线预览csv文件
  • Django 的 ModelViewSet 中的 get_queryset 方法自定义查询集
  • 基于SSM的“汽车销售分析与管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 前端网络性能优化问题
  • el-tree 父节点隐藏
  • 【Linux】进程的概念
  • 架构师备考-概念背诵(软件工程)
  • 构建基于协同过滤与深度学习的个性化推荐系统:电商平台实战(附实现代码~)
  • 通过pin_memory 优化 PyTorch 数据加载和传输:工作原理、使用场景与性能分析
  • springboot使用aop防御用户重复请求
  • Java 线程池详解
  • Stream API 中的 forEach
  • Linux内核USB2.0驱动框架分析--USB设备枚举过程
  • MybatisPlus入门(十)MybatisPlus-逻辑删除和多记录操作
  • 使用HTML、CSS和JavaScript创建动态雪人和雪花效果
  • JVM中对象在堆中的生命周期?
  • 会话技术-JWT令牌和filter
  • 如何快速关闭Linux上的服务脚本
  • 共享经济下的SpringBoot汽车管理创新
  • 电脑屏幕录像软件哪个好?这五款屏幕录像工具实打实推荐,记录精彩的瞬间!
  • 高效建造,全新体验:气膜网球馆的革新之选—轻空间
  • SpringBoot技术下的共享汽车运营平台
  • Result和ResultCode类,用于封装后端返回给前端的数据
  • 基于Python的自然语言处理系列(57):使用最佳表示向量法实现整本书的高效摘要
  • 06 P2437 蜜蜂路线
  • HTTP 和 HTTPS 的区别 - 2024最新版前端秋招面试短期突击面试题【100道】