mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Added Daisy descriptor. ORB: updated default parameters. Making ORBOctree using ORB parameters. Updated Vis/CorNNDR default from 0.6 to 0.8 (increase number of matches with binary descriptors, increase slightly feature matching time with float descriptors). Note that jfr2018 scripts have been updated to use old value 0.6. rtabmap-info: show descriptor dimension and type.
This commit is contained in:
@@ -21,7 +21,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|||||||
#######################
|
#######################
|
||||||
SET(RTABMAP_MAJOR_VERSION 0)
|
SET(RTABMAP_MAJOR_VERSION 0)
|
||||||
SET(RTABMAP_MINOR_VERSION 20)
|
SET(RTABMAP_MINOR_VERSION 20)
|
||||||
SET(RTABMAP_PATCH_VERSION 5)
|
SET(RTABMAP_PATCH_VERSION 6)
|
||||||
SET(RTABMAP_VERSION
|
SET(RTABMAP_VERSION
|
||||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ typedef cv::gpu::FAST_GPU CV_FAST_GPU;
|
|||||||
namespace cv{
|
namespace cv{
|
||||||
namespace xfeatures2d {
|
namespace xfeatures2d {
|
||||||
class FREAK;
|
class FREAK;
|
||||||
|
class DAISY;
|
||||||
class BriefDescriptorExtractor;
|
class BriefDescriptorExtractor;
|
||||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
|
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
|
||||||
class SIFT;
|
class SIFT;
|
||||||
@@ -81,6 +82,7 @@ typedef cv::SIFT CV_SIFT; // SIFT is back in features2d since 4.4.0 / 3.4.11
|
|||||||
typedef cv::xfeatures2d::SURF CV_SURF;
|
typedef cv::xfeatures2d::SURF CV_SURF;
|
||||||
typedef cv::FastFeatureDetector CV_FAST;
|
typedef cv::FastFeatureDetector CV_FAST;
|
||||||
typedef cv::xfeatures2d::FREAK CV_FREAK;
|
typedef cv::xfeatures2d::FREAK CV_FREAK;
|
||||||
|
typedef cv::xfeatures2d::DAISY CV_DAISY;
|
||||||
typedef cv::GFTTDetector CV_GFTT;
|
typedef cv::GFTTDetector CV_GFTT;
|
||||||
typedef cv::xfeatures2d::BriefDescriptorExtractor CV_BRIEF;
|
typedef cv::xfeatures2d::BriefDescriptorExtractor CV_BRIEF;
|
||||||
typedef cv::BRISK CV_BRISK;
|
typedef cv::BRISK CV_BRISK;
|
||||||
@@ -116,7 +118,10 @@ public:
|
|||||||
kFeatureKaze=9, //new 0.13.2
|
kFeatureKaze=9, //new 0.13.2
|
||||||
kFeatureOrbOctree=10, //new 0.19.2
|
kFeatureOrbOctree=10, //new 0.19.2
|
||||||
kFeatureSuperPointTorch=11, //new 0.19.7
|
kFeatureSuperPointTorch=11, //new 0.19.7
|
||||||
kFeatureSurfFreak=12}; //new 0.20.4
|
kFeatureSurfFreak=12, //new 0.20.4
|
||||||
|
kFeatureGfttDaisy=13, //new 0.20.6
|
||||||
|
kFeatureSurfDaisy=14}; //new 0.20.6
|
||||||
|
|
||||||
static std::string typeName(Type type)
|
static std::string typeName(Type type)
|
||||||
{
|
{
|
||||||
switch(type){
|
switch(type){
|
||||||
@@ -146,6 +151,10 @@ public:
|
|||||||
return "SUPERPOINT";
|
return "SUPERPOINT";
|
||||||
case kFeatureSurfFreak:
|
case kFeatureSurfFreak:
|
||||||
return "SURF+Freak";
|
return "SURF+Freak";
|
||||||
|
case kFeatureGfttDaisy:
|
||||||
|
return "GFTT+Daisy";
|
||||||
|
case kFeatureSurfDaisy:
|
||||||
|
return "SURF+Daisy";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
@@ -563,6 +572,8 @@ private:
|
|||||||
private:
|
private:
|
||||||
float scaleFactor_;
|
float scaleFactor_;
|
||||||
int nLevels_;
|
int nLevels_;
|
||||||
|
int patchSize_;
|
||||||
|
int edgeThreshold_;
|
||||||
int fastThreshold_;
|
int fastThreshold_;
|
||||||
int fastMinThreshold_;
|
int fastMinThreshold_;
|
||||||
|
|
||||||
@@ -593,6 +604,54 @@ private:
|
|||||||
bool cuda_;
|
bool cuda_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//GFTT_DAISY
|
||||||
|
class RTABMAP_EXP GFTT_DAISY : public GFTT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GFTT_DAISY(const ParametersMap & parameters = ParametersMap());
|
||||||
|
virtual ~GFTT_DAISY();
|
||||||
|
|
||||||
|
virtual void parseParameters(const ParametersMap & parameters);
|
||||||
|
virtual Feature2D::Type getType() const {return kFeatureGfttDaisy;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual cv::Mat generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool orientationNormalized_;
|
||||||
|
bool scaleNormalized_;
|
||||||
|
float patternScale_;
|
||||||
|
int nOctaves_;
|
||||||
|
|
||||||
|
#if CV_MAJOR_VERSION > 2
|
||||||
|
cv::Ptr<CV_DAISY> _daisy;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
//SURF_DAISY
|
||||||
|
class RTABMAP_EXP SURF_DAISY : public SURF
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SURF_DAISY(const ParametersMap & parameters = ParametersMap());
|
||||||
|
virtual ~SURF_DAISY();
|
||||||
|
|
||||||
|
virtual void parseParameters(const ParametersMap & parameters);
|
||||||
|
virtual Feature2D::Type getType() const {return kFeatureSurfDaisy;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual cv::Mat generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool orientationNormalized_;
|
||||||
|
bool scaleNormalized_;
|
||||||
|
float patternScale_;
|
||||||
|
int nOctaves_;
|
||||||
|
|
||||||
|
#if CV_MAJOR_VERSION > 2
|
||||||
|
cv::Ptr<CV_DAISY> _daisy;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* FEATURES2D_H_ */
|
#endif /* FEATURES2D_H_ */
|
||||||
|
|||||||
@@ -244,9 +244,9 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
||||||
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
||||||
// OpenCV>2 without xFeatures2D module doesn't have BRIEF
|
// OpenCV>2 without xFeatures2D module doesn't have BRIEF
|
||||||
RTABMAP_PARAM(Kp, DetectorStrategy, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint Torch 12=SURF/FREAK.");
|
RTABMAP_PARAM(Kp, DetectorStrategy, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY");
|
||||||
#else
|
#else
|
||||||
RTABMAP_PARAM(Kp, DetectorStrategy, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint Torch 12=SURF/FREAK.");
|
RTABMAP_PARAM(Kp, DetectorStrategy, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY");
|
||||||
#endif
|
#endif
|
||||||
RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood.");
|
RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood.");
|
||||||
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
|
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
|
||||||
@@ -300,9 +300,9 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, "");
|
RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, "");
|
||||||
RTABMAP_PARAM(GFTT, K, double, 0.04, "");
|
RTABMAP_PARAM(GFTT, K, double, 0.04, "");
|
||||||
|
|
||||||
RTABMAP_PARAM(ORB, ScaleFactor, float, 1.2, "Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer.");
|
RTABMAP_PARAM(ORB, ScaleFactor, float, 2, "Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer.");
|
||||||
RTABMAP_PARAM(ORB, NLevels, int, 8, "The number of pyramid levels. The smallest level will have linear size equal to input_image_linear_size/pow(scaleFactor, nlevels).");
|
RTABMAP_PARAM(ORB, NLevels, int, 3, "The number of pyramid levels. The smallest level will have linear size equal to input_image_linear_size/pow(scaleFactor, nlevels).");
|
||||||
RTABMAP_PARAM(ORB, EdgeThreshold, int, 31, "This is size of the border where the features are not detected. It should roughly match the patchSize parameter.");
|
RTABMAP_PARAM(ORB, EdgeThreshold, int, 19, "This is size of the border where the features are not detected. It should roughly match the patchSize parameter.");
|
||||||
RTABMAP_PARAM(ORB, FirstLevel, int, 0, "It should be 0 in the current implementation.");
|
RTABMAP_PARAM(ORB, FirstLevel, int, 0, "It should be 0 in the current implementation.");
|
||||||
RTABMAP_PARAM(ORB, WTA_K, int, 2, "The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 random points (of course, those point coordinates are random, but they are generated from the pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3).");
|
RTABMAP_PARAM(ORB, WTA_K, int, 2, "The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 random points (of course, those point coordinates are random, but they are generated from the pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3).");
|
||||||
RTABMAP_PARAM(ORB, ScoreType, int, 0, "The default HARRIS_SCORE=0 means that Harris algorithm is used to rank features (the score is written to KeyPoint::score and is used to retain best nfeatures features); FAST_SCORE=1 is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute.");
|
RTABMAP_PARAM(ORB, ScoreType, int, 0, "The default HARRIS_SCORE=0 means that Harris algorithm is used to rank features (the score is written to KeyPoint::score and is used to retain best nfeatures features); FAST_SCORE=1 is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute.");
|
||||||
@@ -587,9 +587,9 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Vis, Iterations, int, 300, "Maximum iterations to compute the transform.");
|
RTABMAP_PARAM(Vis, Iterations, int, 300, "Maximum iterations to compute the transform.");
|
||||||
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
|
||||||
// OpenCV>2 without xFeatures2D module doesn't have BRIEF
|
// OpenCV>2 without xFeatures2D module doesn't have BRIEF
|
||||||
RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint Torch 12=SURF/FREAK.");
|
RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY");
|
||||||
#else
|
#else
|
||||||
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint Torch 12=SURF/FREAK.");
|
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY");
|
||||||
#endif
|
#endif
|
||||||
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
||||||
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
||||||
@@ -603,7 +603,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Vis, GridCols, int, 1, uFormat("Number of columns of the grid used to extract uniformly \"%s / grid cells\" features from each cell.", kVisMaxFeatures().c_str()));
|
RTABMAP_PARAM(Vis, GridCols, int, 1, uFormat("Number of columns of the grid used to extract uniformly \"%s / grid cells\" features from each cell.", kVisMaxFeatures().c_str()));
|
||||||
RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow");
|
RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow");
|
||||||
RTABMAP_PARAM(Vis, CorNNType, int, 1, uFormat("[%s=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4, BruteForceCrossCheck=5, SuperGlue=6, GMS=7. Used for features matching approach.", kVisCorType().c_str()));
|
RTABMAP_PARAM(Vis, CorNNType, int, 1, uFormat("[%s=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4, BruteForceCrossCheck=5, SuperGlue=6, GMS=7. Used for features matching approach.", kVisCorType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, CorNNDR, float, 0.6, uFormat("[%s=0] NNDR: nearest neighbor distance ratio. Used for knn features matching approach.", kVisCorType().c_str()));
|
RTABMAP_PARAM(Vis, CorNNDR, float, 0.8, uFormat("[%s=0] NNDR: nearest neighbor distance ratio. Used for knn features matching approach.", kVisCorType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, CorGuessWinSize, int, 20, uFormat("[%s=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled.", kVisCorType().c_str()));
|
RTABMAP_PARAM(Vis, CorGuessWinSize, int, 20, uFormat("[%s=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled.", kVisCorType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, CorGuessMatchToProjection, bool, false, uFormat("[%s=0] Match frame's corners to source's projected points (when guess transform is provided) instead of projected points to frame's corners.", kVisCorType().c_str()));
|
RTABMAP_PARAM(Vis, CorGuessMatchToProjection, bool, false, uFormat("[%s=0] Match frame's corners to source's projected points (when guess transform is provided) instead of projected points to frame's corners.", kVisCorType().c_str()));
|
||||||
RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
|
RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
|
||||||
|
|||||||
@@ -509,55 +509,69 @@ Feature2D * Feature2D::create(const ParametersMap & parameters)
|
|||||||
Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parameters)
|
Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parameters)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// NONFREE checks
|
||||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
|
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
|
||||||
#ifndef RTABMAP_NONFREE
|
|
||||||
if(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSift || type == Feature2D::kFeatureSurfFreak)
|
#ifndef RTABMAP_NONFREE
|
||||||
|
if(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSift || type == Feature2D::kFeatureSurfFreak || type == Feature2D::kFeatureSurfDaisy)
|
||||||
{
|
{
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if CV_MAJOR_VERSION < 3
|
||||||
UWARN("SURF and SIFT features cannot be used because OpenCV was not built with nonfree module. GFTT/ORB is used instead.");
|
UWARN("SURF and SIFT features cannot be used because OpenCV was not built with nonfree module. GFTT/ORB is used instead.");
|
||||||
#else
|
#else
|
||||||
UWARN("SURF and SIFT features cannot be used because OpenCV was not built with xfeatures2d module. GFTT/ORB is used instead.");
|
UWARN("SURF and SIFT features cannot be used because OpenCV was not built with xfeatures2d module. GFTT/ORB is used instead.");
|
||||||
#endif
|
#endif
|
||||||
type = Feature2D::kFeatureGfttOrb;
|
type = Feature2D::kFeatureGfttOrb;
|
||||||
}
|
}
|
||||||
#if CV_MAJOR_VERSION == 3
|
#endif
|
||||||
if(type == Feature2D::kFeatureFastBrief ||
|
|
||||||
type == Feature2D::kFeatureFastFreak ||
|
|
||||||
type == Feature2D::kFeatureGfttBrief ||
|
|
||||||
type == Feature2D::kFeatureGfttFreak ||
|
|
||||||
type == Feature2D::kFeatureSurfFreak)
|
|
||||||
{
|
|
||||||
UWARN("BRIEF and FREAK features cannot be used because OpenCV was not built with xfeatures2d module. GFTT/ORB is used instead.");
|
|
||||||
type = Feature2D::kFeatureGfttOrb;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // >= 4.4.0 >= 3.4.11
|
#else // >= 4.4.0 >= 3.4.11
|
||||||
|
|
||||||
#ifndef RTABMAP_NONFREE
|
#ifndef RTABMAP_NONFREE
|
||||||
if(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSurfFreak)
|
if(type == Feature2D::kFeatureSurf)
|
||||||
{
|
{
|
||||||
UWARN("SURF features cannot be used because OpenCV was not built with nonfree module. SIFT is used instead.");
|
UWARN("SURF features cannot be used because OpenCV was not built with nonfree module. SIFT is used instead.");
|
||||||
type = Feature2D::kFeatureSift;
|
type = Feature2D::kFeatureSift;
|
||||||
}
|
}
|
||||||
#endif
|
else if(type == Feature2D::kFeatureSurfFreak || type == Feature2D::kFeatureSurfDaisy)
|
||||||
|
{
|
||||||
|
UWARN("SURF detector cannot be used because OpenCV was not built with nonfree module. GFTT/ORB is used instead.");
|
||||||
|
type = Feature2D::kFeatureGfttOrb;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // >= 4.4.0 >= 3.4.11
|
#endif // >= 4.4.0 >= 3.4.11
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if !defined(HAVE_OPENCV_XFEATURES2D) && CV_MAJOR_VERSION >= 3
|
||||||
|
if(type == Feature2D::kFeatureFastBrief ||
|
||||||
|
type == Feature2D::kFeatureFastFreak ||
|
||||||
|
type == Feature2D::kFeatureGfttBrief ||
|
||||||
|
type == Feature2D::kFeatureGfttFreak ||
|
||||||
|
type == Feature2D::kFeatureSurfFreak ||
|
||||||
|
type == Feature2D::kFeatureGfttDaisy ||
|
||||||
|
type == Feature2D::kFeatureSurfDaisy)
|
||||||
|
{
|
||||||
|
UWARN("BRIEF, FREAK and DAISY features cannot be used because OpenCV was not built with xfeatures2d module. GFTT/ORB is used instead.");
|
||||||
|
type = Feature2D::kFeatureGfttOrb;
|
||||||
|
}
|
||||||
|
#elif CV_MAJOR_VERSION < 3
|
||||||
if(type == Feature2D::kFeatureKaze)
|
if(type == Feature2D::kFeatureKaze)
|
||||||
{
|
{
|
||||||
#ifdef RTABMAP_NONFREE
|
#ifdef RTABMAP_NONFREE
|
||||||
UWARN("KAZE detector/descriptor can be used only with OpenCV3. SURF is used instead.");
|
UWARN("KAZE detector/descriptor can be used only with OpenCV3. SURF is used instead.");
|
||||||
type = Feature2D::kFeatureSurf;
|
type = Feature2D::kFeatureSurf;
|
||||||
#else
|
#else
|
||||||
UWARN("KAZE detector/descriptor can be used only with OpenCV3. GFTT/ORB is used instead.");
|
UWARN("KAZE detector/descriptor can be used only with OpenCV3. GFTT/ORB is used instead.");
|
||||||
type = Feature2D::kFeatureGfttOrb;
|
type = Feature2D::kFeatureGfttOrb;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
if(type == Feature2D::kFeatureGfttDaisy || type == Feature2D::kFeatureSurfDaisy)
|
||||||
|
{
|
||||||
|
UWARN("DAISY detector/descriptor can be used only with OpenCV3. GFTT/BRIEF is used instead.");
|
||||||
|
type = Feature2D::kFeatureGfttBrief;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef RTABMAP_ORB_OCTREE
|
#ifndef RTABMAP_ORB_OCTREE
|
||||||
if(type == Feature2D::kFeatureOrbOctree)
|
if(type == Feature2D::kFeatureOrbOctree)
|
||||||
{
|
{
|
||||||
@@ -618,6 +632,12 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
|||||||
case Feature2D::kFeatureSurfFreak:
|
case Feature2D::kFeatureSurfFreak:
|
||||||
feature2D = new SURF_FREAK(parameters);
|
feature2D = new SURF_FREAK(parameters);
|
||||||
break;
|
break;
|
||||||
|
case Feature2D::kFeatureGfttDaisy:
|
||||||
|
feature2D = new GFTT_DAISY(parameters);
|
||||||
|
break;
|
||||||
|
case Feature2D::kFeatureSurfDaisy:
|
||||||
|
feature2D = new SURF_DAISY(parameters);
|
||||||
|
break;
|
||||||
#ifdef RTABMAP_NONFREE
|
#ifdef RTABMAP_NONFREE
|
||||||
default:
|
default:
|
||||||
feature2D = new SURF(parameters);
|
feature2D = new SURF(parameters);
|
||||||
@@ -626,7 +646,7 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
|||||||
#else
|
#else
|
||||||
default:
|
default:
|
||||||
feature2D = new ORB(parameters);
|
feature2D = new ORB(parameters);
|
||||||
type = Feature2D::kFeatureOrb;
|
type = Feature2D::kFeatureGfttOrb;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1939,7 +1959,10 @@ cv::Mat KAZE::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
|
|||||||
ORBOctree::ORBOctree(const ParametersMap & parameters) :
|
ORBOctree::ORBOctree(const ParametersMap & parameters) :
|
||||||
scaleFactor_(Parameters::defaultORBScaleFactor()),
|
scaleFactor_(Parameters::defaultORBScaleFactor()),
|
||||||
nLevels_(Parameters::defaultORBNLevels()),
|
nLevels_(Parameters::defaultORBNLevels()),
|
||||||
fastThreshold_(Parameters::defaultFASTThreshold())
|
patchSize_(Parameters::defaultORBPatchSize()),
|
||||||
|
edgeThreshold_(Parameters::defaultORBEdgeThreshold()),
|
||||||
|
fastThreshold_(Parameters::defaultFASTThreshold()),
|
||||||
|
fastMinThreshold_(Parameters::defaultFASTMinThreshold())
|
||||||
{
|
{
|
||||||
parseParameters(parameters);
|
parseParameters(parameters);
|
||||||
}
|
}
|
||||||
@@ -1954,12 +1977,14 @@ void ORBOctree::parseParameters(const ParametersMap & parameters)
|
|||||||
|
|
||||||
Parameters::parse(parameters, Parameters::kORBScaleFactor(), scaleFactor_);
|
Parameters::parse(parameters, Parameters::kORBScaleFactor(), scaleFactor_);
|
||||||
Parameters::parse(parameters, Parameters::kORBNLevels(), nLevels_);
|
Parameters::parse(parameters, Parameters::kORBNLevels(), nLevels_);
|
||||||
|
Parameters::parse(parameters, Parameters::kORBPatchSize(), patchSize_);
|
||||||
|
Parameters::parse(parameters, Parameters::kORBEdgeThreshold(), edgeThreshold_);
|
||||||
|
|
||||||
Parameters::parse(parameters, Parameters::kFASTThreshold(), fastThreshold_);
|
Parameters::parse(parameters, Parameters::kFASTThreshold(), fastThreshold_);
|
||||||
Parameters::parse(parameters, Parameters::kFASTMinThreshold(), fastMinThreshold_);
|
Parameters::parse(parameters, Parameters::kFASTMinThreshold(), fastMinThreshold_);
|
||||||
|
|
||||||
#ifdef RTABMAP_ORB_OCTREE
|
#ifdef RTABMAP_ORB_OCTREE
|
||||||
_orb = cv::Ptr<ORBextractor>(new ORBextractor(this->getMaxFeatures(), scaleFactor_, nLevels_, fastThreshold_, fastMinThreshold_));
|
_orb = cv::Ptr<ORBextractor>(new ORBextractor(this->getMaxFeatures(), scaleFactor_, nLevels_, fastThreshold_, fastMinThreshold_, patchSize_, edgeThreshold_));
|
||||||
#else
|
#else
|
||||||
UWARN("RTAB-Map is not built with ORB OcTree option enabled so ORB OcTree feature cannot be used!");
|
UWARN("RTAB-Map is not built with ORB OcTree option enabled so ORB OcTree feature cannot be used!");
|
||||||
#endif
|
#endif
|
||||||
@@ -2070,4 +2095,103 @@ cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vec
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
//GFTT-DAISY
|
||||||
|
//////////////////////////
|
||||||
|
GFTT_DAISY::GFTT_DAISY(const ParametersMap & parameters) :
|
||||||
|
GFTT(parameters),
|
||||||
|
orientationNormalized_(Parameters::defaultFREAKOrientationNormalized()),
|
||||||
|
scaleNormalized_(Parameters::defaultFREAKScaleNormalized()),
|
||||||
|
patternScale_(Parameters::defaultFREAKPatternScale()),
|
||||||
|
nOctaves_(Parameters::defaultFREAKNOctaves())
|
||||||
|
{
|
||||||
|
parseParameters(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
GFTT_DAISY::~GFTT_DAISY()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GFTT_DAISY::parseParameters(const ParametersMap & parameters)
|
||||||
|
{
|
||||||
|
GFTT::parseParameters(parameters);
|
||||||
|
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKOrientationNormalized(), orientationNormalized_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKScaleNormalized(), scaleNormalized_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKPatternScale(), patternScale_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKNOctaves(), nOctaves_);
|
||||||
|
|
||||||
|
#if CV_MAJOR_VERSION < 3
|
||||||
|
_daisy = cv::Ptr<CV_DAISY>(new CV_DAISY());
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||||
|
_daisy = CV_DAISY::create();
|
||||||
|
#else
|
||||||
|
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so DAISY cannot be used!");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat GFTT_DAISY::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
|
||||||
|
{
|
||||||
|
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||||
|
cv::Mat descriptors;
|
||||||
|
#if CV_MAJOR_VERSION < 3
|
||||||
|
_daisy->compute(image, keypoints, descriptors);
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||||
|
_daisy->compute(image, keypoints, descriptors);
|
||||||
|
#else
|
||||||
|
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so DAISY cannot be used!");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
//SURF-DAISY
|
||||||
|
//////////////////////////
|
||||||
|
SURF_DAISY::SURF_DAISY(const ParametersMap & parameters) :
|
||||||
|
SURF(parameters),
|
||||||
|
orientationNormalized_(Parameters::defaultFREAKOrientationNormalized()),
|
||||||
|
scaleNormalized_(Parameters::defaultFREAKScaleNormalized()),
|
||||||
|
patternScale_(Parameters::defaultFREAKPatternScale()),
|
||||||
|
nOctaves_(Parameters::defaultFREAKNOctaves())
|
||||||
|
{
|
||||||
|
parseParameters(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
SURF_DAISY::~SURF_DAISY()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SURF_DAISY::parseParameters(const ParametersMap & parameters)
|
||||||
|
{
|
||||||
|
SURF::parseParameters(parameters);
|
||||||
|
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKOrientationNormalized(), orientationNormalized_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKScaleNormalized(), scaleNormalized_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKPatternScale(), patternScale_);
|
||||||
|
Parameters::parse(parameters, Parameters::kFREAKNOctaves(), nOctaves_);
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||||
|
_daisy = CV_DAISY::create();
|
||||||
|
#else
|
||||||
|
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so DAISY cannot be used!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat SURF_DAISY::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
|
||||||
|
{
|
||||||
|
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||||
|
cv::Mat descriptors;
|
||||||
|
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||||
|
_daisy->compute(image, keypoints, descriptors);
|
||||||
|
#else
|
||||||
|
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so DAISY cannot be used!");
|
||||||
|
#endif
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,24 +80,19 @@ using namespace std;
|
|||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
{
|
{
|
||||||
|
|
||||||
const int PATCH_SIZE = 31;
|
static float IC_Angle(const Mat& image, Point2f pt, const vector<int> & u_max, int halfPatchSize)
|
||||||
const int HALF_PATCH_SIZE = 15;
|
|
||||||
const int EDGE_THRESHOLD = 19;
|
|
||||||
|
|
||||||
|
|
||||||
static float IC_Angle(const Mat& image, Point2f pt, const vector<int> & u_max)
|
|
||||||
{
|
{
|
||||||
int m_01 = 0, m_10 = 0;
|
int m_01 = 0, m_10 = 0;
|
||||||
|
|
||||||
const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
|
const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
|
||||||
|
|
||||||
// Treat the center line differently, v=0
|
// Treat the center line differently, v=0
|
||||||
for (int u = -HALF_PATCH_SIZE; u <= HALF_PATCH_SIZE; ++u)
|
for (int u = -halfPatchSize; u <= halfPatchSize; ++u)
|
||||||
m_10 += u * center[u];
|
m_10 += u * center[u];
|
||||||
|
|
||||||
// Go line by line in the circuI853lar patch
|
// Go line by line in the circuI853lar patch
|
||||||
int step = (int)image.step1();
|
int step = (int)image.step1();
|
||||||
for (int v = 1; v <= HALF_PATCH_SIZE; ++v)
|
for (int v = 1; v <= halfPatchSize; ++v)
|
||||||
{
|
{
|
||||||
// Proceed over the two lines
|
// Proceed over the two lines
|
||||||
int v_sum = 0;
|
int v_sum = 0;
|
||||||
@@ -419,10 +414,11 @@ static int bit_pattern_31_[256*4] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
|
ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
|
||||||
int _iniThFAST, int _minThFAST):
|
int _iniThFAST, int _minThFAST, int _patchSize, int _edgeThreshold):
|
||||||
nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
|
nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
|
||||||
iniThFAST(_iniThFAST), minThFAST(_minThFAST)
|
iniThFAST(_iniThFAST), minThFAST(_minThFAST), patchSize(_patchSize), edgeThreshold(_edgeThreshold)
|
||||||
{
|
{
|
||||||
|
halfPatchSize = patchSize/2;
|
||||||
mvScaleFactor.resize(nlevels);
|
mvScaleFactor.resize(nlevels);
|
||||||
mvLevelSigma2.resize(nlevels);
|
mvLevelSigma2.resize(nlevels);
|
||||||
mvScaleFactor[0]=1.0f;
|
mvScaleFactor[0]=1.0f;
|
||||||
@@ -462,16 +458,16 @@ ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
|
|||||||
|
|
||||||
//This is for orientation
|
//This is for orientation
|
||||||
// pre-compute the end of a row in a circular patch
|
// pre-compute the end of a row in a circular patch
|
||||||
umax.resize(HALF_PATCH_SIZE + 1);
|
umax.resize(halfPatchSize + 1);
|
||||||
|
|
||||||
int v, v0, vmax = cvFloor(HALF_PATCH_SIZE * sqrt(2.f) / 2 + 1);
|
int v, v0, vmax = cvFloor(float(halfPatchSize) * sqrt(2.f) / 2 + 1);
|
||||||
int vmin = cvCeil(HALF_PATCH_SIZE * sqrt(2.f) / 2);
|
int vmin = cvCeil(float(halfPatchSize) * sqrt(2.f) / 2);
|
||||||
const double hp2 = HALF_PATCH_SIZE*HALF_PATCH_SIZE;
|
const double hp2 = halfPatchSize*halfPatchSize;
|
||||||
for (v = 0; v <= vmax; ++v)
|
for (v = 0; v <= vmax; ++v)
|
||||||
umax[v] = cvRound(sqrt(hp2 - v * v));
|
umax[v] = cvRound(sqrt(hp2 - v * v));
|
||||||
|
|
||||||
// Make sure we are symmetric
|
// Make sure we are symmetric
|
||||||
for (v = HALF_PATCH_SIZE, v0 = 0; v >= vmin; --v)
|
for (v = halfPatchSize, v0 = 0; v >= vmin; --v)
|
||||||
{
|
{
|
||||||
while (umax[v0] == umax[v0 + 1])
|
while (umax[v0] == umax[v0 + 1])
|
||||||
++v0;
|
++v0;
|
||||||
@@ -480,12 +476,12 @@ ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void computeOrientation(const Mat& image, vector<KeyPoint>& keypoints, const vector<int>& umax)
|
static void computeOrientation(const Mat& image, vector<KeyPoint>& keypoints, const vector<int>& umax, int halfPatchSize)
|
||||||
{
|
{
|
||||||
for (vector<KeyPoint>::iterator keypoint = keypoints.begin(),
|
for (vector<KeyPoint>::iterator keypoint = keypoints.begin(),
|
||||||
keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
|
keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
|
||||||
{
|
{
|
||||||
keypoint->angle = IC_Angle(image, keypoint->pt, umax);
|
keypoint->angle = IC_Angle(image, keypoint->pt, umax, halfPatchSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,10 +777,10 @@ void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoin
|
|||||||
|
|
||||||
for (int level = 0; level < nlevels; ++level)
|
for (int level = 0; level < nlevels; ++level)
|
||||||
{
|
{
|
||||||
const int minBorderX = EDGE_THRESHOLD-3;
|
const int minBorderX = edgeThreshold-3;
|
||||||
const int minBorderY = minBorderX;
|
const int minBorderY = minBorderX;
|
||||||
const int maxBorderX = mvImagePyramid[level].cols-EDGE_THRESHOLD+3;
|
const int maxBorderX = mvImagePyramid[level].cols-edgeThreshold+3;
|
||||||
const int maxBorderY = mvImagePyramid[level].rows-EDGE_THRESHOLD+3;
|
const int maxBorderY = mvImagePyramid[level].rows-edgeThreshold+3;
|
||||||
|
|
||||||
vector<cv::KeyPoint> vToDistributeKeys;
|
vector<cv::KeyPoint> vToDistributeKeys;
|
||||||
vToDistributeKeys.reserve(nfeatures*10);
|
vToDistributeKeys.reserve(nfeatures*10);
|
||||||
@@ -845,7 +841,7 @@ void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoin
|
|||||||
keypoints = DistributeOctTree(vToDistributeKeys, minBorderX, maxBorderX,
|
keypoints = DistributeOctTree(vToDistributeKeys, minBorderX, maxBorderX,
|
||||||
minBorderY, maxBorderY,mnFeaturesPerLevel[level], level);
|
minBorderY, maxBorderY,mnFeaturesPerLevel[level], level);
|
||||||
|
|
||||||
const int scaledPatchSize = PATCH_SIZE*mvScaleFactor[level];
|
const int scaledPatchSize = patchSize*mvScaleFactor[level];
|
||||||
|
|
||||||
// Add border to coordinates and scale information
|
// Add border to coordinates and scale information
|
||||||
const int nkps = keypoints.size();
|
const int nkps = keypoints.size();
|
||||||
@@ -860,7 +856,7 @@ void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoin
|
|||||||
|
|
||||||
// compute orientations
|
// compute orientations
|
||||||
for (int level = 0; level < nlevels; ++level)
|
for (int level = 0; level < nlevels; ++level)
|
||||||
computeOrientation(mvImagePyramid[level], allKeypoints[level], umax);
|
computeOrientation(mvImagePyramid[level], allKeypoints[level], umax, halfPatchSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allKeypoints)
|
void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allKeypoints)
|
||||||
@@ -876,10 +872,10 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
|||||||
const int levelCols = sqrt((float)nDesiredFeatures/(5*imageRatio));
|
const int levelCols = sqrt((float)nDesiredFeatures/(5*imageRatio));
|
||||||
const int levelRows = imageRatio*levelCols;
|
const int levelRows = imageRatio*levelCols;
|
||||||
|
|
||||||
const int minBorderX = EDGE_THRESHOLD;
|
const int minBorderX = edgeThreshold;
|
||||||
const int minBorderY = minBorderX;
|
const int minBorderY = minBorderX;
|
||||||
const int maxBorderX = mvImagePyramid[level].cols-EDGE_THRESHOLD;
|
const int maxBorderX = mvImagePyramid[level].cols-edgeThreshold;
|
||||||
const int maxBorderY = mvImagePyramid[level].rows-EDGE_THRESHOLD;
|
const int maxBorderY = mvImagePyramid[level].rows-edgeThreshold;
|
||||||
|
|
||||||
const int W = maxBorderX - minBorderX;
|
const int W = maxBorderX - minBorderX;
|
||||||
const int H = maxBorderY - minBorderY;
|
const int H = maxBorderY - minBorderY;
|
||||||
@@ -1006,7 +1002,7 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
|||||||
vector<KeyPoint> & keypoints = allKeypoints[level];
|
vector<KeyPoint> & keypoints = allKeypoints[level];
|
||||||
keypoints.reserve(nDesiredFeatures*2);
|
keypoints.reserve(nDesiredFeatures*2);
|
||||||
|
|
||||||
const int scaledPatchSize = PATCH_SIZE*mvScaleFactor[level];
|
const int scaledPatchSize = patchSize*mvScaleFactor[level];
|
||||||
|
|
||||||
// Retain by score and transform coordinates
|
// Retain by score and transform coordinates
|
||||||
for(int i=0; i<levelRows; i++)
|
for(int i=0; i<levelRows; i++)
|
||||||
@@ -1039,7 +1035,7 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
|||||||
|
|
||||||
// and compute orientations
|
// and compute orientations
|
||||||
for (int level = 0; level < nlevels; ++level)
|
for (int level = 0; level < nlevels; ++level)
|
||||||
computeOrientation(mvImagePyramid[level], allKeypoints[level], umax);
|
computeOrientation(mvImagePyramid[level], allKeypoints[level], umax, halfPatchSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void computeDescriptors(const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors,
|
static void computeDescriptors(const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors,
|
||||||
@@ -1121,21 +1117,21 @@ void ORBextractor::ComputePyramid(cv::Mat image)
|
|||||||
{
|
{
|
||||||
float scale = mvInvScaleFactor[level];
|
float scale = mvInvScaleFactor[level];
|
||||||
Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
|
Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
|
||||||
Size wholeSize(sz.width + EDGE_THRESHOLD*2, sz.height + EDGE_THRESHOLD*2);
|
Size wholeSize(sz.width + edgeThreshold*2, sz.height + edgeThreshold*2);
|
||||||
Mat temp(wholeSize, image.type()), masktemp;
|
Mat temp(wholeSize, image.type()), masktemp;
|
||||||
mvImagePyramid[level] = temp(Rect(EDGE_THRESHOLD, EDGE_THRESHOLD, sz.width, sz.height));
|
mvImagePyramid[level] = temp(Rect(edgeThreshold, edgeThreshold, sz.width, sz.height));
|
||||||
|
|
||||||
// Compute the resized image
|
// Compute the resized image
|
||||||
if( level != 0 )
|
if( level != 0 )
|
||||||
{
|
{
|
||||||
resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);
|
resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);
|
||||||
|
|
||||||
copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
|
copyMakeBorder(mvImagePyramid[level], temp, edgeThreshold, edgeThreshold, edgeThreshold, edgeThreshold,
|
||||||
BORDER_REFLECT_101+BORDER_ISOLATED);
|
BORDER_REFLECT_101+BORDER_ISOLATED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
|
copyMakeBorder(image, temp, edgeThreshold, edgeThreshold, edgeThreshold, edgeThreshold,
|
||||||
BORDER_REFLECT_101);
|
BORDER_REFLECT_101);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
enum {HARRIS_SCORE=0, FAST_SCORE=1 };
|
enum {HARRIS_SCORE=0, FAST_SCORE=1 };
|
||||||
|
|
||||||
ORBextractor(int nfeatures, float scaleFactor, int nlevels,
|
ORBextractor(int nfeatures, float scaleFactor, int nlevels,
|
||||||
int iniThFAST, int minThFAST);
|
int iniThFAST, int minThFAST, int patchSize, int edgeThreshold);
|
||||||
|
|
||||||
~ORBextractor(){}
|
~ORBextractor(){}
|
||||||
|
|
||||||
@@ -107,6 +107,10 @@ protected:
|
|||||||
int nlevels;
|
int nlevels;
|
||||||
int iniThFAST;
|
int iniThFAST;
|
||||||
int minThFAST;
|
int minThFAST;
|
||||||
|
int patchSize;
|
||||||
|
int edgeThreshold;
|
||||||
|
int halfPatchSize;
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> mnFeaturesPerLevel;
|
std::vector<int> mnFeaturesPerLevel;
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ do
|
|||||||
--Mem/UseOdomFeatures false \
|
--Mem/UseOdomFeatures false \
|
||||||
--Mem/BinDataKept false \
|
--Mem/BinDataKept false \
|
||||||
--Rtabmap/CreateIntermediateNodes false\
|
--Rtabmap/CreateIntermediateNodes false\
|
||||||
|
--Vis/CorNNDR 0.6 \
|
||||||
$V203_params\
|
$V203_params\
|
||||||
$F2F_params\
|
$F2F_params\
|
||||||
--OdomORBSLAM2/VocPath /root/ORBvoc.txt\
|
--OdomORBSLAM2/VocPath /root/ORBvoc.txt\
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ do
|
|||||||
--Mem/STMSize 30\
|
--Mem/STMSize 30\
|
||||||
--Mem/UseOdomFeatures false \
|
--Mem/UseOdomFeatures false \
|
||||||
--Mem/BinDataKept false \
|
--Mem/BinDataKept false \
|
||||||
|
--Vis/CorNNDR 0.6 \
|
||||||
$SCAN \
|
$SCAN \
|
||||||
--gt $KITTI_ROOT_PATH"/devkit/cpp/data/odometry/poses/$d.txt"\
|
--gt $KITTI_ROOT_PATH"/devkit/cpp/data/odometry/poses/$d.txt"\
|
||||||
--output "$KITTI_RESULTS_PATH/$d"\
|
--output "$KITTI_RESULTS_PATH/$d"\
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ do
|
|||||||
--Mem/UseOdomFeatures false \
|
--Mem/UseOdomFeatures false \
|
||||||
--Mem/BinDataKept true \
|
--Mem/BinDataKept true \
|
||||||
--Rtabmap/CreateIntermediateNodes false\
|
--Rtabmap/CreateIntermediateNodes false\
|
||||||
|
--Vis/CorNNDR 0.6 \
|
||||||
$F2F_params\
|
$F2F_params\
|
||||||
--OdomORBSLAM2/VocPath /root/ORBvoc.txt\
|
--OdomORBSLAM2/VocPath /root/ORBvoc.txt\
|
||||||
--OdomFovis/MinFeaturesForEstimate 10\
|
--OdomFovis/MinFeaturesForEstimate 10\
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/gui/EditMapArea.h"
|
#include "rtabmap/gui/EditMapArea.h"
|
||||||
#include "rtabmap/core/SensorData.h"
|
#include "rtabmap/core/SensorData.h"
|
||||||
#include "rtabmap/core/GainCompensator.h"
|
#include "rtabmap/core/GainCompensator.h"
|
||||||
|
#include "rtabmap/core/VisualWord.h"
|
||||||
#include "rtabmap/gui/ExportDialog.h"
|
#include "rtabmap/gui/ExportDialog.h"
|
||||||
#include "rtabmap/gui/EditConstraintDialog.h"
|
#include "rtabmap/gui/EditConstraintDialog.h"
|
||||||
#include "rtabmap/gui/ProgressDialog.h"
|
#include "rtabmap/gui/ProgressDialog.h"
|
||||||
@@ -1999,8 +2000,28 @@ void DatabaseViewer::updateInfo()
|
|||||||
{
|
{
|
||||||
ui_->textEdit_info->append(tr("Total odometry length:\t%1 m").arg(infoTotalOdom_));
|
ui_->textEdit_info->append(tr("Total odometry length:\t%1 m").arg(infoTotalOdom_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lastWordIdId = 0;
|
||||||
|
int wordsDim = 0;
|
||||||
|
int wordsType = 0;
|
||||||
|
dbDriver_->getLastWordId(lastWordIdId);
|
||||||
|
if(lastWordIdId>0)
|
||||||
|
{
|
||||||
|
std::set<int> ids;
|
||||||
|
ids.insert(lastWordIdId);
|
||||||
|
std::list<VisualWord *> vws;
|
||||||
|
dbDriver_->loadWords(ids, vws);
|
||||||
|
if(!vws.empty())
|
||||||
|
{
|
||||||
|
wordsDim = vws.front()->getDescriptor().cols;
|
||||||
|
wordsType = vws.front()->getDescriptor().type();
|
||||||
|
delete vws.front();
|
||||||
|
vws.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui_->textEdit_info->append(tr("Total time:\t\t%1").arg(QDateTime::fromMSecsSinceEpoch(infoTotalTime_*1000).toUTC().toString("hh:mm:ss.zzz")));
|
ui_->textEdit_info->append(tr("Total time:\t\t%1").arg(QDateTime::fromMSecsSinceEpoch(infoTotalTime_*1000).toUTC().toString("hh:mm:ss.zzz")));
|
||||||
ui_->textEdit_info->append(tr("LTM:\t\t%1 nodes and %2 words").arg(ids_.size()).arg(dbDriver_->getTotalDictionarySize()));
|
ui_->textEdit_info->append(tr("LTM:\t\t%1 nodes and %2 words (dim=%3 type=%4)").arg(ids_.size()).arg(dbDriver_->getTotalDictionarySize()).arg(wordsDim).arg(wordsType==CV_8UC1?"8U":wordsType==CV_32FC1?"32F":uNumber2Str(wordsType).c_str()));
|
||||||
ui_->textEdit_info->append(tr("WM:\t\t%1 nodes and %2 words").arg(dbDriver_->getLastNodesSize()).arg(dbDriver_->getLastDictionarySize()));
|
ui_->textEdit_info->append(tr("WM:\t\t%1 nodes and %2 words").arg(dbDriver_->getLastNodesSize()).arg(dbDriver_->getLastDictionarySize()));
|
||||||
ui_->textEdit_info->append(tr("Global graph:\t%1 poses and %2 links").arg(odomPoses_.size()).arg(links_.size()));
|
ui_->textEdit_info->append(tr("Global graph:\t%1 poses and %2 links").arg(odomPoses_.size()).arg(links_.size()));
|
||||||
ui_->textEdit_info->append(tr("Ground truth:\t%1 poses").arg(groundTruthPoses_.size()));
|
ui_->textEdit_info->append(tr("Ground truth:\t%1 poses").arg(groundTruthPoses_.size()));
|
||||||
|
|||||||
@@ -195,8 +195,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
#ifndef RTABMAP_NONFREE
|
#ifndef RTABMAP_NONFREE
|
||||||
_ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1);
|
||||||
_ui->comboBox_detector_strategy->setItemData(12, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(12, 0, Qt::UserRole - 1);
|
||||||
|
_ui->comboBox_detector_strategy->setItemData(14, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(0, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(0, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(12, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(12, 0, Qt::UserRole - 1);
|
||||||
|
_ui->vis_feature_detector->setItemData(14, 0, Qt::UserRole - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SIFT
|
// SIFT
|
||||||
@@ -213,11 +215,15 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->comboBox_detector_strategy->setItemData(5, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(5, 0, Qt::UserRole - 1);
|
||||||
_ui->comboBox_detector_strategy->setItemData(6, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(6, 0, Qt::UserRole - 1);
|
||||||
_ui->comboBox_detector_strategy->setItemData(12, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(12, 0, Qt::UserRole - 1);
|
||||||
|
_ui->comboBox_detector_strategy->setItemData(13, 0, Qt::UserRole - 1);
|
||||||
|
_ui->comboBox_detector_strategy->setItemData(14, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(3, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(3, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(4, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(4, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(5, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(5, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(6, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(6, 0, Qt::UserRole - 1);
|
||||||
_ui->vis_feature_detector->setItemData(12, 0, Qt::UserRole - 1);
|
_ui->vis_feature_detector->setItemData(12, 0, Qt::UserRole - 1);
|
||||||
|
_ui->vis_feature_detector->setItemData(13, 0, Qt::UserRole - 1);
|
||||||
|
_ui->vis_feature_detector->setItemData(14, 0, Qt::UserRole - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RTABMAP_ORB_OCTREE
|
#ifndef RTABMAP_ORB_OCTREE
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-1179</y>
|
<y>-27</y>
|
||||||
<width>686</width>
|
<width>686</width>
|
||||||
<height>3236</height>
|
<height>3236</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>21</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||||
@@ -8969,6 +8969,16 @@ generate the number of words requested.</string>
|
|||||||
<string>SURF+FREAK</string>
|
<string>SURF+FREAK</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>GFTT+DAISY</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>SURF+DAISY</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="7" column="0">
|
||||||
@@ -18249,6 +18259,16 @@ Lower the ratio -> higher the precision.</string>
|
|||||||
<string>SURF+FREAK</string>
|
<string>SURF+FREAK</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>GFTT+DAISY</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>SURF+DAISY</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <rtabmap/core/DBDriver.h>
|
#include <rtabmap/core/DBDriver.h>
|
||||||
|
#include <rtabmap/core/VisualWord.h>
|
||||||
#include <rtabmap/utilite/UDirectory.h>
|
#include <rtabmap/utilite/UDirectory.h>
|
||||||
#include "rtabmap/utilite/UFile.h"
|
#include "rtabmap/utilite/UFile.h"
|
||||||
#include "rtabmap/utilite/UStl.h"
|
#include "rtabmap/utilite/UStl.h"
|
||||||
@@ -329,8 +330,27 @@ int main(int argc, char * argv[])
|
|||||||
sessionsInOptGraphStr << *iter << "(" << mapIdsLinkedToLastGraph.count(*iter) << ")";
|
sessionsInOptGraphStr << *iter << "(" << mapIdsLinkedToLastGraph.count(*iter) << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lastWordIdId = 0;
|
||||||
|
int wordsDim = 0;
|
||||||
|
int wordsType = 0;
|
||||||
|
driver->getLastWordId(lastWordIdId);
|
||||||
|
if(lastWordIdId>0)
|
||||||
|
{
|
||||||
|
std::set<int> ids;
|
||||||
|
ids.insert(lastWordIdId);
|
||||||
|
std::list<VisualWord *> vws;
|
||||||
|
driver->loadWords(ids, vws);
|
||||||
|
if(!vws.empty())
|
||||||
|
{
|
||||||
|
wordsDim = vws.front()->getDescriptor().cols;
|
||||||
|
wordsType = vws.front()->getDescriptor().type();
|
||||||
|
delete vws.front();
|
||||||
|
vws.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << (uFormat("%s%fs\n", pad("Total time:").c_str(), infoTotalTime));
|
std::cout << (uFormat("%s%fs\n", pad("Total time:").c_str(), infoTotalTime));
|
||||||
std::cout << (uFormat("%s%d nodes and %d words\n", pad("LTM:").c_str(), (int)ids.size(), driver->getTotalDictionarySize()));
|
std::cout << (uFormat("%s%d nodes and %d words (dim=%d type=%s)\n", pad("LTM:").c_str(), (int)ids.size(), driver->getTotalDictionarySize(), wordsDim, wordsType==CV_8UC1?"8U":wordsType==CV_32FC1?"32F":uNumber2Str(wordsType).c_str()));
|
||||||
std::cout << (uFormat("%s%d nodes and %d words\n", pad("WM:").c_str(), driver->getLastNodesSize(), driver->getLastDictionarySize()));
|
std::cout << (uFormat("%s%d nodes and %d words\n", pad("WM:").c_str(), driver->getLastNodesSize(), driver->getLastDictionarySize()));
|
||||||
std::cout << (uFormat("%s%d poses and %d links\n", pad("Global graph:").c_str(), odomPoses, links.size()));
|
std::cout << (uFormat("%s%d poses and %d links\n", pad("Global graph:").c_str(), odomPoses, links.size()));
|
||||||
std::cout << (uFormat("%s%d poses\n", pad("Optimized graph:").c_str(), (int)optimizedPoses.size(), links.size()));
|
std::cout << (uFormat("%s%d poses\n", pad("Optimized graph:").c_str(), (int)optimizedPoses.size(), links.size()));
|
||||||
|
|||||||
Reference in New Issue
Block a user