• ORB-SLAM2 ---- Frame::AssignFeaturesToGrid函数


    1.这个函数做什么的

            将提取的ORB特征点分配到图像网格中方便特征点匹配的时候用到

    2.Frame::AssignFeaturesToGrid函数代码解析

    1. void Frame::AssignFeaturesToGrid()
    2. {
    3. // Step 1 给存储特征点的网格数组 Frame::mGrid 预分配空间
    4. // ? 这里0.5 是为什么?节省空间?
    5. // FRAME_GRID_COLS = 64,FRAME_GRID_ROWS=48
    6. int nReserve = 0.5f*N/(FRAME_GRID_COLS*FRAME_GRID_ROWS);
    7. //开始对mGrid这个二维数组中的每一个vector元素遍历并预分配空间
    8. for(unsigned int i=0; i
    9. for (unsigned int j=0; j
    10. mGrid[i][j].reserve(nReserve);
    11. // Step 2 遍历每个特征点,将每个特征点在mvKeysUn中的索引值放到对应的网格mGrid中
    12. for(int i=0;i
    13. {
    14. //从类的成员变量中获取已经去畸变后的特征点
    15. const cv::KeyPoint &kp = mvKeysUn[i];
    16. //存储某个特征点所在网格的网格坐标,nGridPosX范围:[0,FRAME_GRID_COLS], nGridPosY范围:[0,FRAME_GRID_ROWS]
    17. int nGridPosX, nGridPosY;
    18. // 计算某个特征点所在网格的网格坐标,如果找到特征点所在的网格坐标,记录在nGridPosX,nGridPosY里,返回true,没找到返回false
    19. if(PosInGrid(kp,nGridPosX,nGridPosY))
    20. //如果找到特征点所在网格坐标,将这个特征点的索引添加到对应网格的数组mGrid中
    21. mGrid[nGridPosX][nGridPosY].push_back(i);
    22. }
    23. }

             我们先来看nReserve 的含义,FRAME_GRID_COLS*FRAME_GRID_ROWS是网格数目(64*48的网格),用特征点总数N/FRAME_GRID_COLS*FRAME_GRID_ROWS,含义是每个网格中平均含有的特征点数量,0.5*它为了节省空间。

            然后对遍历每个网格分配nReserve 个特征点。

            再遍历每个特征点,将每个特征点在mvKeysUn中的索引值(去畸变后的特征点)放到对应的网格mGrid中。

    1. ///这个向量中存储的是每个图像网格内特征点的id(左图)
    2. std::vectorsize_t> mGrid[FRAME_GRID_COLS][FRAME_GRID_ROWS];

    3. Frame::PosInGrid代码解析

    1. /**
    2. * @brief 计算某个特征点所在网格的网格坐标,如果找到特征点所在的网格坐标,记录在nGridPosX,nGridPosY里,返回true,没找到返回false
    3. *
    4. * @param[in] kp 给定的特征点
    5. * @param[in & out] posX 特征点所在网格坐标的横坐标
    6. * @param[in & out] posY 特征点所在网格坐标的纵坐标
    7. * @return true 如果找到特征点所在的网格坐标,返回true
    8. * @return false 没找到返回false
    9. */
    10. bool Frame::PosInGrid(const cv::KeyPoint &kp, int &posX, int &posY)
    11. {
    12. // 计算特征点x,y坐标落在哪个网格内,网格坐标为posX,posY
    13. // mfGridElementWidthInv=(FRAME_GRID_COLS)/(mnMaxX-mnMinX);
    14. // mfGridElementHeightInv=(FRAME_GRID_ROWS)/(mnMaxY-mnMinY);
    15. posX = round((kp.pt.x-mnMinX)*mfGridElementWidthInv);
    16. posY = round((kp.pt.y-mnMinY)*mfGridElementHeightInv);
    17. //Keypoint's coordinates are undistorted, which could cause to go out of the image
    18. // 因为特征点进行了去畸变,而且前面计算是round取整,所以有可能得到的点落在图像网格坐标外面
    19. // 如果网格坐标posX,posY超出了[0,FRAME_GRID_COLS] 和[0,FRAME_GRID_ROWS],表示该特征点没有对应网格坐标,返回false
    20. if(posX<0 || posX>=FRAME_GRID_COLS || posY<0 || posY>=FRAME_GRID_ROWS)
    21. return false;
    22. // 计算成功返回true
    23. return true;
    24. }

            我们将mvKeysUn中的特征点一个个在此函数处理,最终将各个去畸变后的特征点的索引值存放在grid栅格中。

            mfGridElementWidthInv=(FRAME_GRID_COLS)/(mnMaxX-mnMinX),这个变量的意义是栅格的列数/图像的宽度,举个例子,比如要把10米分成5个栅格,那么5/10=0.5,用这个数去乘以当前图像的位置就可以得到在哪个栅格中,比如有个物体在7m处,7*0.5=3.5,那么这个物体就在第三个栅格中。

            因此,posX、posY是该特征点所在的栅格位置,然后判断栅格位置是否合法,若合法,将特征点的索引赋值给grid栅格,最终应该是这样的。

     

  • 相关阅读:
    Java之线程的详细解析一
    GJB 5000B二级-QA质量保证
    python打包exe
    如何使用 MiniGPT-v2
    WSN final fighting 12.05
    springMAC的原理以及概述
    【Kubernetes 系列】Kubernetes 创建K8s集群项目
    【ECharts】环形图、饼状图
    港联证券:上市公司三季报反映经济回暖向好态势
    uniapp 获取cookie与携带cookie请求数据
  • 原文地址:https://blog.csdn.net/qq_41694024/article/details/126316590