GCNv2_SLAM结果复现

9 篇文章 1 订阅
2 篇文章 0 订阅
该博客介绍了如何在ORB_SLAM3基础上集成并修改GCNv2_SLAM,以解决相机转动过快导致的丢失问题。作者详细描述了编译和代码修改过程,包括对GCNextractor.h的改动和CMakeLists.txt的调整。通过测试,验证了修改后的GCNv2_SLAM在特征点提取和匹配上的可行性,并展示了匹配结果图像。
摘要由CSDN通过智能技术生成

很多人对GCNv2比较感兴趣,但是因为这是比较久之前做的测试,具体细节已经遗忘。。。问题无法一一解答,鉴于目前也在orbslam3基础上改东西,最近会再测试一下

=========================================================================

文章写于2021.9.29

由于在实时跑ORB_SLAM3的时候,相机转动过快会LOST,因此采用其他特征点提取方法进行尝试,首先是GCNv2_SLAM。

系统:Ubuntu 18.04       

g++:5.x

CUDA:10.2

参考文章:Ubuntu系统pangolin与libtorch所引发的连接错误_feiyang_luo的博客-CSDN博客

GCNv2编译过程中出现的问题_CAFE-BABE的博客-CSDN博客

Pytorch1.4下运行 GCNv2slam 需要修改的地方_马马虎虎半吊子的博客-CSDN博客 (主要参考)

1、首先下载:https://github.com/jiexiong2016/GCNv2_SLAM https://github.com/jiexiong2016/GCNv2_SLAM

(因为版本问题,github提供的pytorch 源码编译方法在编译的时候会报错(ubuntu版本过高或者g++版本低))

2、官网下载libtorch,和CUDA适配,X11 ABI的版本的(pre-X11版本 后续会报错),下载后解压即可,无需构建  (当时下载的1.9.1版本)

3、代码改动:

GCNextractor.h :

//99行
//原
std::shared_ptr<torch::jit::script::Module> module;
//改为
torch::jit::script::Module module;
//270行
//原
auto output = module->forward(inputs).toTuple();
//改为
auto output = module.forward(inputs).toTuple();

CMakeLists.txt

//更改c++编译标准 
set(CMAKE_CXX_STANDARD 14)


//在if( TORCH_PATH ) 前加     给一个刚刚下载的路径
set(TORCH_PATH "/home/***/libtorch/share/cmake/Torch")

//最后项目链接  从11改成14
set_property(TARGET rgbd_gcn PROPERTY CXX_STANDARD 14)

4、数据改动

双击打开gcn2_320x240.pt (其他pt文件同理)(无需解压)/gcn/code/'下找到 ‘gcn.py’

#原   这是因为1.3以前默认true   1.3以后默认false
_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0))
#改为
_32 = torch.squeeze(torch.grid_sampler(input, grid, 0, 0, True))


#原
_14 = torch.unsqueeze(torch.index(det, [_12, _13]), 1)
#改为
det_flatten = torch.flatten(det, start_dim=0, end_dim=-1)  
_12_13 = _12*320+_13
_14 = torch.unsqueeze(torch.index_select(det_flatten, 0, _12_13),1)

我猜测 _14是根据待选特征点的横纵坐标_12 _13,在分数矩阵det中提取待选特征点的分数。 index在这个地方因为版本更迭导致作用失效(我就没找到index的说明文档在哪里。。)。所以直接将dat展平,利用index_select提取0维度上的点的值。

5、编译GCNv2_SLAM

6、执行程序

GCN_PATH=/home/***/GCNv2_SLAM-master/GCN2/gcn2_320x240.pt ./rgbd_gcn /home/***/GCNv2_SLAM-master/Vocabulary/voc/ORBvoc.bin /home/***/GCNv2_SLAM-master/GCN2/TUM3.yaml /home/***/datasets/tum/rgbd_dataset_freiburg2_xyz /home/***/datasets/tum/rgbd_dataset_freiburg2_xyz/associate.txt

 

=========================================================================

然后我把这部分代码摘了出来,想要单独验证下其性能,另外评估一下我模型地方改的对不对   (删掉了GCNextractor的namespace)

代码解释:读取了euroc的图片,参数从ORBSLAM3文件中找的,直接填了进去。

检测器方面:由于 在双目初始化过程中是针对金字塔一层层采集的,GCN是没有金字塔的..关键帧track是比对的BOW,BOW是由特征点生成的,所以直接比对特征点就好了。所以这里直接用的opencv的DMach(因为给的双目图像, 所以参数给的比较苛刻。)。

test1.cpp

#include "GCNextractor.h"
#include <vector>
#include <opencv2/opencv.hpp>
void Frame(const cv::Mat &imLeft, const cv::Mat &imRight)
{
    GCNextractor* mpleftGCNextractor = new GCNextractor(1000,1.2,8,20,7);
    GCNextractor* mprightGCNextractor = new GCNextractor(1000,1.2,8,20,7);

    std::vector<cv::KeyPoint> mvLeftKeys,mvRightKeys;
    cv::Mat mleftDescriptors,mRightDescriptors;
    (*mpleftGCNextractor)(imLeft,cv::Mat(),mvLeftKeys,mleftDescriptors);
    (*mprightGCNextractor)(imRight,cv::Mat(),mvRightKeys,mRightDescriptors);

    if(mvLeftKeys.empty()||mvRightKeys.empty())
        std::cout<<"特征点提取出现问题"<<std::endl;

    std::cout<<"imtrack"<<std::endl;

	std::vector<cv::DMatch> matches;
	cv::BFMatcher bfmatcher(cv::NORM_HAMMING);
	bfmatcher.match(mleftDescriptors, mRightDescriptors, matches);
 
	double min_dist = 1000, max_dist = 0;
	for (int i = 0; i < mleftDescriptors.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist < min_dist) min_dist = dist;
		if (dist > max_dist) max_dist = dist;
	}

	std::vector<cv::DMatch> good_matches;

	for (int i = 0; i < mleftDescriptors.rows; i++)
	{
		if (matches[i].distance <= std::max(1.2 * min_dist, 30.0))
			good_matches.push_back(matches[i]);
	}
 
	cv::Mat img_match,img_match2;
	drawMatches(imLeft, mvLeftKeys, imRight, mvRightKeys, good_matches, img_match);
    cv::namedWindow("img_match", CV_WINDOW_NORMAL);
        cv::namedWindow("img_match2", CV_WINDOW_NORMAL);

    imshow("img_match",img_match);

    cv::hconcat(imLeft,imRight,img_match2);
    cv::cvtColor(img_match2,img_match2,CV_GRAY2RGB);

    std::cout << "1"<<std::endl;
    for(int i = 0; i < mvLeftKeys.size(); i++)
    {
        cv::circle(img_match2,cv::Point2f(mvLeftKeys[i].pt.x,mvLeftKeys[i].pt.y),2,cv::Scalar(255,0,0),1);
    }
    for(int i = 0; i < mvRightKeys.size(); i++)
    {
        cv::circle(img_match2,cv::Point2f(mvRightKeys[i].pt.x + imLeft.cols,mvRightKeys[i].pt.y),2,cv::Scalar(255,0,0),1);

    }

    for(int i = 0; i < good_matches.size(); i++)
    {
        cv::circle(img_match2,cv::Point2f(mvLeftKeys[good_matches[i].queryIdx].pt.x,mvLeftKeys[good_matches[i].queryIdx].pt.y),2,cv::Scalar(0,255,0),1);
    }

    for(int i = 0; i < good_matches.size(); i++)
    {
        cv::circle(img_match2,cv::Point2f(mvRightKeys[good_matches[i].trainIdx].pt.x + imLeft.cols,mvRightKeys[good_matches[i].trainIdx].pt.y),2,cv::Scalar(0,255,0),1);
    }

    imshow("img_match2",img_match2);
    // cv::waitKey(0);
}


int main(int argc,char** argv)
{        
    cv::Mat imleft = cv::imread("/home/***/euroc/MH_01/mav0/cam0/data/1403636579813555456.png");
    cv::Mat imright = cv::imread("/home/***/euroc/MH_01/mav0/cam1/data/1403636579813555456.png");
    if(imleft.channels()==3)
    {
        cvtColor(imleft,imleft,CV_RGB2GRAY);
    }
    if(imright.channels()==3)
    {
        cvtColor(imright,imright,CV_RGB2GRAY);
    }
    cv::Mat leftmap1,leftmap2,rightmap1,rightmap2;
    cv::Mat leftintrinsics = (cv::Mat_<double>(3,3) << 458.654,0., 367.215,0., 457.296, 248.375,0.,0.,1);
    cv::Mat leftdistortion = (cv::Mat_<double>(4,1) << -0.28340811, 0.07395907, 0.00019359, 1.76187114e-05);
    cv::Mat rightintrinsics = (cv::Mat_<double>(3,3) << 457.587,0., 379.999,0.,456.134, 255.238,0.,0.,1);
    cv::Mat rightdistortion = (cv::Mat_<double>(4,1) << -0.28368365,  0.07451284, -0.00010473, -3.55590700e-05);
    cv::Mat leftR = (cv::Mat_<double>(3,3) << 0.999966347530033, -0.001422739138722922, 0.008079580483432283, 0.001365741834644127, 0.9999741760894847, 0.007055629199258132, -0.008089410156878961, -0.007044357138835809, 0.9999424675829176);
    cv::Mat rightR = (cv::Mat_<double>(3,3) << 0.9999633526194376, -0.003625811871560086, 0.007755443660172947, 0.003680398547259526, 0.9999684752771629, -0.007035845251224894, -0.007729688520722713, 0.007064130529506649, 0.999945173484644);
    cv::Size imageSize(752, 480);
    cv::Size unimageSize(320, 240);
    cv::Mat newintrinsics =  (cv::Mat_<double>(3,3) << 194.7179,0., 159.5,0., 228.0670, 119.5 ,0.,0.,1); // vfov 与 hfov 保持不变,按左图
    initUndistortRectifyMap(leftintrinsics,leftdistortion,leftR,newintrinsics,imageSize,CV_32FC1,leftmap1,leftmap2);
    cv::Mat unimleft,unimright;
    cv::remap(imleft, unimleft, leftmap1, leftmap2, 1, 0);
    unimleft = unimleft(cv::Rect(0, 0, 320,240)).clone();
    initUndistortRectifyMap(rightintrinsics,rightdistortion,rightR,newintrinsics,imageSize,CV_32FC1,rightmap1,rightmap2);
    cv::remap(imright, unimright, rightmap1, rightmap2, 1, 0);
    unimright = unimright(cv::Rect(0, 0, 320,240)).clone();
    cv::imshow("unimleft",unimleft);
    cv::imshow("unimright",unimright);

    Frame(unimleft, unimright);

    cv::waitKey(0);

    return 0;
}

img_match

 img_match2

 从图上看还是可用的,接下来将其运用到双目匹配中。

评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值