欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

视觉SLAM:生成点云部分学习

程序员文章站 2024-03-25 10:41:30
...

前期准备:在ubuntu16.04安装编译好了opencv、eigen、及PCL(根据源码安装)。

采用深度相机RGB-D。

参考方法为:(1)视觉slam十四讲第5讲,代码见https://github.com/gaoxiang12/slambook

(2)高博博客:https://www.cnblogs.com/gaoxiang12/p/4652478.html

(第二讲,从图像到点云)

在跑(1)示例代码时,出现提示:point cloud size = 0 terminate called after throwing an instance of 'pcl::IOException'
  what():  : [pcl::PCDWriter::writeASCII] Input point cloud has no data!

首先查看是否对智能指针进行了初始化。在PCL中一定要初始化!初始化!初始化!已有:

PointCloud::Ptr cloud (new PointCloud);

依然会报此错误,出现问题的原因是对空指针进行操作,分析之后发现,没有对图像进行处理,所以没有对点云赋值,点云指针就是空指针。解决办法,是在包含data文件夹路径下运行程序。(在ch5-jionMap,把color与depth两个文件夹copy到cmake-buiild-debug文件目录下————clion编译);但仍未成功。

提示:terminate called after throwing an instance of ‘pcl::IOException’ what(): [pcl::PCDWriter::writeASCII] Number of points different than width * height! Aborted 

查询发现,还需在代码中添加:

pointCloud->width = 1;
pointCloud->height = pointCloud->points.size();
pcl::io::savePCDFileBinary("map.pcd", *pointCloud );

这是在点云写入的时候遇到的一个问题,因为LZ不确定最后点云的数量有多少,所以并没有制定点云的height和width,然后在写PCD的时候会不认,解决方案如下,在写PCD之前可以这样显示的定义一下点云的height和width。

经过以上操作,即可运行成功,否则clion编译会Aborted。

 

在跑(2)示例代码时,出现了一系列undefined reference问题,cmake编译不成功,才开始主要集中在cmake编译问题,后期出现同示例(1)的问题,按照示例(1)中解决办法解决即可。尝试修改CMakeLIsts.txt文件。

源于太粗心大意了,将链接库:

TARGET_LINK_LIBRARIES( generatePointCloud ${OpenCV_LIBS} ${PCL_LIBRARIES} )
误写成
TARGET_LINK_LIBRARIES( generatePointCloud ${OpenCV_LIBS} ${PCL_LIBSRARIES} )

导致提示:error: #error PCL requires C++14 or above
   #error PCL requires C++14 or above,以为是g++版本问题,引发了上一篇博客,并添加指令

ADD_COMPILE_OPTIONS(-std=c++14 ),添加后虽不再提示该问题,但出现系列underfined reference,是因为链接库不对的问题。

再无拼写错误的情况下,

ADD_COMPILE_OPTIONS(-std=c++11 )
ADD_COMPILE_OPTIONS(-std=c++14 )
set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
或不规定cmkae编译带有c++11特性等均可以编译成功。

在获取彩色图像的b\g\r数值部分不是特别明白:

p.b = color.data[ v*color.step+u*color.channels() ];
p.g = color.data[ v*color.step+u*color.channels()+1 ];
p.r = color.data[ v*color.step+u*color.channels()+2 ];

p.b = color.ptr<uchar>(v)[u*3];

p.b = color.ptr<uchar>(v)[u*3+1];

p.b = color.ptr<uchar>(v)[u*3+2];

 

以及通过T将坐标由相机坐标系转化到世界坐标系中(是Vector3d 中×重载么?)

Eigen::Vector3d pointWorld = T*point;对应公式Puv=TPw。