赞
踩
源码链接: link.
搭建对应的环境,安装对应的各个库的版本,最好就用它测试用的那些库版本,即对应的GitHub上的readme。
1、编译过程中会出现如下报错信息:
/ORB_SLAM3/src/LocalMapping.cc:628:49: error: no match for ‘operator/’ (operand types are ‘cv::Matx<float, 3, 1>’ and ‘float’)
x3D = x3D_h.get_minor<3,1>(0,0) / x3D_h(3);
解决:
注: cv::Matx固定维度的矩阵,在编译之前便知道其维度大小,用其替代cv::Mat可以减少内存占用,提高效率.
可能是OpenCV版本的原因,代码不支持此操作符,在不更换OpenCV版本的情况下可以通过修改代码解决此问题:修改步骤如下:
(1)在void KannalaBrandt8::Triangulate_()中注释掉出错的这句话:
x3D = x3D_h.get_minor<3,1>(0,0) / x3D_h(3)
(2)在void LocalMapping::CreateNewMapPoints()修改为:
(其实就是ORBSLAM3上一版的函数直接copy过来):
void LocalMapping::CreateNewMapPoints() { // Retrieve neighbor keyframes in covisibility graph int nn = 10; // For stereo inertial case if(mbMonocular) nn=20; vector<KeyFrame*> vpNeighKFs = mpCurrentKeyFrame->GetBestCovisibilityKeyFrames(nn); if (mbInertial) { KeyFrame* pKF = mpCurrentKeyFrame; int count=0; while((vpNeighKFs.size()<=nn)&&(pKF->mPrevKF)&&(count++<nn)) { vector<KeyFrame*>::iterator it = std::find(vpNeighKFs.begin(), vpNeighKFs.end(), pKF->mPrevKF); if(it==vpNeighKFs.end()) vpNeighKFs.push_back(pKF->mPrevKF); pKF = pKF->mPrevKF; } } float th = 0.6f; ORBmatcher matcher(th,false); cv::Mat Rcw1 = mpCurrentKeyFrame->GetRotation(); cv::Mat Rwc1 = Rcw1.t(); cv::Mat tcw1 = mpCurrentKeyFrame->GetTranslation(); cv::Mat Tcw1(3,4,CV_32F); Rcw1.copyTo(Tcw1.colRange(0,3)); tcw1.copyTo(Tcw1.col(3)); cv::Mat Ow1 = mpCurrentKeyFrame->GetCameraCenter(); const float &fx1 = mpCurrentKeyFrame->fx; const float &fy1 = mpCurrentKeyFrame->fy; const float &cx1 = mpCurrentKeyFrame->cx; const float &cy1 = mpCurrentKeyFrame->cy; const float &invfx1 = mpCurrentKeyFrame->invfx; const float &invfy1 = mpCurrentKeyFrame->invfy; const float ratioFactor = 1.5f*mpCurrentKeyFrame->mfScaleFactor; // Search matches with epipolar restriction and triangulate for(size_t i=0; i<vpNeighKFs.size(); i++) { if(i>0 && CheckNewKeyFrames())// && (mnMatchesInliers>50)) return; KeyFrame* pKF2 = vpNeighKFs[i]; GeometricCamera* pCamera1 = mpCurrentKeyFrame->mpCamera, *pCamera2 = pKF2->mpCamera; // Check first that baseline is not too short cv::Mat Ow2 = pKF2->GetCameraCenter(); cv::Mat vBaseline = Ow2-Ow1; const float baseline = cv::norm(vBaseline); if(!mbMonocular) { if(baseline<pKF2->mb) continue; } else { const float medianDepthKF2 = pKF2->ComputeSceneMedianDepth(2); const float ratioBaselineDepth = baseline/medianDepthKF2; if(ratioBaselineDepth<0.01) continue; } // Compute Fundamental Matrix cv::Mat F12 = ComputeF12(mpCurrentKeyFrame,pKF2); // Search matches that fullfil epipolar constraint vector<pair<size_t,size_t> > vMatchedIndices; bool bCoarse = mbInertial && ((!mpCurrentKeyFrame->GetMap()->GetIniertialBA2() && mpCurrentKeyFrame->GetMap()->GetIniertialBA1())|| mpTracker->mState==Tracking::RECENTLY_LOST); matcher.SearchForTriangulation(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false,bCoarse); cv::Mat Rcw2 = pKF2->GetRotation(); cv::Mat Rwc2 = Rcw2.t(); cv::Mat tcw2 = pKF2->GetTranslation(); cv::Mat Tcw2(3,4,CV_32F); Rcw2.copyTo(Tcw2.colRange(0,3)); tcw2.copyTo(Tcw2.col(3)); const float &fx2 = pKF2->fx; const float &fy2 = pKF2->fy; const float &cx2 = pKF2->cx; const float &cy2 = pKF2->cy; const float &invfx2 = pKF2->invfx; const float &invfy2 = pKF2->invfy; // Triangulate each match const int nmatches = vMatchedIndices.size(); for(int ikp=0; ikp<nmatches; ikp++) { const int &idx1 = vMatchedIndices[ikp].first; const int &idx2 = vMatchedIndices[ikp].second; const cv::KeyPoint &kp1 = (mpCurrentKeyFrame -> NLeft == -1) ? mpCurrentKeyFrame->mvKeysUn[idx1] : (idx1 < mpCurrentKeyFrame -> NLeft) ? mpCurrentKeyFrame -> mvKeys[idx1] : mpCurrentKeyFrame -> mvKeysRight[idx1 - mpCurrentKeyFrame -> NLeft]; const float kp1_ur=mpCurrentKeyFrame->mvuRight[idx1]; bool bStereo1 = (!mpCurrentKeyFrame->mpCamera2 && kp1_ur>=0); const bool bRight1 = (mpCurrentKeyFrame -> NLeft == -1 || idx1 < mpCurrentKeyFrame -> NLeft) ? false : true; const cv::KeyPoint &kp2 = (pKF2 -> NLeft == -1) ? pKF2->mvKeysUn[idx2] : (idx2 < pKF2 -> NLeft) ? pKF2 -> mvKeys[idx2] : pKF2 -> mvKeysRight[idx2 - pKF2 -> NLeft]; const float kp2_ur = pKF2->mvuRight[idx2]; bool bStereo2 = (!pKF2->mpCamera2 && kp2_ur>=0); const bool bRight2 = (pKF2 -> NLeft == -1 || idx2 < pKF2 -> NLeft) ? false : true; if(mpCurrentKeyFrame->mpCamera2 && pKF2->mpCamera2){ if(bRight1 && bRight2){ Rcw1 = mpCurrentKeyFrame->GetRightRotation(); Rwc1 = Rcw1.t(); tcw1 = mpCurrentKeyFrame->GetRightTranslation(); Tcw1 = mpCurrentKeyFrame->GetRightPose(); Ow1 = mpCurrentKeyFrame->GetRightCameraCenter(); Rcw2 = pKF2->GetRightRotation(); Rwc2 = Rcw2.t(); tcw2 = pKF2->GetRightTranslation(); Tcw2 = pKF2->GetRightPose(); Ow2 = pKF2->GetRightCameraCenter(); pCamera1 = mpCurrentKeyFrame->mpCamera2; pCamera2 = pKF2->mpCamera2; } else if(bRight1 && !bRight2){ Rcw1 = mpCurrentKeyFrame->GetRightRotation(); Rwc1 = Rcw1.t(); tcw1 = mpCurrentKeyFrame->GetRightTranslation(); Tcw1 = mpCurrentKeyFrame->GetRightPose(); Ow1 = mpCurrentKeyFrame->GetRightCameraCenter(); Rcw2 = pKF2->GetRotation(); Rwc2 = Rcw2.t(); tcw2 = pKF2->GetTranslation(); Tcw2 = pKF2->GetPose(); Ow2 = pKF2->GetCameraCenter(); pCamera1 = mpCurrentKeyFrame->mpCamera2; pCamera2 = pKF2->mpCamera; } else if(!bRight1 && bRight2){ Rcw1 = mpCurrentKeyFrame->GetRotation(); Rwc1 = Rcw1.t(); tcw1 = mpCurrentKeyFrame->GetTranslation(); Tcw1 = mpCurrentKeyFrame->GetPose(); Ow1 = mpCurrentKeyFrame->GetCameraCenter(); Rcw2 = pKF2->GetRightRotation(); Rwc2 = Rcw2.t(); tcw2 = pKF2->GetRightTranslation(); Tcw2 = pKF2->GetRightPose(); Ow2 = pKF2->GetRightCameraCenter(); pCamera1 = mpCurrentKeyFrame->mpCamera; pCamera2 = pKF2->mpCamera2; } else{ Rcw1 = mpCurrentKeyFrame->GetRotation(); Rwc1 = Rcw1.t(); tcw1 = mpCurrentKeyFrame->GetTranslation(); Tcw1 = mpCurrentKeyFrame->GetPose(); Ow1 = mpCurrentKeyFrame->GetCameraCenter(); Rcw2 = pKF2->GetRotation(); Rwc2 = Rcw2.t(); tcw2 = pKF2->GetTranslation(); Tcw2 = pKF2->GetPose(); Ow2 = pKF2->GetCameraCenter(); pCamera1 = mpCurrentKeyFrame->mpCamera; pCamera2 = pKF2->mpCamera; } } // Check parallax between rays cv::Mat xn1 = pCamera1->unprojectMat(kp1.pt); cv::Mat xn2 = pCamera2->unprojectMat(kp2.pt); cv::Mat ray1 = Rwc1*xn1; cv::Mat ray2 = Rwc2*xn2; const float cosParallaxRays = ray1.dot(ray2)/(cv::norm(ray1)*cv::norm(ray2)); float cosParallaxStereo = cosParallaxRays+1; float cosParallaxStereo1 = cosParallaxStereo; float cosParallaxStereo2 = cosParallaxStereo; if(bStereo1) cosParallaxStereo1 = cos(2*atan2(mpCurrentKeyFrame->mb/2,mpCurrentKeyFrame->mvDepth[idx1])); else if(bStereo2) cosParallaxStereo2 = cos(2*atan2(pKF2->mb/2,pKF2->mvDepth[idx2])); cosParallaxStereo = min(cosParallaxStereo1,cosParallaxStereo2); cv::Mat x3D; if(cosParallaxRays<cosParallaxStereo && cosParallaxRays>0 && (bStereo1 || bStereo2 || (cosParallaxRays<0.9998 && mbInertial) || (cosParallaxRays<0.9998 && !mbInertial))) { // Linear Triangulation Method cv::Mat A(4,4,CV_32F); A.row(0) = xn1.at<float>(0)*Tcw1.row(2)-Tcw1.row(0); A.row(1) = xn1.at<float>(1)*Tcw1.row(2)-Tcw1.row(1); A.row(2) = xn2.at<float>(0)*Tcw2.row(2)-Tcw2.row(0); A.row(3) = xn2.at<float>(1)*Tcw2.row(2)-Tcw2.row(1); cv::Mat w,u,vt; cv::SVD::compute(A,w,u,vt,cv::SVD::MODIFY_A| cv::SVD::FULL_UV); x3D = vt.row(3).t(); if(x3D.at<float>(3)==0) continue; // Euclidean coordinates x3D = x3D.rowRange(0,3)/x3D.at<float>(3); } else if(bStereo1 && cosParallaxStereo1<cosParallaxStereo2) { x3D = mpCurrentKeyFrame->UnprojectStereo(idx1); } else if(bStereo2 && cosParallaxStereo2<cosParallaxStereo1) { x3D = pKF2->UnprojectStereo(idx2); } else { continue; //No stereo and very low parallax } cv::Mat x3Dt = x3D.t(); if(x3Dt.empty()) continue; //Check triangulation in front of cameras float z1 = Rcw1.row(2).dot(x3Dt)+tcw1.at<float>(2); if(z1<=0) continue; float z2 = Rcw2.row(2).dot(x3Dt)+tcw2.at<float>(2); if(z2<=0) continue; //Check reprojection error in first keyframe const float &sigmaSquare1 = mpCurrentKeyFrame->mvLevelSigma2[kp1.octave]; const float x1 = Rcw1.row(0).dot(x3Dt)+tcw1.at<float>(0); const float y1 = Rcw1.row(1).dot(x3Dt)+tcw1.at<float>(1); const float invz1 = 1.0/z1; if(!bStereo1) { cv::Point2f uv1 = pCamera1->project(cv::Point3f(x1,y1,z1)); float errX1 = uv1.x - kp1.pt.x; float errY1 = uv1.y - kp1.pt.y; if((errX1*errX1+errY1*errY1)>5.991*sigmaSquare1) continue; } else { float u1 = fx1*x1*invz1+cx1; float u1_r = u1 - mpCurrentKeyFrame->mbf*invz1; float v1 = fy1*y1*invz1+cy1; float errX1 = u1 - kp1.pt.x; float errY1 = v1 - kp1.pt.y; float errX1_r = u1_r - kp1_ur; if((errX1*errX1+errY1*errY1+errX1_r*errX1_r)>7.8*sigmaSquare1) continue; } //Check reprojection error in second keyframe const float sigmaSquare2 = pKF2->mvLevelSigma2[kp2.octave]; const float x2 = Rcw2.row(0).dot(x3Dt)+tcw2.at<float>(0); const float y2 = Rcw2.row(1).dot(x3Dt)+tcw2.at<float>(1); const float invz2 = 1.0/z2; if(!bStereo2) { cv::Point2f uv2 = pCamera2->project(cv::Point3f(x2,y2,z2)); float errX2 = uv2.x - kp2.pt.x; float errY2 = uv2.y - kp2.pt.y; if((errX2*errX2+errY2*errY2)>5.991*sigmaSquare2) continue; } else { float u2 = fx2*x2*invz2+cx2; float u2_r = u2 - mpCurrentKeyFrame->mbf*invz2; float v2 = fy2*y2*invz2+cy2; float errX2 = u2 - kp2.pt.x; float errY2 = v2 - kp2.pt.y; float errX2_r = u2_r - kp2_ur; if((errX2*errX2+errY2*errY2+errX2_r*errX2_r)>7.8*sigmaSquare2) continue; } //Check scale consistency cv::Mat normal1 = x3D-Ow1; float dist1 = cv::norm(normal1); cv::Mat normal2 = x3D-Ow2; float dist2 = cv::norm(normal2); if(dist1==0 || dist2==0) continue; if(mbFarPoints && (dist1>=mThFarPoints||dist2>=mThFarPoints)) // MODIFICATION continue; const float ratioDist = dist2/dist1; const float ratioOctave = mpCurrentKeyFrame->mvScaleFactors[kp1.octave]/pKF2->mvScaleFactors[kp2.octave]; if(ratioDist*ratioFactor<ratioOctave || ratioDist>ratioOctave*ratioFactor) continue; // Triangulation is succesfull MapPoint* pMP = new MapPoint(x3D,mpCurrentKeyFrame,mpAtlas->GetCurrentMap()); pMP->AddObservation(mpCurrentKeyFrame,idx1); pMP->AddObservation(pKF2,idx2); mpCurrentKeyFrame->AddMapPoint(pMP,idx1); pKF2->AddMapPoint(pMP,idx2); pMP->ComputeDistinctiveDescriptors(); pMP->UpdateNormalAndDepth(); mpAtlas->AddMapPoint(pMP); mlpRecentAddedMapPoints.push_back(pMP); } } }
运行报错:libg2o.so文件找不到
解决:个人猜想其实是ros运行没有弄对,因为我没有创建工作空间,直接在源码的文件夹里面搞的,所以会出错!
创建文件夹catkin_ws_orbslam3,并在终端打开
mkdir src
cd src
catkin_init_workspace
此时,如果src文件夹下出现了CMakeLists文件,说明工作空间生成成功
cd .. //回到上级catkin_ws_orbslam3目录
catkin_make
编译成功根目录后会出现devel和src文件
1、将ORB-SLAM3源码放入catkin_ws_orbslam3/src文件下
2、在主文件夹下,Ctrl+h,可以看到隐藏的文件,在.bashrc文档末尾添加两行:(根据自己路径更改),命令操作为:
sudo gedit ~/.bashrc
打开后文件后在最后一行添加:
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/chen/catkin_ws_orbslam3/src/ORB_SLAM3/Examples/ROS
source ~/catkin_ws_orbslam3/devel/setup.bash
在终端运行:
source ~/.bashrc
3、编译orb_slam3
打开终端,运行
cd catkin_ws_orbslam3/src/ORB_SLAM3
mkdir build
cd build
cmake ..
make -j12
4、编译ROS的example
cd ~/catkin_ws_orbslam3/src/ORB_SLAM3/Example/ROS/ORB_SLAM3
mkdir build
cd build
cmake ..
make -j12
1、分别打开3个终端
终端1:roscore
终端2:在目录/catkin_ws_orbslam3/src/ORB_SLAM3下运行:
rosrun ORB_SLAM3 Stereo Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml true
终端3:在数据集的目录(/Datasets)下
rosbag play MH_02_easy.bag /cam0/image_raw:=/camera/left/image_raw /cam1/image_raw:=/camera/right/image_raw /imu0:=/imu
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。