mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
If OpenCV nonfree module is not found, RTAB-Map will still build but with disabled SURF/SIFT options. Default BOW dictionary will be ORB in this case.
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@2071 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// default parameters
|
||||
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
|
||||
#include "rtabmap/core/Version.h" // DLL export/import defines
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
@@ -102,6 +103,37 @@ typedef std::pair<std::string, std::string> ParametersPair;
|
||||
Dummy##PREFIX##NAME dummy##PREFIX##NAME;
|
||||
// end define PARAM
|
||||
|
||||
/**
|
||||
* Macro used to create parameter's key and default value.
|
||||
* This macro must be used only in the Parameters class definition (in this file).
|
||||
* They are automatically added to the default parameters map of the class Parameters.
|
||||
* Example:
|
||||
* @code
|
||||
* //for PARAM(Video, ImageWidth, int, 640), the output will be :
|
||||
* public:
|
||||
* static std::string kVideoImageWidth() {return std::string("Video/ImageWidth");}
|
||||
* static int defaultVideoImageWidth() {return 640;}
|
||||
* private:
|
||||
* class DummyVideoImageWidth {
|
||||
* public:
|
||||
* DummyVideoImageWidth() {parameters_.insert(ParametersPair("Video/ImageWidth", "640"));}
|
||||
* };
|
||||
* DummyVideoImageWidth dummyVideoImageWidth;
|
||||
* @endcode
|
||||
*/
|
||||
#define RTABMAP_PARAM_COND(PREFIX, NAME, TYPE, COND, DEFAULT_VALUE1, DEFAULT_VALUE2, DESCRIPTION) \
|
||||
public: \
|
||||
static std::string k##PREFIX##NAME() {return std::string(#PREFIX "/" #NAME);} \
|
||||
static TYPE default##PREFIX##NAME() {return COND?DEFAULT_VALUE1:DEFAULT_VALUE2;} \
|
||||
private: \
|
||||
class Dummy##PREFIX##NAME { \
|
||||
public: \
|
||||
Dummy##PREFIX##NAME() {parameters_.insert(ParametersPair(#PREFIX "/" #NAME, COND?#DEFAULT_VALUE1:#DEFAULT_VALUE2)); \
|
||||
descriptions_.insert(ParametersPair(#PREFIX "/" #NAME, DESCRIPTION));} \
|
||||
}; \
|
||||
Dummy##PREFIX##NAME dummy##PREFIX##NAME;
|
||||
// end define PARAM
|
||||
|
||||
/**
|
||||
* Class Parameters.
|
||||
* This class is used to manage all custom parameters
|
||||
@@ -162,13 +194,13 @@ class RTABMAP_EXP Parameters
|
||||
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.")
|
||||
|
||||
// KeypointMemory (Keypoint-based)
|
||||
RTABMAP_PARAM(Kp, NNStrategy, int, 1, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4");
|
||||
RTABMAP_PARAM_COND(Kp, NNStrategy, int, RTABMAP_NONFREE, 1, 3, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4");
|
||||
RTABMAP_PARAM(Kp, IncrementalDictionary, bool, true, "");
|
||||
RTABMAP_PARAM(Kp, MaxDepth, float, 0.0, "Filter extracted keypoints by depth (0=inf)");
|
||||
RTABMAP_PARAM(Kp, WordsPerImage, int, 400, "");
|
||||
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.2, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
|
||||
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, DetectorStrategy, int, 0, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK.");
|
||||
RTABMAP_PARAM_COND(Kp, DetectorStrategy, int, RTABMAP_NONFREE, 0, 2, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK.");
|
||||
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_STR(Kp, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom].");
|
||||
@@ -210,14 +242,14 @@ class RTABMAP_EXP Parameters
|
||||
|
||||
RTABMAP_PARAM(GFTT, MaxCorners, int, 400, "");
|
||||
RTABMAP_PARAM(GFTT, QualityLevel, double, 0.01, "");
|
||||
RTABMAP_PARAM(GFTT, MinDistance, double, 1, "");
|
||||
RTABMAP_PARAM(GFTT, MinDistance, double, 5, "");
|
||||
RTABMAP_PARAM(GFTT, BlockSize, int, 3, "");
|
||||
RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, "");
|
||||
RTABMAP_PARAM(GFTT, K, double, 0.04, "");
|
||||
|
||||
RTABMAP_PARAM(ORB, NFeatures, int, 500, "The maximum number of features to retain.");
|
||||
RTABMAP_PARAM(ORB, NFeatures, int, 400, "The maximum number of features to retain.");
|
||||
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, 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, 1, "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, 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).");
|
||||
@@ -300,7 +332,7 @@ class RTABMAP_EXP Parameters
|
||||
RTABMAP_PARAM(LccBow, Iterations, int, 100, "Maximum iterations to compute the transform from visual words.");
|
||||
RTABMAP_PARAM(LccBow, MaxDepth, float, 4.0, "Max depth of the words (0 means no limit).");
|
||||
RTABMAP_PARAM(LccBow, Force2D, bool, false, "Force 2D transform (3Dof: x,y and yaw).");
|
||||
RTABMAP_PARAM(LccReextract, Activated, bool, false, "Activate re-extracting features on global loop closure.");
|
||||
RTABMAP_PARAM_COND(LccReextract, Activated, bool, RTABMAP_NONFREE, false, true, "Activate re-extracting features on global loop closure.");
|
||||
RTABMAP_PARAM(LccReextract, NNType, int, 3, "kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4.");
|
||||
RTABMAP_PARAM(LccReextract, NNDR, float, 0.7, "NNDR: nearest neighbor distance ratio.");
|
||||
RTABMAP_PARAM(LccReextract, FeatureType, int, 4, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK.");
|
||||
|
||||
@@ -196,7 +196,7 @@ cv::Mat CameraImages::captureImage()
|
||||
{
|
||||
ULOGGER_DEBUG("Loading image : %s", fullPath.c_str());
|
||||
|
||||
#if CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4
|
||||
#if CV_MAJOR_VERSION >2 || (CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4)
|
||||
img = cv::imread(fullPath.c_str(), cv::IMREAD_UNCHANGED);
|
||||
#else
|
||||
img = cv::imread(fullPath.c_str(), -1);
|
||||
|
||||
@@ -37,12 +37,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <opencv2/gpu/gpu.hpp>
|
||||
#include <opencv2/core/version.hpp>
|
||||
|
||||
#if CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4
|
||||
#ifdef WITH_NONFREE
|
||||
#if CV_MAJOR_VERSION > 2 || (CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4)
|
||||
#include <opencv2/nonfree/gpu.hpp>
|
||||
#include <opencv2/nonfree/features2d.hpp>
|
||||
#endif
|
||||
|
||||
#define OPENCV_SURF_GPU CV_MAJOR_VERSION >= 2 and CV_MINOR_VERSION >=2 and CV_SUBMINOR_VERSION>=1
|
||||
#endif
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -321,21 +321,30 @@ cv::Rect Feature2D::computeRoi(const cv::Mat & image, const std::vector<float> &
|
||||
/////////////////////
|
||||
Feature2D * Feature2D::create(Feature2D::Type & type, const ParametersMap & parameters)
|
||||
{
|
||||
if(RTABMAP_NONFREE == 0 &&
|
||||
(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSift))
|
||||
{
|
||||
UERROR("SURF/SIFT features cannot be used because OpenCV was not built with nonfree module. ORB is used instead.");
|
||||
type = Feature2D::kFeatureOrb;
|
||||
}
|
||||
Feature2D * feature2D = 0;
|
||||
switch(type)
|
||||
{
|
||||
case Feature2D::kFeatureSurf:
|
||||
feature2D = new SURF(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureSift:
|
||||
feature2D = new SIFT(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureOrb:
|
||||
feature2D = new ORB(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureFastBrief:
|
||||
feature2D = new FAST_BRIEF(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureFastFreak:
|
||||
feature2D = new FAST_FREAK(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureOrb:
|
||||
feature2D = new ORB(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureGfttFreak:
|
||||
feature2D = new GFTT_FREAK(parameters);
|
||||
break;
|
||||
@@ -345,11 +354,18 @@ Feature2D * Feature2D::create(Feature2D::Type & type, const ParametersMap & para
|
||||
case Feature2D::kFeatureBrisk:
|
||||
feature2D = new BRISK(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureSurf:
|
||||
#ifdef WITH_NONFREE
|
||||
default:
|
||||
feature2D = new SURF(parameters);
|
||||
type = Feature2D::kFeatureSurf;
|
||||
break;
|
||||
#else
|
||||
default:
|
||||
feature2D = new ORB(parameters);
|
||||
type = Feature2D::kFeatureOrb;
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
return feature2D;
|
||||
}
|
||||
@@ -417,6 +433,7 @@ SURF::SURF(const ParametersMap & parameters) :
|
||||
|
||||
SURF::~SURF()
|
||||
{
|
||||
#ifdef WITH_NONFREE
|
||||
if(_surf)
|
||||
{
|
||||
delete _surf;
|
||||
@@ -425,6 +442,7 @@ SURF::~SURF()
|
||||
{
|
||||
delete _gpuSurf;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SURF::parseParameters(const ParametersMap & parameters)
|
||||
@@ -437,6 +455,7 @@ void SURF::parseParameters(const ParametersMap & parameters)
|
||||
Parameters::parse(parameters, Parameters::kSURFGpuKeypointsRatio(), gpuKeypointsRatio_);
|
||||
Parameters::parse(parameters, Parameters::kSURFGpuVersion(), gpuVersion_);
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
if(_gpuSurf)
|
||||
{
|
||||
delete _gpuSurf;
|
||||
@@ -461,12 +480,17 @@ void SURF::parseParameters(const ParametersMap & parameters)
|
||||
|
||||
_surf = new cv::SURF(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, upright_);
|
||||
}
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<cv::KeyPoint> SURF::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi) const
|
||||
{
|
||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||
std::vector<cv::KeyPoint> keypoints;
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
cv::Mat imgRoi(image, roi);
|
||||
if(_gpuSurf)
|
||||
{
|
||||
@@ -477,7 +501,9 @@ std::vector<cv::KeyPoint> SURF::generateKeypointsImpl(const cv::Mat & image, con
|
||||
{
|
||||
_surf->detect(imgRoi, keypoints);
|
||||
}
|
||||
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
|
||||
#endif
|
||||
return keypoints;
|
||||
}
|
||||
|
||||
@@ -485,6 +511,7 @@ cv::Mat SURF::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
|
||||
{
|
||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||
cv::Mat descriptors;
|
||||
#ifdef WITH_NONFREE
|
||||
if(_gpuSurf)
|
||||
{
|
||||
cv::gpu::GpuMat imgGpu(image);
|
||||
@@ -505,6 +532,9 @@ cv::Mat SURF::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
|
||||
{
|
||||
_surf->compute(image, keypoints, descriptors);
|
||||
}
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
|
||||
#endif
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
@@ -525,10 +555,14 @@ SIFT::SIFT(const ParametersMap & parameters) :
|
||||
|
||||
SIFT::~SIFT()
|
||||
{
|
||||
#ifdef WITH_NONFREE
|
||||
if(_sift)
|
||||
{
|
||||
delete _sift;
|
||||
}
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void SIFT::parseParameters(const ParametersMap & parameters)
|
||||
@@ -539,6 +573,7 @@ void SIFT::parseParameters(const ParametersMap & parameters)
|
||||
Parameters::parse(parameters, Parameters::kSIFTNOctaveLayers(), nOctaveLayers_);
|
||||
Parameters::parse(parameters, Parameters::kSIFTSigma(), sigma_);
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
if(_sift)
|
||||
{
|
||||
delete _sift;
|
||||
@@ -546,14 +581,21 @@ void SIFT::parseParameters(const ParametersMap & parameters)
|
||||
}
|
||||
|
||||
_sift = new cv::SIFT(nfeatures_, nOctaveLayers_, contrastThreshold_, edgeThreshold_, sigma_);
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi) const
|
||||
{
|
||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||
std::vector<cv::KeyPoint> keypoints;
|
||||
#ifdef WITH_NONFREE
|
||||
cv::Mat imgRoi(image, roi);
|
||||
_sift->detect(imgRoi, keypoints); // Opencv keypoints
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
|
||||
#endif
|
||||
return keypoints;
|
||||
}
|
||||
|
||||
@@ -561,7 +603,11 @@ cv::Mat SIFT::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
|
||||
{
|
||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||
cv::Mat descriptors;
|
||||
#ifdef WITH_NONFREE
|
||||
_sift->compute(image, keypoints, descriptors);
|
||||
#else
|
||||
UERROR("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
|
||||
#endif
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ Memory::Memory(const ParametersMap & parameters) :
|
||||
_signaturesAdded(0),
|
||||
_postInitClosingEvents(false),
|
||||
|
||||
_feature2D(new SURF(parameters)),
|
||||
_featureType(Feature2D::kFeatureSurf),
|
||||
_featureType((Feature2D::Type)Parameters::defaultKpDetectorStrategy()),
|
||||
_badSignRatio(Parameters::defaultKpBadSignRatio()),
|
||||
_tfIdfLikelihoodUsed(Parameters::defaultKpTfIdfLikelihoodUsed()),
|
||||
_parallelized(Parameters::defaultKpParallelized()),
|
||||
@@ -114,6 +113,7 @@ Memory::Memory(const ParametersMap & parameters) :
|
||||
_subPixIterations(Parameters::defaultKpSubPixIterations()),
|
||||
_subPixEps(Parameters::defaultKpSubPixEps())
|
||||
{
|
||||
_feature2D = Feature2D::create(_featureType, parameters);
|
||||
_vwd = new VWDictionary(parameters);
|
||||
this->parseParameters(parameters);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <pcl/ModelCoefficients.h>
|
||||
#include <pcl/segmentation/sac_segmentation.h>
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
#include <opencv2/nonfree/features2d.hpp>
|
||||
#endif
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <opencv2/video/tracking.hpp>
|
||||
#include <rtabmap/core/VWDictionary.h>
|
||||
@@ -1123,7 +1125,7 @@ cv::Mat uncompressImage(const cv::Mat & bytes)
|
||||
cv::Mat image;
|
||||
if(!bytes.empty())
|
||||
{
|
||||
#if CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4
|
||||
#if CV_MAJOR_VERSION>2 || (CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4)
|
||||
image = cv::imdecode(bytes, cv::IMREAD_UNCHANGED);
|
||||
#else
|
||||
image = cv::imdecode(bytes, -1);
|
||||
@@ -1137,7 +1139,7 @@ cv::Mat uncompressImage(const std::vector<unsigned char> & bytes)
|
||||
cv::Mat image;
|
||||
if(bytes.size())
|
||||
{
|
||||
#if CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4
|
||||
#if CV_MAJOR_VERSION>2 || (CV_MAJOR_VERSION >=2 && CV_MINOR_VERSION >=4)
|
||||
image = cv::imdecode(bytes, cv::IMREAD_UNCHANGED);
|
||||
#else
|
||||
image = cv::imdecode(bytes, -1);
|
||||
|
||||
Reference in New Issue
Block a user