ORB-SLAM2学习笔记:ExtractorNode::DivideNode和ORBextractor::DistributeOctTree函数详解

发布于:2025-05-29 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、ExtractorNode::DivideNode

void ExtractorNode::DivideNode(ExtractorNode &n1, ExtractorNode &n2, ExtractorNode &n3, ExtractorNode &n4)
{
   
    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.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);
    n1.vKeys.reserve(vKeys.size());

    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.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.UL = n3.UR;
    n4.UR = n2.BR;
    n4.BL = n3.BR;
    n4.BR = BR;
    n4.vKeys.reserve(vKeys.size());

    //Associate points to childs
    for(size_t i=0;i<vKeys.size();i++)
    {
   
        const cv::KeyPoint &kp = vKeys[i];
        if(kp.pt.x<n1.UR.x)
        {
   
            if(kp.pt.y<n1.BR.y)
                n1.vKeys.push_back(kp);
            else
                n3.vKeys.push_back(kp);
        }
        else if(kp.pt.y<n1.BR.y)
            n2.vKeys.push_back(kp);
        else
            n4.vKeys.push_back(kp);
    }

    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;

}

以下是 ExtractorNode::DivideNode 函数的详细解析,结合其在特征提取中的应用场景:


功能概述

该函数用于将当前节点(父节点)分割为四个子节点(n1-n4),并将父节点中的特征点(vKeys)按坐标分配到对应的子节点中,是ORB特征均匀化分布的核心操作,常用于四叉树分割策略中。


输入与输出

  • 输入:四个子节点的引用 n1, n2, n3, 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);
  • 功能:计算父节点宽度(UR.x - UL.x)和高度(BR.y - UL.y)的一半,使用 ceil 确保分割后子节点覆盖整个父区域。
  • 示例:若父节点宽度为奇数(如5像素),halfX=3,保证子节点无遗漏。
2. 定义子节点坐标
// n1(左上子节点)
n1.UL = UL;  // 左上角继承父节点
n1.UR = cv::Point2i(UL.x + halfX, UL.y);  

网站公告

今日签到

点亮在社区的每一天
去签到