RGB-D SLAM——点云拼接篇(二)
来源:互联网 发布:成都网络推广公司排名 编辑:程序博客网 时间:2024/05/21 19:49
1.OpenCv旋转向量平移向量转换为Eigen变换矩阵
在上一节中我们已经知道如何求出俩张图片的旋转向量和平移向量,那么接下来我们需要将旋转向量和平移向量转换成平移矩阵,可以使用Eigen工具来实现:
Eigen::Isometry3d cvMat2Eigen(cv::Mat &rvec,cv::Mat &tvec){ cv::Mat R; cv::Rodrigues(rvec,R);//罗德里格旋转公式,将3x1的旋转向量转换成3x3的旋转矩阵 Eigen::Matrix3d r; //the matrix are 3x3,类型为double cv::cv2eigen(R,r);//将cv格式的矩阵(Mat类型的)转换成Eigen类型的Matrix Eigen::Isometry3d T=Eigen::Isometry3d::Identity();//旋转和平移的集合,4*4的矩阵 Eigen::AngleAxisd angle(r); Eigen::Translation<double,3> trans(tvec.at<double>(0,0),tvec.at<double>(0,1),tvec.at<double>(0,2)); T=angle; //完成旋转矩阵的存储 T(0,3)=tvec.at<double>(0,0); T(1,3)=tvec.at<double>(0,1); T(2,3)=tvec.at<double>(0,2); return T;}
这段程序需要的知识:
1.其中的Rodrigues()函数:
原型为(详细可见该API):
void Rodrigues(InputArray src, OutputArray dst, OutputArray jacobian=noArray())Parameters: src – 输入旋转向量(3x1/1x3)或者旋转矩阵(3x3) dst – 分别输出旋转矩阵(3x3)或者(3x1/1x3) jacobian – 可选择的输出雅克比矩阵,为3x9的或者9x3的,简单来说就是输出矩阵对输入矩阵的分别的局部派生关系 2.这是cv旋转向量和平移向量的转换,之所以只要这么转换,主要是后面pcl点云拼接的时候会用到Eigen的矩阵,因为pcl用了第三方的Eigen来进行矩阵的运算。
2.拼接点云,俩帧点云
当有了每帧图像的点云,又有了俩帧相对的转换关系之后,这时候我们就可以进行点云的拼接了,点云拼接的具体函数如下所示:
void jointPointCloud(FRAME &originalframe,FRAME &newframe,Eigen::Isometry3d &T) //{ PointCloud::Ptr originalcloud=image2PointCloud(originalframe.rgb,originaleframe.depth); PointCloud::Ptr newCloud=image2PointCloud(newframe.rgb,newframe.depth); PointCloud::Ptr cloud_output(new PointCloud()); pcl::transformPointCloud(*originalcloud,*cloud_output,T.matrix()); *cloud_output += *newCloud;//降采样滤波,如果在这里使用了#include <pcl/filters/voxel_grid.h>,记得把CMakeLists里的set(CMAKE_CXX_FLAGS "-std=c++11 ")字眼去掉 static pcl::VoxelGrid<PointT> voxel; voxel.setLeafSize(0.01f,0.01f,0.01f); voxel.setInputCloud(cloud_output); PointCloud::Ptr tmp(new PointCloud()); voxel.filter(*tmp); pcl::io::savePCLFile("jointcloud",*cloud_output); pcl::visualization::CloudViewer viewer("jointcloud"); viewer.showCloud(cloud_output)}
则得到以下效果:
3.多帧图片进行点云拼接
为完成多点云拼接,需要不断的向里面导入新的点云,然后通过T不断的组装起来,在下面展示如果不断的导入帧并实现把帧给融合起来。
int main(int argc, char** argv){ vector<FRAME> frame; vector<Eigen::Isometry3d> Trans;//导入帧,使构成的地图更加完整 for(int i=1;i<300;i++) { FRAME frame_single; string path_rgb("/home/hansry/Pose_part/data/rgb_png/"); string path_depth("/home/hansry/Pose_part/data/depth_png/"); string suffix(".png"); stringstream str_rgb,str_depth; str_rgb<<path_rgb<<i<<suffix; str_depth<<path_depth<<i<<suffix; frame_single.rgb=imread(str_rgb.str()); frame_single.depth=imread(str_depth.str(),-1); frame.push_back(frame_single); } cout<<frame.size()<<endl; for(int k=0;k<(frame.size()-1);k++) { computeKeyPointsAndDesp(frame[k]); computeKeyPointsAndDesp(frame[k+1]); RESULT_OF_PNP result=estimateMotion(frame[k],frame[k+1]); if ( result.inliers < 5 ) //inliers不够,放弃该帧 continue; double norm = normofTransform(result.rvec, result.tvec); cout<<"norm = "<<norm<<endl; if ( norm >= 0.3) continue; Eigen::Isometry3d T=cvMat2Eigen(result.rvec,result.tvec); Trans.push_back(T); cout<<Trans.size()<<endl; } //生成第一帧的点云 PointCloud::Ptr original_cloud=image2PointCloud(frame[0].rgb,frame[0].depth); for(int j=1;j<frame.size();j++) { PointCloud::Ptr output=jointPointCloud(original_cloud,frame[j],Trans[j-1]); original_cloud=output; } pcl::io::savePCDFile("/home/hansry/Pose_part/data/outputcloud.pcd",*original_cloud); waitKey(0); return 0;}
程序运行结果如下:
有点心塞,滤波虽然能很好的提升速度,但是好像失真得好厉害啊啊啊啊啊!!!!
最后,就只剩下优化啦!!!
参考:https://github.com/gaoxiang12/rgbd-slam-tutorial-gx/blob/master/part%20VI/include/slamBase.h
阅读全文
0 0
- RGB-D SLAM——点云拼接篇(二)
- 一起做RGB-D SLAM (4) 点云拼接
- 4、RGB-D—点云拼接 joinPointCloud
- SLAM(二)——RGB-D的含义
- RGB-D SLAM——匹配篇(一)
- RGB-D SLAM——g2o篇(三)
- RGB-D SLAM——回环检测篇(四)
- 调试笔记——《一起做RGB-D SLAM 》
- 一起做RGB-D SLAM 第二季 (二)
- SLAM实战 RGB-D SLAM V2
- RGB-D SLAM环境配置
- rgb-d slam(2)笔记
- 一起做RGB-D SLAM(7) (完结篇)
- 一起做RGB-D SLAM(7) (完结篇)
- 一起做RGB-D SLAM(7) (完结篇)
- 一起做RGB-D SLAM(7) (完结篇)
- 【转】一起做RGB-D SLAM (1)
- 一起做RGB-D SLAM (1)
- 欢迎使用CSDN-markdown编辑器
- ubuntu安装eclipse
- 示波器调试RS485通信波形图
- Java设置大数非科学计数法显示
- git 常用命令
- RGB-D SLAM——点云拼接篇(二)
- #正念奇迹#ZQ0012《演讲的力量:如何让公众表达变成影响力》
- sass-安装ruby
- [经验] C语言关键字中static,volatile,const,extern,return含义及作用?
- 有return 0 为什么出错还正常显示;为什么不溢出显示-32768
- 51nod 1018 排序
- Linux文件系统之一:inode节点和inode节点包含的block寻址信息
- git fatal: Unable to find remote helper for 'https'
- SSH与SSM学习之hibernate20——多对多操作