《一起做RGB-D SLAM(4)》学习内容与遇到的问题

**《一起做RGB-D SLAM(4)》学习内容与遇到的问题 **

一.代码理解
1.slamBase.h中的读取参数文件类
我把代码详细注释了,就能看大概理解这个类的工作原理了。

class ParameterReader
{
    
    
public:
    ParameterReader( string filename="./parameters.txt" )//构造函数
    {
    
    
        ifstream fin( filename.c_str() );//c_str()把string类型转换成char*类型
        if (!fin)
        {
    
    
            cerr<<"parameter file does not exist."<<endl;
            return;
        }
        while(!fin.eof())//fin.eof()读到文件末尾,则返回true
        {
    
    
            string str;
            getline( fin, str );//从fin中提取字符到str中,遇到换行或文件结束符结束,即一行一行读取
            if (str[0] == '#')
            {
    
    
                // 以‘#’开头的是注释
                continue;
            }

            int pos = str.find("=");//从第0个字符查起,若找到=,则返回找到=的位置,若失败则返回npos,即-1
            if (pos == -1)
                continue;
            //下面两行代码意思是,当找到=,则将等号左边的关键词给key,等号右边的值给value
            string key = str.substr( 0, pos );//从0开始复制pos长度的str到key中
            string value = str.substr( pos+1, str.length() );
            data[key] = value; //键值对

            if ( !fin.good() )//fin.good()判断文件是否打开,打开返回true
                break;
        }
    }
    string getData( string key )
    {
    
    
        map<string, string>::iterator iter = data.find(key);
        if (iter == data.end())
        {
    
    
            cerr<<"Parameter name "<<key<<" not found!"<<endl;
            return string("NOT_FOUND");
        }
        return iter->second;
    }
public:
    map<string, string> data; //map是一个接口,代表一个key-value键值对,其数据类型都为string
};

2.joinPointCloud.cpp中

// 将旋转向量转化为旋转矩阵
    cv::Mat R;
    cv::Rodrigues( result.rvec, R ); 
    Eigen::Matrix3d r; //3×3矩阵
    cv::cv2eigen(R, r); //OPENCV中矩阵用cv::Mat表示,但在pcl中用Eigen::Matrix表示
  
    // 将平移向量和旋转矩阵转换成变换矩阵
    Eigen::Isometry3d T = Eigen::Isometry3d::Identity(); //T变换矩阵
    Eigen::AngleAxisd angle(r); //旋转向量(3x1)
    T = angle;
    //据说这里写错了,tvec行列要互换
    T(0,3) = result.tvec.at<double>(0,0); 
    T(1,3) = result.tvec.at<double>(0,1); 
    T(2,3) = result.tvec.at<double>(0,2);

二.遇到的问题
1.找不到Eigen库
一般Eigen库都是装到/usr/include中,但是由于Eigen库的特殊结构,需要把Eigen3文件夹里个Eigen和unsupported链接到/usr/include下。

cd /usr/include 
sudo ln -sf eigen3/Eigen Eigen
sudo ln -sf eigen3/unsupported unsupported

2.bin/joinPointCloud
extracting features
solving pnp
OpenCV Error: Unsupported format or combination of formats (type=0
) in buildIndex_, file /home/pepper/Desktop/opencv-2.4.9/modules/flann/src/miniflann.cpp, line 315
terminate called after throwing an instance of ‘cv::Exception’
what(): /home/pepper/Desktop/opencv-2.4.9/modules/flann/src/miniflann.cpp:315: error: (-210) type=0
in function buildIndex_

Aborted (core dumped)
解决:这个是estimateMotion函数中cv::FlannBasedMatcher matcher;出错,改成 cv::BFMatcher matcher;
三.最后的结果
在这里插入图片描述不知道为什么是这个样子???
%%%更新%%%
找到显示上图点云的原因了——码错代码了!`
在slamBase.cpp中,计算点的空间坐标p.y写错

 // 计算这个点的空间坐标
            p.z = double(d) / camera.scale;
            p.x = (n - camera.cx) * p.z / camera.fx;
            p.y = (n - camera.cy) * p.z / camera.fy;

最后,得到正确的图了。如果点云图是上下颠倒的,在p.y上加个负号即可。因为opencv是x右y下,而pcl显示x右y上。

猜你喜欢

转载自blog.csdn.net/qq_43265072/article/details/104709775
今日推荐