44 #include <opencv2/imgproc/imgproc.hpp> 45 #include <opencv2/calib3d/calib3d.hpp> 46 #include <opencv2/video/tracking.hpp> 47 #include <pcl/common/centroid.h> 53 flowWinSize_(
Parameters::defaultVisCorFlowWinSize()),
54 flowIterations_(
Parameters::defaultVisCorFlowIterations()),
56 flowMaxLevel_(
Parameters::defaultVisCorFlowMaxLevel()),
57 minInliers_(
Parameters::defaultVisMinInliers()),
58 iterations_(
Parameters::defaultVisIterations()),
59 pnpReprojError_(
Parameters::defaultVisPnPReprojError()),
61 pnpRefineIterations_(
Parameters::defaultVisPnPRefineIterations()),
62 localHistoryMaxSize_(
Parameters::defaultOdomF2MMaxSize()),
63 initMinFlow_(
Parameters::defaultOdomMonoInitMinFlow()),
64 initMinTranslation_(
Parameters::defaultOdomMonoInitMinTranslation()),
65 minTranslation_(
Parameters::defaultOdomMonoMinTranslation()),
66 fundMatrixReprojError_(
Parameters::defaultVhEpRansacParam1()),
67 fundMatrixConfidence_(
Parameters::defaultVhEpRansacParam2()),
68 maxVariance_(
Parameters::defaultOdomMonoMaxVariance())
92 float minDepth = Parameters::defaultVisMinDepth();
93 float maxDepth = Parameters::defaultVisMaxDepth();
94 std::string roi = Parameters::defaultVisRoiRatios();
100 customParameters.insert(
ParametersPair(Parameters::kKpRoiRatios(), roi));
101 customParameters.insert(
ParametersPair(Parameters::kMemRehearsalSimilarity(),
"1.0"));
102 customParameters.insert(
ParametersPair(Parameters::kMemBinDataKept(),
"false"));
103 customParameters.insert(
ParametersPair(Parameters::kMemSTMSize(),
"0"));
104 customParameters.insert(
ParametersPair(Parameters::kMemNotLinkedNodesKept(),
"false"));
105 customParameters.insert(
ParametersPair(Parameters::kKpTfIdfLikelihoodUsed(),
"false"));
106 int nn = Parameters::defaultVisCorNNType();
107 float nndr = Parameters::defaultVisCorNNDR();
108 int featureType = Parameters::defaultVisFeatureType();
109 int maxFeatures = Parameters::defaultVisMaxFeatures();
119 int subPixWinSize = Parameters::defaultVisSubPixWinSize();
120 int subPixIterations = Parameters::defaultVisSubPixIterations();
121 double subPixEps = Parameters::defaultVisSubPixEps();
123 Parameters::parse(parameters, Parameters::kVisSubPixIterations(), subPixIterations);
130 for(ParametersMap::const_iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
134 customParameters.insert(*iter);
141 UERROR(
"Error initializing the memory for Mono Odometry.");
144 bool stereoOpticalFlow = Parameters::defaultStereoOpticalFlow();
145 Parameters::parse(parameters, Parameters::kStereoOpticalFlow(), stereoOpticalFlow);
146 if(stereoOpticalFlow)
179 UERROR(
"Image empty! Cannot compute odometry...");
185 UERROR(
"Odometry cannot be done without calibration or on multi-camera!");
195 int correspondences = 0;
202 cv::cvtColor(data.
imageRaw(), newFrame, cv::COLOR_BGR2GRAY);
225 bool newPtsAdded =
false;
228 nFeatures = (int)newS->
getWords().size();
231 cv::Mat K = cameraModel.
K();
233 cv::Mat R = (cv::Mat_<double>(3,3) <<
234 (
double)pnpGuess.
r11(), (double)pnpGuess.
r12(), (double)pnpGuess.
r13(),
235 (double)pnpGuess.
r21(), (double)pnpGuess.
r22(), (double)pnpGuess.
r23(),
236 (double)pnpGuess.
r31(), (double)pnpGuess.
r32(), (double)pnpGuess.
r33());
237 cv::Mat rvec(1,3, CV_64FC1);
238 cv::Rodrigues(R, rvec);
239 cv::Mat tvec = (cv::Mat_<double>(1,3) << (
double)pnpGuess.
x(), (double)pnpGuess.
y(), (double)pnpGuess.
z());
241 std::vector<cv::Point3f> objectPoints;
242 std::vector<cv::Point2f> imagePoints;
243 std::vector<int> matches;
245 UDEBUG(
"compute PnP from optical flow");
251 UDEBUG(
"project points to previous image");
252 std::vector<cv::Point2f> prevImagePoints;
255 cv::Mat prevR = (cv::Mat_<double>(3,3) <<
256 (
double)prevGuess.
r11(), (double)prevGuess.
r12(), (double)prevGuess.
r13(),
257 (double)prevGuess.
r21(), (double)prevGuess.
r22(), (double)prevGuess.
r23(),
258 (double)prevGuess.
r31(), (double)prevGuess.
r32(), (double)prevGuess.
r33());
259 cv::Mat prevRvec(1,3, CV_64FC1);
260 cv::Rodrigues(prevR, prevRvec);
261 cv::Mat prevTvec = (cv::Mat_<double>(1,3) << (
double)prevGuess.
x(), (double)prevGuess.
y(), (double)prevGuess.
z());
262 cv::projectPoints(objectPoints, prevRvec, prevTvec, K, cv::Mat(), prevImagePoints);
265 UDEBUG(
"project points to previous image");
266 cv::projectPoints(objectPoints, rvec, tvec, K, cv::Mat(), imagePoints);
269 std::vector<cv::Point3f> objectPointsTmp(objectPoints.size());
270 std::vector<cv::Point2f> refCorners(objectPoints.size());
271 std::vector<cv::Point2f> newCorners(objectPoints.size());
272 matches.resize(objectPoints.size());
274 for(
unsigned int i=0; i<objectPoints.size(); ++i)
276 if(
uIsInBounds(
int(imagePoints[i].x), 0, newFrame.cols) &&
277 uIsInBounds(
int(imagePoints[i].y), 0, newFrame.rows) &&
281 refCorners[oi] = prevImagePoints[i];
282 newCorners[oi] = imagePoints[i];
285 if(prevS->
getWords().count(ids[i]) == 1)
288 refCorners[oi] = prevS->
getWords().find(ids[i])->second.pt;
290 if(newS->
getWords().count(ids[i]) == 1)
293 newCorners[oi] = newS->
getWords().find(ids[i])->second.pt;
296 objectPointsTmp[oi] = objectPoints[i];
297 matches[oi] = ids[i];
301 objectPointsTmp.resize(oi);
302 refCorners.resize(oi);
303 newCorners.resize(oi);
307 std::vector<unsigned char> statusFlowInliers;
308 std::vector<float> err;
309 UDEBUG(
"cv::calcOpticalFlowPyrLK() begin");
310 cv::calcOpticalFlowPyrLK(
319 cv::OPTFLOW_LK_GET_MIN_EIGENVALS | cv::OPTFLOW_USE_INITIAL_FLOW, 1
e-4);
320 UDEBUG(
"cv::calcOpticalFlowPyrLK() end");
322 objectPoints.resize(statusFlowInliers.size());
323 imagePoints.resize(statusFlowInliers.size());
324 std::vector<int> matchesTmp(statusFlowInliers.size());
326 for(
unsigned int i=0; i<statusFlowInliers.size(); ++i)
328 if(statusFlowInliers[i])
330 objectPoints[oi] = objectPointsTmp[i];
331 imagePoints[oi] = newCorners[i];
332 matchesTmp[oi] = matches[i];
338 if(newS->
getWords().count(matches[i]) == 1)
340 kpt = newS->
getWords().find(matches[i])->second;
342 kpt.pt = newCorners[i];
343 info->
words.insert(std::make_pair(matches[i], kpt));
347 UDEBUG(
"Flow inliers= %d/%d", oi, (
int)statusFlowInliers.size());
348 objectPoints.resize(oi);
349 imagePoints.resize(oi);
350 matchesTmp.resize(oi);
351 matches = matchesTmp;
357 correspondences = (int)matches.size();
366 std::vector<int> inliersV;
382 UDEBUG(
"inliers=%d/%d", (
int)inliersV.size(), (int)objectPoints.size());
384 inliers = (int)inliersV.size();
387 UWARN(
"PnP not enough inliers (%d < %d), rejecting the transform...", (
int)inliersV.size(),
minInliers_);
391 cv::Mat R(3,3,CV_64FC1);
392 cv::Rodrigues(rvec, R);
393 Transform pnp =
Transform(R.at<
double>(0,0), R.at<
double>(0,1), R.at<
double>(0,2), tvec.at<
double>(0),
394 R.at<
double>(1,0), R.at<
double>(1,1), R.at<
double>(1,2), tvec.at<
double>(1),
395 R.at<
double>(2,0), R.at<
double>(2,1), R.at<
double>(2,2), tvec.at<
double>(2));
401 for(
unsigned int i=0; i<inliersV.size(); ++i)
409 stMem.erase(newS->
id());
411 int maxLikelihoodId = -1;
412 float maxLikelihood = 0;
413 for(std::map<int, float>::iterator iter=likelihood.begin(); iter!=likelihood.end(); ++iter)
415 if(iter->second > maxLikelihood)
417 maxLikelihood = iter->second;
418 maxLikelihoodId = iter->first;
421 UASSERT(maxLikelihoodId != -1);
430 UINFO(
"Translation with the nearest frame is too small (%f<%f) to add new points to local map",
437 const std::map<int, cv::Point3f> & previousGuess =
keyFrameWords3D_.find(previousS->
id())->second;
454 UWARN(
"Epipolar geometry not enough inliers (%d < %d), rejecting the transform (%s)...",
463 UDEBUG(
"inliers3D=%d/%d variance= %f", inliers3D.size(), newS->
getWords().size(), variance);
467 std::multimap<int, cv::Point3f> wordsToAdd;
468 for(std::map<int, cv::Point3f>::iterator iter=inliers3D.begin();
469 iter != inliers3D.end();
479 wordsToAdd.insert(std::make_pair(iter->first, newPt));
483 if((
int)wordsToAdd.size())
485 localMap_.insert(wordsToAdd.begin(), wordsToAdd.end());
487 UDEBUG(
"Added %d words", (
int)wordsToAdd.size());
499 std::list<int> removedPts;
503 for(std::list<int>::iterator iter = removedPts.begin(); iter!=removedPts.end(); ++iter)
533 std::vector<cv::Point2f> refCorners(
cornersMap_.size());
534 std::vector<cv::Point2f> refCornersGuess(
cornersMap_.size());
539 std::multimap<int, cv::KeyPoint>::const_iterator jter=refS->
getWords().find(iter->first);
541 refCorners[ii] = jter->second.pt;
542 refCornersGuess[ii] = iter->second;
543 cornerIds[ii] = iter->first;
549 std::vector<unsigned char> statusFlowInliers;
550 std::vector<float> err;
551 UDEBUG(
"cv::calcOpticalFlowPyrLK() begin");
552 cv::calcOpticalFlowPyrLK(
561 cv::OPTFLOW_LK_GET_MIN_EIGENVALS | cv::OPTFLOW_USE_INITIAL_FLOW, 1
e-4);
562 UDEBUG(
"cv::calcOpticalFlowPyrLK() end");
564 UDEBUG(
"Filtering optical flow outliers...");
574 std::vector<cv::Point2f> tmpRefCorners(statusFlowInliers.size());
575 std::vector<cv::Point2f> newCorners(statusFlowInliers.size());
576 std::vector<int> inliersV(statusFlowInliers.size());
577 std::vector<int> tmpCornersId(statusFlowInliers.size());
578 UASSERT(refCornersGuess.size() == statusFlowInliers.size());
579 UASSERT(refCorners.size() == statusFlowInliers.size());
580 UASSERT(cornerIds.size() == statusFlowInliers.size());
581 for(
unsigned int i=0; i<statusFlowInliers.size(); ++i)
583 if(statusFlowInliers[i])
585 float dx = refCorners[i].x - refCornersGuess[i].x;
586 float dy = refCorners[i].y - refCornersGuess[i].y;
590 tmpRefCorners[oi] = refCorners[i];
591 newCorners[oi] = refCornersGuess[i];
595 tmpCornersId[oi] = cornerIds[i];
608 tmpRefCorners.resize(oi);
609 newCorners.resize(oi);
610 inliersV.resize((oi));
611 tmpCornersId.resize(oi);
612 refCorners= tmpRefCorners;
613 cornerIds = tmpCornersId;
619 inliers = (int)inliersV.size();
622 UDEBUG(
"Filtering optical flow outliers...done! (inliers=%d/%d)", oi, (
int)statusFlowInliers.size());
628 UDEBUG(
"Find fundamental matrix");
629 std::vector<unsigned char> statusFInliers;
630 cv::Mat F = cv::findFundamentalMat(
641 UDEBUG(
"Filtering fundamental matrix outliers...");
642 std::vector<cv::Point2f> tmpNewCorners(statusFInliers.size());
643 std::vector<cv::Point2f> tmpRefCorners(statusFInliers.size());
644 tmpCornersId.resize(statusFInliers.size());
646 UASSERT(newCorners.size() == statusFInliers.size());
647 UASSERT(refCorners.size() == statusFInliers.size());
648 UASSERT(cornerIds.size() == statusFInliers.size());
649 std::vector<int> tmpInliers(statusFInliers.size());
650 for(
unsigned int i=0; i<statusFInliers.size(); ++i)
652 if(statusFInliers[i])
654 tmpNewCorners[oi] = newCorners[i];
655 tmpRefCorners[oi] = refCorners[i];
656 tmpInliers[oi] = inliersV[i];
657 tmpCornersId[oi] = cornerIds[i];
661 tmpInliers.resize(oi);
662 tmpNewCorners.resize(oi);
663 tmpRefCorners.resize(oi);
664 tmpCornersId.resize(oi);
665 newCorners = tmpNewCorners;
666 refCorners = tmpRefCorners;
667 inliersV = tmpInliers;
668 cornerIds = tmpCornersId;
673 inliers = (int)inliersV.size();
675 UDEBUG(
"Filtering fundamental matrix outliers...done! (inliers=%d/%d)", oi, (
int)statusFInliers.size());
679 std::vector<cv::Point2f> refCornersRefined;
680 std::vector<cv::Point2f> newCornersRefined;
682 cv::correctMatches(F, refCorners, newCorners, refCornersRefined, newCornersRefined);
683 UASSERT(refCorners.size() == refCornersRefined.size());
684 UASSERT(newCorners.size() == newCornersRefined.size());
685 refCorners = refCornersRefined;
686 newCorners = newCornersRefined;
690 cv::Mat K = cameraModel.
K();
692 cv::Mat Kinv = K.inv();
693 cv::Mat E = K.t()*F*K;
696 cv::Mat x(3, (
int)refCorners.size(), CV_64FC1);
697 cv::Mat xp(3, (
int)refCorners.size(), CV_64FC1);
698 for(
unsigned int i=0; i<refCorners.size(); ++i)
700 x.at<
double>(0, i) = refCorners[i].x;
701 x.at<
double>(1, i) = refCorners[i].y;
702 x.at<
double>(2, i) = 1;
704 xp.at<
double>(0, i) = newCorners[i].x;
705 xp.at<
double>(1, i) = newCorners[i].y;
706 xp.at<
double>(2, i) = 1;
709 cv::Mat x_norm = Kinv * x;
710 cv::Mat xp_norm = Kinv * xp;
711 x_norm = x_norm.rowRange(0,2);
712 xp_norm = xp_norm.rowRange(0,2);
717 cv::Mat P0 = cv::Mat::zeros(3, 4, CV_64FC1);
718 P0.at<
double>(0,0) = 1;
719 P0.at<
double>(1,1) = 1;
720 P0.at<
double>(2,2) = 1;
722 UDEBUG(
"Computing P...done!");
729 std::vector<double> reprojErrors;
730 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
733 std::vector<cv::Point3f> inliersRef;
734 std::vector<cv::Point3f> inliersRefGuess;
735 std::vector<cv::Point2f> imagePoints(cloud->size());
736 inliersRef.resize(cloud->size());
737 inliersRefGuess.resize(cloud->size());
738 tmpCornersId.resize(cloud->size());
741 UASSERT(newCorners.size() == cloud->size());
743 std::vector<cv::Point3f> newCorners3D;
751 std::vector<unsigned char> stereoStatus;
752 std::vector<cv::Point2f> rightCorners;
767 std::vector<cv::KeyPoint> tmpKpts;
768 cv::KeyPoint::convert(refCorners, tmpKpts);
781 for(
unsigned int i=0; i<cloud->size(); ++i)
785 imagePoints[oi] = newCorners[i];
786 tmpCornersId[oi] = cornerIds[i];
787 inliersRef[oi].x = cloud->at(i).x;
788 inliersRef[oi].y = cloud->at(i).y;
789 inliersRef[oi].z = cloud->at(i).z;
790 if(!newCorners3D.empty())
792 inliersRefGuess[oi] = newCorners3D.at(i);
797 imagePoints.resize(oi);
798 inliersRef.resize(oi);
799 inliersRefGuess.resize(oi);
800 tmpCornersId.resize(oi);
801 cornerIds = tmpCornersId;
807 std::multimap<float, float> scales;
808 if(!newCorners3D.empty())
810 UASSERT(inliersRefGuess.size() == inliersRef.size());
811 for(
unsigned int i=0; i<inliersRef.size(); ++i)
815 float s = inliersRefGuess.at(i).z/inliersRef.at(i).z;
816 std::vector<float> errorSqrdDists(inliersRef.size());
818 for(
unsigned int j=0; j<inliersRef.size(); ++j)
822 cv::Point3f refPt = inliersRef.at(j);
826 const cv::Point3f & guess = inliersRefGuess.at(j);
827 errorSqrdDists[oi++] =
uNormSquared(refPt.x-guess.x, refPt.y-guess.y, refPt.z-guess.z);
830 errorSqrdDists.resize(oi);
831 if(errorSqrdDists.size() > 2)
833 std::sort(errorSqrdDists.begin(), errorSqrdDists.end());
834 double median_error_sqr = (double)errorSqrdDists[errorSqrdDists.size () >> 1];
835 float variance = 2.1981 * median_error_sqr;
839 scales.insert(std::make_pair(variance, s));
844 if(scales.size() == 0)
846 UWARN(
"No scales found!?");
851 scale = scales.begin()->second;
852 UWARN(
"scale used = %f (variance=%f scales=%d)", scale, scales.begin()->first, (int)scales.size());
854 UDEBUG(
"Max noise variance = %f current variance=%f",
maxVariance_, scales.begin()->first);
857 UWARN(
"Too high variance %f (should be < %f)", scales.begin()->first,
maxVariance_);
863 else if(inliersRef.size())
866 Eigen::Vector4f centroid(0,0,0,0);
867 pcl::PointCloud<pcl::PointXYZ> inliersRefCloud;
868 inliersRefCloud.resize(inliersRef.size());
869 for(
unsigned int i=0; i<inliersRef.size(); ++i)
871 inliersRefCloud[i].x = inliersRef[i].x;
872 inliersRefCloud[i].y = inliersRef[i].y;
873 inliersRefCloud[i].z = inliersRef[i].z;
875 pcl::compute3DCentroid(inliersRefCloud, centroid);
876 scale = 1.0f / centroid[2];
886 std::vector<cv::Point3f> objectPoints(inliersRef.size());
887 for(
unsigned int i=0; i<inliersRef.size(); ++i)
889 objectPoints[i].x = inliersRef.at(i).x *
scale;
890 objectPoints[i].y = inliersRef.at(i).y *
scale;
891 objectPoints[i].z = inliersRef.at(i).z *
scale;
895 std::vector<int> inliersPnP;
911 UDEBUG(
"PnP inliers = %d / %d", (
int)inliersPnP.size(), (int)objectPoints.size());
913 cv::Rodrigues(rvec, R);
914 Transform pnp(R.at<
double>(0,0), R.at<
double>(0,1), R.at<
double>(0,2), tvec.at<
double>(0),
915 R.at<
double>(1,0), R.at<
double>(1,1), R.at<
double>(1,2), tvec.at<
double>(1),
916 R.at<
double>(2,0), R.at<
double>(2,1), R.at<
double>(2,2), tvec.at<
double>(2));
922 UWARN(
"Camera must be moved at least %f m for initialization (current=%f)",
931 UASSERT(cornerIds.size() == objectPoints.size());
932 std::map<int, cv::Point3f> keyFrameWords3D;
934 for(
unsigned int i=0; i<inliersPnP.size(); ++i)
936 int index =inliersPnP.at(i);
937 int id = cornerIds[index];
938 UASSERT(
id > 0 &&
id <= *wordsId.rbegin());
940 objectPoints.at(index),
942 localMap_.insert(std::make_pair(
id, cv::Point3f(pt.x, pt.y, pt.z)));
943 keyFrameWords3D.insert(std::make_pair(
id, pt));
953 UERROR(
"No valid camera matrix found!");
963 UWARN(
"Fundamental matrix not found!");
968 UWARN(
"Flow not enough high! flow=%f ki=%d", flow, oi);
988 for(std::multimap<int, cv::KeyPoint>::const_iterator iter=words.begin(); iter!=words.end(); ++iter)
990 if(words.count(iter->first) == 1)
992 cornersMap_.insert(std::make_pair(iter->first, iter->second.pt));
1000 UWARN(
"Too low 2D corners (%d), ignoring new frame...",
1007 UERROR(
"Failed creating signature");
1023 UINFO(
"Odom update=%fs tf=[%s] inliers=%d/%d, local_map[%d]=%d, accepted=%s",
1030 !output.
isNull()?
"true":
"false");
static bool isFeatureParameter(const std::string ¶m)
bool RTABMAP_EXP isFinite(const cv::Point3f &pt)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
std::map< K, V > uMultimapToMapUnique(const std::multimap< K, V > &m)
std::vector< cv::Point2f > refCorners
std::map< int, cv::Point3f > RTABMAP_EXP generateWords3DMono(const std::map< int, cv::KeyPoint > &kpts, const std::map< int, cv::KeyPoint > &previousKpts, const CameraModel &cameraModel, Transform &cameraTransform, int pnpIterations=100, float pnpReprojError=8.0f, int pnpFlags=0, int pnpRefineIterations=1, float ransacParam1=3.0f, float ransacParam2=0.99f, const std::map< int, cv::Point3f > &refGuess3D=std::map< int, cv::Point3f >(), double *variance=0)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
std::vector< K > uKeys(const std::multimap< K, V > &mm)
const std::multimap< int, cv::KeyPoint > & getWords() const
bool isInfoDataFilled() const
bool uIsInBounds(const T &value, const T &low, const T &high)
virtual void reset(const Transform &initialPose=Transform::getIdentity())
const Signature * getSignature(int id) const
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
virtual Transform computeTransform(SensorData &data, const Transform &guess=Transform(), OdometryInfo *info=0)
std::map< int, cv::Point3f > localMap
std::pair< std::string, std::string > ParametersPair
GLM_FUNC_DECL genType e()
std::map< std::string, std::string > ParametersMap
OdometryMono(const rtabmap::ParametersMap ¶meters=rtabmap::ParametersMap())
const Transform & getPose() const
Basic mathematics functions.
std::vector< int > inliersIDs
Some conversion functions.
void deleteLocation(int locationId, std::list< int > *deletedWords=0)
const cv::Mat & imageRaw() const
float initMinTranslation_
const std::set< int > & getStMem() const
bool init(const std::string &dbUrl, bool dbOverwritten=false, const ParametersMap ¶meters=ParametersMap(), bool postInitClosingEvents=false)
#define UASSERT(condition)
Wrappers of STL for convenient functions.
static double triangulatePoints(const cv::Mat &pt_set1, const cv::Mat &pt_set2, const cv::Mat &P, const cv::Mat &P1, pcl::PointCloud< pcl::PointXYZ >::Ptr &pointcloud, std::vector< double > &reproj_errors)
virtual std::vector< cv::Point2f > computeCorrespondences(const cv::Mat &leftImage, const cv::Mat &rightImage, const std::vector< cv::Point2f > &leftCorners, std::vector< unsigned char > &status) const
bool isValidForProjection() const
const CameraModel & left() const
std::vector< int > cornerInliers
bool update(const SensorData &data, Statistics *stats=0)
const cv::Mat & depthOrRightRaw() const
bool uContains(const std::list< V > &list, const V &value)
void RTABMAP_EXP solvePnPRansac(const std::vector< cv::Point3f > &objectPoints, const std::vector< cv::Point2f > &imagePoints, const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, cv::Mat &rvec, cv::Mat &tvec, bool useExtrinsicGuess, int iterationsCount, float reprojectionError, int minInliersCount, std::vector< int > &inliers, int flags, int refineIterations=1, float refineSigma=3.0f)
std::map< int, Transform > keyFramePoses_
int getLastSignatureId() const
const std::vector< CameraModel > & cameraModels() const
std::vector< V > uValues(const std::multimap< K, V > &mm)
float fundMatrixReprojError_
std::multimap< int, cv::KeyPoint > words
SensorData & sensorData()
T uNormSquared(const std::vector< T > &v)
const Signature * getLastWorkingSignature() const
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
std::vector< int > matchesIDs
std::map< int, float > computeLikelihood(const Signature *signature, const std::list< int > &ids)
std::vector< cv::Point2f > newCorners
virtual void reset(const Transform &initialPose)
std::map< int, cv::Point2f > cornersMap_
static void findRTFromP(const cv::Mat &p, cv::Mat &r, cv::Mat &t)
float fundMatrixConfidence_
void setLocalTransform(const Transform &transform)
std::map< int, std::map< int, cv::Point3f > > keyFrameWords3D_
std::vector< cv::Point3f > RTABMAP_EXP generateKeypoints3DDepth(const std::vector< cv::KeyPoint > &keypoints, const cv::Mat &depth, const CameraModel &cameraModel, float minDepth=0, float maxDepth=0)
static cv::Mat findPFromE(const cv::Mat &E, const cv::Mat &x, const cv::Mat &xp)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
std::map< int, cv::Point3f > localMap_
const Transform & localTransform() const
std::vector< cv::Point3f > RTABMAP_EXP generateKeypoints3DStereo(const std::vector< cv::Point2f > &leftCorners, const std::vector< cv::Point2f > &rightCorners, const StereoCameraModel &model, const std::vector< unsigned char > &mask=std::vector< unsigned char >(), float minDepth=0, float maxDepth=0)
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)