**《一起做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上。