mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 09:30: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:
@@ -509,55 +509,69 @@ Feature2D * Feature2D::create(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)))
|
||||
#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.");
|
||||
#else
|
||||
#else
|
||||
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;
|
||||
}
|
||||
#if CV_MAJOR_VERSION == 3
|
||||
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
|
||||
#endif
|
||||
|
||||
#else // >= 4.4.0 >= 3.4.11
|
||||
|
||||
#ifndef RTABMAP_NONFREE
|
||||
if(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSurfFreak)
|
||||
#ifndef RTABMAP_NONFREE
|
||||
if(type == Feature2D::kFeatureSurf)
|
||||
{
|
||||
UWARN("SURF features cannot be used because OpenCV was not built with nonfree module. SIFT is used instead.");
|
||||
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
|
||||
|
||||
#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)
|
||||
{
|
||||
#ifdef RTABMAP_NONFREE
|
||||
#ifdef RTABMAP_NONFREE
|
||||
UWARN("KAZE detector/descriptor can be used only with OpenCV3. SURF is used instead.");
|
||||
type = Feature2D::kFeatureSurf;
|
||||
#else
|
||||
#else
|
||||
UWARN("KAZE detector/descriptor can be used only with OpenCV3. GFTT/ORB is used instead.");
|
||||
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
|
||||
|
||||
|
||||
#ifndef RTABMAP_ORB_OCTREE
|
||||
if(type == Feature2D::kFeatureOrbOctree)
|
||||
{
|
||||
@@ -618,6 +632,12 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
||||
case Feature2D::kFeatureSurfFreak:
|
||||
feature2D = new SURF_FREAK(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureGfttDaisy:
|
||||
feature2D = new GFTT_DAISY(parameters);
|
||||
break;
|
||||
case Feature2D::kFeatureSurfDaisy:
|
||||
feature2D = new SURF_DAISY(parameters);
|
||||
break;
|
||||
#ifdef RTABMAP_NONFREE
|
||||
default:
|
||||
feature2D = new SURF(parameters);
|
||||
@@ -626,7 +646,7 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
||||
#else
|
||||
default:
|
||||
feature2D = new ORB(parameters);
|
||||
type = Feature2D::kFeatureOrb;
|
||||
type = Feature2D::kFeatureGfttOrb;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -1939,7 +1959,10 @@ cv::Mat KAZE::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
|
||||
ORBOctree::ORBOctree(const ParametersMap & parameters) :
|
||||
scaleFactor_(Parameters::defaultORBScaleFactor()),
|
||||
nLevels_(Parameters::defaultORBNLevels()),
|
||||
fastThreshold_(Parameters::defaultFASTThreshold())
|
||||
patchSize_(Parameters::defaultORBPatchSize()),
|
||||
edgeThreshold_(Parameters::defaultORBEdgeThreshold()),
|
||||
fastThreshold_(Parameters::defaultFASTThreshold()),
|
||||
fastMinThreshold_(Parameters::defaultFASTMinThreshold())
|
||||
{
|
||||
parseParameters(parameters);
|
||||
}
|
||||
@@ -1954,12 +1977,14 @@ void ORBOctree::parseParameters(const ParametersMap & parameters)
|
||||
|
||||
Parameters::parse(parameters, Parameters::kORBScaleFactor(), scaleFactor_);
|
||||
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::kFASTMinThreshold(), fastMinThreshold_);
|
||||
|
||||
#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
|
||||
UWARN("RTAB-Map is not built with ORB OcTree option enabled so ORB OcTree feature cannot be used!");
|
||||
#endif
|
||||
@@ -2070,4 +2095,103 @@ cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vec
|
||||
#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
|
||||
{
|
||||
|
||||
const int PATCH_SIZE = 31;
|
||||
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)
|
||||
static float IC_Angle(const Mat& image, Point2f pt, const vector<int> & u_max, int halfPatchSize)
|
||||
{
|
||||
int m_01 = 0, m_10 = 0;
|
||||
|
||||
const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
|
||||
|
||||
// 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];
|
||||
|
||||
// Go line by line in the circuI853lar patch
|
||||
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
|
||||
int v_sum = 0;
|
||||
@@ -419,10 +414,11 @@ static int bit_pattern_31_[256*4] =
|
||||
};
|
||||
|
||||
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),
|
||||
iniThFAST(_iniThFAST), minThFAST(_minThFAST)
|
||||
iniThFAST(_iniThFAST), minThFAST(_minThFAST), patchSize(_patchSize), edgeThreshold(_edgeThreshold)
|
||||
{
|
||||
halfPatchSize = patchSize/2;
|
||||
mvScaleFactor.resize(nlevels);
|
||||
mvLevelSigma2.resize(nlevels);
|
||||
mvScaleFactor[0]=1.0f;
|
||||
@@ -462,16 +458,16 @@ ORBextractor::ORBextractor(int _nfeatures, float _scaleFactor, int _nlevels,
|
||||
|
||||
//This is for orientation
|
||||
// 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 vmin = cvCeil(HALF_PATCH_SIZE * sqrt(2.f) / 2);
|
||||
const double hp2 = HALF_PATCH_SIZE*HALF_PATCH_SIZE;
|
||||
int v, v0, vmax = cvFloor(float(halfPatchSize) * sqrt(2.f) / 2 + 1);
|
||||
int vmin = cvCeil(float(halfPatchSize) * sqrt(2.f) / 2);
|
||||
const double hp2 = halfPatchSize*halfPatchSize;
|
||||
for (v = 0; v <= vmax; ++v)
|
||||
umax[v] = cvRound(sqrt(hp2 - v * v));
|
||||
|
||||
// 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])
|
||||
++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(),
|
||||
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)
|
||||
{
|
||||
const int minBorderX = EDGE_THRESHOLD-3;
|
||||
const int minBorderX = edgeThreshold-3;
|
||||
const int minBorderY = minBorderX;
|
||||
const int maxBorderX = mvImagePyramid[level].cols-EDGE_THRESHOLD+3;
|
||||
const int maxBorderY = mvImagePyramid[level].rows-EDGE_THRESHOLD+3;
|
||||
const int maxBorderX = mvImagePyramid[level].cols-edgeThreshold+3;
|
||||
const int maxBorderY = mvImagePyramid[level].rows-edgeThreshold+3;
|
||||
|
||||
vector<cv::KeyPoint> vToDistributeKeys;
|
||||
vToDistributeKeys.reserve(nfeatures*10);
|
||||
@@ -845,7 +841,7 @@ void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoin
|
||||
keypoints = DistributeOctTree(vToDistributeKeys, minBorderX, maxBorderX,
|
||||
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
|
||||
const int nkps = keypoints.size();
|
||||
@@ -860,7 +856,7 @@ void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoin
|
||||
|
||||
// compute orientations
|
||||
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)
|
||||
@@ -876,10 +872,10 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
||||
const int levelCols = sqrt((float)nDesiredFeatures/(5*imageRatio));
|
||||
const int levelRows = imageRatio*levelCols;
|
||||
|
||||
const int minBorderX = EDGE_THRESHOLD;
|
||||
const int minBorderX = edgeThreshold;
|
||||
const int minBorderY = minBorderX;
|
||||
const int maxBorderX = mvImagePyramid[level].cols-EDGE_THRESHOLD;
|
||||
const int maxBorderY = mvImagePyramid[level].rows-EDGE_THRESHOLD;
|
||||
const int maxBorderX = mvImagePyramid[level].cols-edgeThreshold;
|
||||
const int maxBorderY = mvImagePyramid[level].rows-edgeThreshold;
|
||||
|
||||
const int W = maxBorderX - minBorderX;
|
||||
const int H = maxBorderY - minBorderY;
|
||||
@@ -1006,7 +1002,7 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
||||
vector<KeyPoint> & keypoints = allKeypoints[level];
|
||||
keypoints.reserve(nDesiredFeatures*2);
|
||||
|
||||
const int scaledPatchSize = PATCH_SIZE*mvScaleFactor[level];
|
||||
const int scaledPatchSize = patchSize*mvScaleFactor[level];
|
||||
|
||||
// Retain by score and transform coordinates
|
||||
for(int i=0; i<levelRows; i++)
|
||||
@@ -1039,7 +1035,7 @@ void ORBextractor::ComputeKeyPointsOld(std::vector<std::vector<KeyPoint> > &allK
|
||||
|
||||
// and compute orientations
|
||||
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,
|
||||
@@ -1121,21 +1117,21 @@ void ORBextractor::ComputePyramid(cv::Mat image)
|
||||
{
|
||||
float scale = mvInvScaleFactor[level];
|
||||
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;
|
||||
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
|
||||
if( level != 0 )
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
|
||||
copyMakeBorder(image, temp, edgeThreshold, edgeThreshold, edgeThreshold, edgeThreshold,
|
||||
BORDER_REFLECT_101);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
enum {HARRIS_SCORE=0, FAST_SCORE=1 };
|
||||
|
||||
ORBextractor(int nfeatures, float scaleFactor, int nlevels,
|
||||
int iniThFAST, int minThFAST);
|
||||
int iniThFAST, int minThFAST, int patchSize, int edgeThreshold);
|
||||
|
||||
~ORBextractor(){}
|
||||
|
||||
@@ -107,6 +107,10 @@ protected:
|
||||
int nlevels;
|
||||
int iniThFAST;
|
||||
int minThFAST;
|
||||
int patchSize;
|
||||
int edgeThreshold;
|
||||
int halfPatchSize;
|
||||
|
||||
|
||||
std::vector<int> mnFeaturesPerLevel;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user