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

ORB-SLAM2源码学习:ORBextractor.cc:ComputePyramid构建图像金字塔①

前言

这部分函数是根据输入的图像矩阵构建图像金字塔,这是 ORB(Oriented FAST and Rotated BRIEF)特征提取算法的一部分。在ORB算法中,通过对图像进行多尺度处理,可以在不同尺度上检测和描述特征,从而使得算法具有尺度不变性。

1.函数声明

void ORBextractor::ComputePyramid(cv::Mat image)//输入图像cv::Mat image。

2.函数定义

2.1对图像进行一些预处理

思路: 

1.获取本层的缩放因子的倒数,构造当前图像像素的尺寸大小SZ

2.根据SZ构造全尺寸图像的尺寸大小(相当于对SZ进行对称加边)

3.构造临时矩阵储存全尺寸图像,masktemp暂时不用理会。

4.最后一步相当于在wholeSize中取出矩形域SZ放入当前层的金字塔图像中。

说明:wholeSize定义了一个足够大的临时图像空间,以便在后续调用 copyMakeBorder 时能在图像的每一边增加适当的边缘填充,从而确保后续处理的稳定性。

for (int level = 0; level < nlevels; ++level)//遍历每一层。
    {
        float scale = mvInvScaleFactor[level];//获取本层的缩放因子的倒数,这里应该是0-1之间的小数。
        // 计算当前层的图像像素大小。
        Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
        // 为了保证图像处理操作在靠近边缘时的稳定性和准确性,避免由于边界像素缺失带来的各种问题而进行边缘补偿操作。
        Size wholeSize(sz.width + EDGE_THRESHOLD*2, sz.height + EDGE_THRESHOLD*2);
        Mat temp(wholeSize, image.type()), masktemp;
        // 第一个和第二个参数是矩形的左上角的坐标,均为 EDGE_THRESHOLD。这意味着提取的区域将向右和向下偏移 EDGE_THRESHOLD 的值。
        // 第三个和第四个参数分别是矩形的宽度和高度,均为 sz.width 和 sz.height,这表示提取的区域大小与缩小后的图像尺寸相同。
        mvImagePyramid[level] = temp(Rect(EDGE_THRESHOLD, EDGE_THRESHOLD, sz.width, sz.height));
....
    }
2.2 图像之间的关系

3.缩放图像并进行边缘填充

     // Compute the resized image 计算缩放后的图像。
        // 在图像金字塔的不同层级上计算和生成缩小版本的图像。
        if( level != 0 )//不包括第0层。
        {
            //将下层图像根据当前层SZ缩放到当前层
            resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);

            // copyMakeBorder 函数被用来为每一层的图像添加边框。
            // 即使在后续的处理(如滤波或特征检测)过程中,金字塔图像的边缘部分也会有足够的邻域信息,从而避免边缘效应带来的计算误差。
            copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                           BORDER_REFLECT_101+BORDER_ISOLATED);
    		//BORDER_ISOLATED 选项确保边缘区域不会受到外部环境(即边界外的像素)的影响。
    		// 即使在图像的边缘添加了边框,边缘的计算也只会依赖于图像的有效区域,不会被外部像素干扰。
        }
        else
        {
            copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                           BORDER_REFLECT_101);
        }

 注:我认为这里存在一些问题,它最后的图像金字塔容器mvImagePyramid并没有保存到图像边界扩充的结果,扩充时保留在了temp中,应该最后要传给mvImagePyramid。

mvImagePyramid[level] = temp;
3.1图像扩充边界的方式


http://www.kler.cn/a/382615.html

相关文章:

  • MySQL基础-单表查询
  • 在 Spring Boot 中使用分布式事务时,如何处理不同数据源之间的事务一致性问题?
  • docker+nacos
  • CST汽车天线仿真(双向混合求解)
  • 手边酒店多商户版V2源码独立部署_博纳软云
  • Multi Agents协作机制设计及实践
  • 【C/C++】模拟实现strcat
  • Pr 视频过渡:沉浸式视频 - VR 光线
  • git 提交管理
  • ArcGIS006:ArcMap常用操作151-200例动图演示
  • Go构造函数的实现
  • 如何设置内网IP的端口映射到公网
  • Java+Swing可视化图像处理软件
  • 720VR全景的未来发展趋势与行业前景
  • C++面向对象高级开发B
  • ansible进阶功能
  • 鸿蒙应用App测试-通用测试
  • 什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
  • 怎麼解決IP地址衝突的問題?
  • 结对编程 --- 软件工程
  • Java学习路线:Maven(二)scope、optional和exclusions
  • Late Chunking×Milvus:如何提高RAG准确率
  • C++ 新手指南:如何使用 set 和 unordered_set
  • 2024年10月个人工作生活总结
  • 【网络】传输层协议TCP(下)
  • Android笔记(三十五):用责任链模式封装一个App首页Dialog管理工具