一起做RGB-D SLAM(5)BUG笔记

跟做高博的《一起做RGB-D SLAM》系列时,出现了挺多bug的(主要因为自己还是个小白),在此记录下解决过程。(ubuntu18.04,opencv3.4.9)

一起做RGB-D SLAM(5):

1./home/max/slam/src/slamBase.cpp:127:9: error: ‘cv2eigen’ is not a member of ‘cv’ cv::cv2eigen(R, r);

这个错误是因为缺少头文件,需要在src/slamBase.cpp里加上:

#include <opencv2/core/eigen.hpp>

注意,这个头文件只能加在slamBase.cpp里,加到头文件slamBase.h里会报错:

In file included from /home/max/slam/include/slamBase.h:9:0, from /home/max/slam/src/slamBase.cpp:1:/usr/local/include/opencv2/core/eigen.hpp:63:22: error: ‘Eigen’ does not name a type; did you mean ‘eigen’?void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )

原因可能是和其他头文件顺序冲突了?

————找到答案了,要把这个头文件加到src/slamBase.h里的#include <Eigen/Core>后面才行:

一起做RGB-D SLAM (5)的一条评论

2./home/max/slam/src/slamBase.cpp:151:10: error: ‘transformPointCloud’ is not a member of ‘pcl’pcl::transformPointCloud( *original, *output, T.matrix() );

这个错误同样是缺少头文件,需要在src/slamBase.h里加上:

#include <pcl/common/transforms.h>

3./home/max/slam/src/slamBase.cpp:155:17: error: ‘VoxelGrid’ in namespace ‘pcl’ does not name a template typestatic pcl::VoxelGrid voxel;/home/max/slam/src/slamBase.cpp:158:5: error: ‘voxel’ was not declared in this scope voxel.setLeafSize( gridsize, gridsize, gridsize );

同样缺少头文件,需要在src/slamBase.h里加上:

#include <pcl/filters/voxel_grid.h>

4.bash: bin/visualOdometry: 没有那个文件或目录

同学要记得在src/CMakeLists.txt里添加二进制可执行文件啊:

ADD_EXECUTABLE(visualOdometry visualOdometry.cpp)
TARGET_LINK_LIBRARIES(visualOdometry
	slambase
	${PCL_LIBRARIES}
	${OpenCV_LIBS})

5./home/max/slam/src/visualOdometry.cpp:33:42: error: ‘getDefaultCamera’ was not declared in this scopeCAMERA_INTRINSIC_PARAMETERS camera = getDefaultCamera();

这个是忘了写读取相机内参的内联函数了,在src/slamBase.h里加上即可:

inline static CAMERA_INTRINSIC_PARAMETERS getDefaultCamera()
{
    ParameterReader pd;
    CAMERA_INTRINSIC_PARAMETERS camera;
    camera.fx = atof( pd.getData( "camera.fx" ).c_str());
    camera.fy = atof( pd.getData( "camera.fy" ).c_str());
    camera.cx = atof( pd.getData( "camera.cx" ).c_str());
    camera.cy = atof( pd.getData( "camera.cy" ).c_str());
    camera.scale = atof( pd.getData( "camera.scale" ).c_str() );
    return camera;
}

6./home/max/slam/src/visualOdometry.cpp:59:31: error: ‘cvMat2Eigen’ was not declared in this scopeEigen::Isometry3d T = cvMat2Eigen( result.rvec, result.tvec );/home/max/slam/src/visualOdometry.cpp:63:17: error: ‘joinPointCloud’ was not declared in this scope cloud = joinPointCloud( cloud, currFrame, T, camera );

src/slamBase.h里忘记声明cpp里对应的函数了:

PointCloud::Ptr joinPointCloud( PointCloud::Ptr original, FRAME& newFrame, Eigen::Isometry3d T, CAMERA_INTRINSIC_PARAMETERS& camera );
Eigen::Isometry3d cvMat2Eigen( cv::Mat& rvec, cv::Mat& tvec );

7.CMakeFiles/jointPointCloud.dir/jointPointCloud.cpp.o:在函数‘main’中:jointPointCloud.cpp:(.text+0xd4b):对‘pcl::visualization::CloudViewer::CloudViewer(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)’未定义的引用jointPointCloud.cpp:(.text+0xdd8):对‘pcl::visualization::CloudViewer::showCloud(boost::shared_ptr<pcl::PointCloudpcl::PointXYZRGBA const> const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)’未定义的引用

在src/CMakeLists.txt中,加入:

FIND_PACKAGE(PCL REQUIRED COMPONENTS common io visualization filters)

8./home/max/slam/src/visualOdometry.cpp:37:10: error: ‘pcl::visualization’ has not been declaredpcl::visualization::CloudViewer viewer(“viewer”);

缺少头文件,需要在src/slamBase.h里加上:

#include <pcl/visualization/cloud_viewer.h>

9.terminate called after throwing an instance of 'cv::Exception’what(): OpenCV(3.4.9) /home/max/SLAM-env/opencv-3.4.9/modules/calib3d/src/solvepnp.cpp:216: error: (-215:Assertion failed) npoints >= 4 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) in function ‘solvePnPRansac’ 已放弃 (核心已转储)

修改src/slamBase.cpp的RESULT_OF_PNP estimateMotion()函数,在下图中第一个白框处添加代码:

if ( minDis < 10 ) 
{
        minDis = 10;
}

在第二个白框处添加代码:

RESULT_OF_PNP result;
if (pts_obj.size() ==0 || pts_img.size()==0)
{
        result.inliers = -1;
        return result;
}

在这里插入图片描述

10.运行结果时,点对数据都为0,mins距离都是999。terminate called after throwing an instance of 'pcl::IOException’what(): : [pcl::PCDWriter::writeASCII] Input point cloud has no data! 已放弃 (核心已转储)

这个错误是由于没有找到数据文件,把参数文件parameters.txt里的数据目录修改为:

rgb_dir=data/rgb_png/
depth_dir=data/depth_png/

或者改为绝对路径也可以。

11.运行结果时会因为3d-2d点对不够而终止程序(到文件254时终止)。terminate called after throwing an instance of ‘cv::Exception’ what(): OpenCV(3.4.9) /home/max/SLAM-env/opencv-3.4.9/modules/calib3d/src/calibration.cpp:1097: error: (-2:Unspecified error) in function ‘void cvFindExtrinsicCameraParams2(const CvMat*, const CvMat*, const CvMat*, const CvMat*, CvMat*, CvMat*, int)’> DLT algorithm needs at least 6 points for pose estimation from 3D-2D point correspondences. (expected: ‘count >= 6’), where> ‘count’ is 5 > must be greater than or equal to > ‘6’ is 6 已放弃 (核心已转储)

这个问题是因为在依据两帧图像求相机位姿变化矩阵时(solvepnp类的函数),opencv会在此函数里调用另一个函数(FindExtrinsicCameraParams2),这个函数的3D-2D求解方法要求输入点对数必须大于等于6,而我们输入的点对数明显小于6.

一开始猜想是因为有两帧图像一样,导致点对数不够,加上判断就行,于是按照高博提示,在src/slamBase.cpp里(下图白框处)加上两个判断:

优化匹配点对数目至少要6对以上:

if (goodMatches.size() <= 5) 
{
     result.inliers = -1;
     return result;
}

输入solvepnpransac函数的前一帧三维点对和后一帧二维点对数目至少要大于6:

if (pts_obj.size() <=5 || pts_img.size() <= 5)
{
     result.inliers = -1;
     return result;
}

在这里插入图片描述

加入判断以后,bug解决了,确实可以继续运行下去,但是在254帧时又出现了同样的错误,利用之前写的detectfeatures程序运行测试,发现253和254帧并不相同,goodmatch和solvepnpransac的输入点对数也都是大于6的。做了大量的调试也没找到解决方法,甚至连问题都不知道出在哪里,就在我准备放弃的时候,在opencv官方文档里发现了猫腻:opencv官方文档
在这里插入图片描述
solvepnpransac函数里的第9个参数,是RANSAC 程序的内部阈值,参数值是观测点和计算点投影之间允许的最大距离。高博的代码里设置的是1,我们把这个值调大一点,改为默认值8就ok了。将src/slamBase.cpp(下图白框处)改为:

cv::solvePnPRansac( pts_obj, pts_img, cameraMatrix, cv::Mat(), rvec, tvec, false, 100, 8.0, 0.99, inliers );

在这里插入图片描述

注意,这个改法仅适用于一起做RGB-D SLAM(5),如果是(7)的话,请参照一起做RGB-D SLAM(7)BUG笔记

ps:voxel_grid分辨率设为0.01效果会好一些;结果图只显示坐标轴或绿红黑三色块,按r重置视角;parameters.txt默认是放在项目根目录下的;计算变换矩阵时的平移矩阵写反了,不过影响不大,可参考一起做RGB-D SLAM(4)BUG笔记最后一个bug。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
RGB-D SLAM是一种同时定位与地图构建(Simultaneous Localization and Mapping)的技术,它利用RGB-D图像来实现对环境的感知和建模。RGB-D图像由RGB图像和深度图像组成,其中RGB图像提供了颜色信息,深度图像则提供了物体距离传感器的实际距离信息。通过将RGB图像和深度图像进行配准,可以实现像素级别的对应关系。RGB-D SLAM可以通过对连续的RGB-D图像进行处理,实时地估计相机的运动轨迹,并同时构建环境的三维地图。 在RGB-D SLAM中,有多种算法和系统可供选择。例如,RGBDSLAM2是一个非常全面优秀的系统,它将SLAM领域的图像特征、优化、闭环检测、点云等技术融为一体,适合初学者使用并可以进行二次开发。然而,RGBDSLAM2的实时性较差,相机必须以较慢的速度运动,并且使用点云来表示三维地图会消耗较多的内存。此外,还有其他的RGB-D SLAM算法和系统可供选择,具体选择哪种算法和系统取决于具体的应用需求和硬件条件。 引用\[1\]中提到了RGB-D图像的组成和配准过程,引用\[2\]中提到了RGB双目相机的特点和限制,引用\[3\]中提到了RGBDSLAM2系统的特点和缺点。这些引用内容提供了关于RGB-D SLAM的基本概念和相关技术的信息。 #### 引用[.reference_title] - *1* [SLAM(二)——RGB-D的含义](https://blog.csdn.net/u013401766/article/details/78671939)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [RGBD-SLAM总结](https://blog.csdn.net/YOULANSHENGMENG/article/details/124141028)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [RGB-D SLAM 相关总结](https://blog.csdn.net/qq_38167930/article/details/118879187)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值