Added GPU options for FAST and ORB

git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@341 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
matlabbe 2014-06-19 18:55:46 +00:00
parent 4347951c57
commit 7bdf4e903e
3 changed files with 227 additions and 53 deletions

View File

@ -111,8 +111,15 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
if(cv::gpu::getCudaEnabledDeviceCount() == 0) if(cv::gpu::getCudaEnabledDeviceCount() == 0)
{ {
Settings::setFeature2D_SURF_gpu(false); Settings::setFeature2D_SURF_gpu(false);
Settings::setFeature2D_Fast_gpu(false);
Settings::setFeature2D_ORB_gpu(false);
ui_->toolBox->updateParameter(Settings::kFeature2D_SURF_gpu()); ui_->toolBox->updateParameter(Settings::kFeature2D_SURF_gpu());
ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false); ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_gpu())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_keypointsRatio())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kFeature2D_ORB_gpu())->setEnabled(false);
} }
detector_ = Settings::createFeaturesDetector(); detector_ = Settings::createFeaturesDetector();

View File

@ -122,8 +122,10 @@ class GPUSURF : public cv::Feature2D
{ {
public: public:
GPUSURF(double hessianThreshold, GPUSURF(double hessianThreshold,
int nOctaves=4, int nOctaveLayers=2, int nOctaves = Settings::defaultFeature2D_SURF_nOctaves(),
bool extended=true, bool upright=false) : int nOctaveLayers = Settings::defaultFeature2D_SURF_nOctaveLayers(),
bool extended = Settings::defaultFeature2D_SURF_extended(),
bool upright = Settings::defaultFeature2D_SURF_upright()) :
hessianThreshold_(hessianThreshold), hessianThreshold_(hessianThreshold),
nOctaves_(nOctaves), nOctaves_(nOctaves),
nOctaveLayers_(nOctaveLayers), nOctaveLayers_(nOctaveLayers),
@ -155,28 +157,26 @@ protected:
{ {
cv::gpu::GpuMat imgGpu(image); cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat maskGpu(mask); cv::gpu::GpuMat maskGpu(mask);
cv::gpu::GpuMat keypointsGpu;
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_); cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
surfGpu(imgGpu, maskGpu, keypointsGpu); surfGpu(imgGpu, maskGpu, keypoints);
surfGpu.downloadKeypoints(keypointsGpu, keypoints);
} }
void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const
{ {
std::vector<float> d; std::vector<float> d;
cv::gpu::GpuMat imgGpu(image); cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat descriptorsGpu;
cv::gpu::GpuMat keypointsGpu;
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_); cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
surfGpu.uploadKeypoints(keypoints, keypointsGpu); cv::gpu::GpuMat descriptorsGPU;
surfGpu(imgGpu, cv::gpu::GpuMat(), keypointsGpu, descriptorsGpu, true); surfGpu(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU, true);
surfGpu.downloadDescriptors(descriptorsGpu, d);
unsigned int dim = extended_?128:64; // Download descriptors
descriptors = cv::Mat(d.size()/dim, dim, CV_32F); if (descriptorsGPU.empty())
for(int i=0; i<descriptors.rows; ++i) descriptors = cv::Mat();
else
{ {
float * rowFl = descriptors.ptr<float>(i); Q_ASSERT(descriptorsGPU.type() == CV_32F);
memcpy(rowFl, &d[i*dim], dim*sizeof(float)); descriptors = cv::Mat(descriptorsGPU.size(), CV_32F);
descriptorsGPU.download(descriptors);
} }
} }
@ -188,6 +188,122 @@ private:
bool upright_; bool upright_;
}; };
class GPUFAST : public cv::FeatureDetector
{
public:
GPUFAST(int threshold=Settings::defaultFeature2D_Fast_threshold(),
bool nonmaxSuppression=Settings::defaultFeature2D_Fast_nonmaxSuppression(),
double keypointsRatio=Settings::defaultFeature2D_Fast_keypointsRatio()) :
threshold_(threshold),
nonmaxSuppression_(nonmaxSuppression),
keypointsRatio_(keypointsRatio)
{
}
virtual ~GPUFAST() {}
protected:
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
{
cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat maskGpu(mask);
cv::gpu::FAST_GPU fastGpu(threshold_, nonmaxSuppression_, keypointsRatio_);
fastGpu(imgGpu, maskGpu, keypoints);
}
private:
int threshold_;
bool nonmaxSuppression_;
double keypointsRatio_;
};
class GPUORB : public cv::Feature2D
{
public:
GPUORB(int nFeatures = Settings::defaultFeature2D_ORB_nFeatures(),
float scaleFactor = Settings::defaultFeature2D_ORB_scaleFactor(),
int nLevels = Settings::defaultFeature2D_ORB_nLevels(),
int edgeThreshold = Settings::defaultFeature2D_ORB_edgeThreshold(),
int firstLevel = Settings::defaultFeature2D_ORB_firstLevel(),
int WTA_K = Settings::defaultFeature2D_ORB_WTA_K(),
int scoreType = Settings::defaultFeature2D_ORB_scoreType(),
int patchSize = Settings::defaultFeature2D_ORB_patchSize(),
int fastThreshold = Settings::defaultFeature2D_Fast_threshold(),
bool fastNonmaxSupression = Settings::defaultFeature2D_Fast_nonmaxSuppression()) :
nFeatures_(nFeatures),
scaleFactor_(scaleFactor),
nLevels_(nLevels),
edgeThreshold_(edgeThreshold),
firstLevel_(firstLevel),
WTA_K_(WTA_K),
scoreType_(scoreType),
patchSize_(patchSize),
fastThreshold_(fastThreshold),
fastNonmaxSupression_(fastNonmaxSupression)
{
}
virtual ~GPUORB() {}
void operator()(cv::InputArray img, cv::InputArray mask,
std::vector<cv::KeyPoint>& keypoints,
cv::OutputArray descriptors,
bool useProvidedKeypoints=false) const
{
printf("GPUSURF:operator() Don't call this directly!\n");
exit(-1);
}
int descriptorSize() const
{
return cv::ORB::kBytes;
}
int descriptorType() const
{
return CV_8U;
}
protected:
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
{
cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat maskGpu(mask);
cv::gpu::ORB_GPU orbGPU(nFeatures_, scaleFactor_, nLevels_, edgeThreshold_ ,firstLevel_, WTA_K_, scoreType_, patchSize_);
orbGPU.setFastParams(fastThreshold_, fastNonmaxSupression_);
orbGPU(imgGpu, maskGpu, keypoints);
}
void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const
{
std::vector<float> d;
cv::gpu::GpuMat imgGpu(image);
cv::gpu::ORB_GPU orbGPU(nFeatures_, scaleFactor_, nLevels_, edgeThreshold_ ,firstLevel_, WTA_K_, scoreType_, patchSize_);
orbGPU.setFastParams(fastThreshold_, fastNonmaxSupression_);
cv::gpu::GpuMat descriptorsGPU;
orbGPU(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU); // No option to use provided keypoints!?
// Download descriptors
if (descriptorsGPU.empty())
descriptors = cv::Mat();
else
{
Q_ASSERT(descriptorsGPU.type() == CV_8U);
descriptors = cv::Mat(descriptorsGPU.size(), CV_8U);
descriptorsGPU.download(descriptors);
}
}
private:
int nFeatures_;
float scaleFactor_;
int nLevels_;
int edgeThreshold_;
int firstLevel_;
int WTA_K_;
int scoreType_;
int patchSize_;
int fastThreshold_;
bool fastNonmaxSupression_;
};
cv::FeatureDetector * Settings::createFeaturesDetector() cv::FeatureDetector * Settings::createFeaturesDetector()
{ {
cv::FeatureDetector * detector = 0; cv::FeatureDetector * detector = 0;
@ -215,16 +331,26 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_Dense_initImgBound(), getFeature2D_Dense_initImgBound(),
getFeature2D_Dense_varyXyStepWithScale(), getFeature2D_Dense_varyXyStepWithScale(),
getFeature2D_Dense_varyImgBoundWithScale()); getFeature2D_Dense_varyImgBoundWithScale());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "Dense"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 1: case 1:
if(strategies.at(index).compare("Fast") == 0) if(strategies.at(index).compare("Fast") == 0)
{
if(getFeature2D_Fast_gpu() && cv::gpu::getCudaEnabledDeviceCount())
{
detector = new GPUFAST(
getFeature2D_Fast_threshold(),
getFeature2D_Fast_nonmaxSuppression());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s GPU\n", strategies.at(index).toStdString().c_str());
}
else
{ {
detector = new cv::FastFeatureDetector( detector = new cv::FastFeatureDetector(
getFeature2D_Fast_threshold(), getFeature2D_Fast_threshold(),
getFeature2D_Fast_nonmaxSuppression()); getFeature2D_Fast_nonmaxSuppression());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "Fast"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
}
} }
break; break;
case 2: case 2:
@ -237,7 +363,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_GFTT_blockSize(), getFeature2D_GFTT_blockSize(),
getFeature2D_GFTT_useHarrisDetector(), getFeature2D_GFTT_useHarrisDetector(),
getFeature2D_GFTT_k()); getFeature2D_GFTT_k());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "GFTT"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 3: case 3:
@ -253,11 +379,28 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_MSER_areaThreshold(), getFeature2D_MSER_areaThreshold(),
getFeature2D_MSER_minMargin(), getFeature2D_MSER_minMargin(),
getFeature2D_MSER_edgeBlurSize()); getFeature2D_MSER_edgeBlurSize());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "MSER"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 4: case 4:
if(strategies.at(index).compare("ORB") == 0) if(strategies.at(index).compare("ORB") == 0)
{
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
{
detector = new GPUORB(
getFeature2D_ORB_nFeatures(),
getFeature2D_ORB_scaleFactor(),
getFeature2D_ORB_nLevels(),
getFeature2D_ORB_edgeThreshold(),
getFeature2D_ORB_firstLevel(),
getFeature2D_ORB_WTA_K(),
getFeature2D_ORB_scoreType(),
getFeature2D_ORB_patchSize(),
getFeature2D_Fast_threshold(),
getFeature2D_Fast_nonmaxSuppression());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
}
else
{ {
detector = new cv::ORB( detector = new cv::ORB(
getFeature2D_ORB_nFeatures(), getFeature2D_ORB_nFeatures(),
@ -268,7 +411,8 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_ORB_WTA_K(), getFeature2D_ORB_WTA_K(),
getFeature2D_ORB_scoreType(), getFeature2D_ORB_scoreType(),
getFeature2D_ORB_patchSize()); getFeature2D_ORB_patchSize());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "ORB"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
}
} }
break; break;
case 5: case 5:
@ -280,7 +424,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_SIFT_contrastThreshold(), getFeature2D_SIFT_contrastThreshold(),
getFeature2D_SIFT_edgeThreshold(), getFeature2D_SIFT_edgeThreshold(),
getFeature2D_SIFT_sigma()); getFeature2D_SIFT_sigma());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "SIFT"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 6: case 6:
@ -292,7 +436,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_Star_lineThresholdProjected(), getFeature2D_Star_lineThresholdProjected(),
getFeature2D_Star_lineThresholdBinarized(), getFeature2D_Star_lineThresholdBinarized(),
getFeature2D_Star_suppressNonmaxSize()); getFeature2D_Star_suppressNonmaxSize());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "Star"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 7: case 7:
@ -306,6 +450,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_SURF_nOctaveLayers(), getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(), getFeature2D_SURF_extended(),
getFeature2D_SURF_upright()); getFeature2D_SURF_upright());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
} }
else else
{ {
@ -315,8 +460,8 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_SURF_nOctaveLayers(), getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(), getFeature2D_SURF_extended(),
getFeature2D_SURF_upright()); getFeature2D_SURF_upright());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "SURF");
} }
break; break;
case 8: case 8:
@ -326,7 +471,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_BRISK_thresh(), getFeature2D_BRISK_thresh(),
getFeature2D_BRISK_octaves(), getFeature2D_BRISK_octaves(),
getFeature2D_BRISK_patternScale()); getFeature2D_BRISK_patternScale());
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "BRISK"); if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
default: default:
@ -364,11 +509,28 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
{ {
extractor = new cv::BriefDescriptorExtractor( extractor = new cv::BriefDescriptorExtractor(
getFeature2D_Brief_bytes()); getFeature2D_Brief_bytes());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "Brief"); if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 1: case 1:
if(strategies.at(index).compare("ORB") == 0) if(strategies.at(index).compare("ORB") == 0)
{
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
{
extractor = new GPUORB(
getFeature2D_ORB_nFeatures(),
getFeature2D_ORB_scaleFactor(),
getFeature2D_ORB_nLevels(),
getFeature2D_ORB_edgeThreshold(),
getFeature2D_ORB_firstLevel(),
getFeature2D_ORB_WTA_K(),
getFeature2D_ORB_scoreType(),
getFeature2D_ORB_patchSize(),
getFeature2D_Fast_threshold(),
getFeature2D_Fast_nonmaxSuppression());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
}
else
{ {
extractor = new cv::ORB( extractor = new cv::ORB(
getFeature2D_ORB_nFeatures(), getFeature2D_ORB_nFeatures(),
@ -379,7 +541,8 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_ORB_WTA_K(), getFeature2D_ORB_WTA_K(),
getFeature2D_ORB_scoreType(), getFeature2D_ORB_scoreType(),
getFeature2D_ORB_patchSize()); getFeature2D_ORB_patchSize());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "ORB"); if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
}
} }
break; break;
case 2: case 2:
@ -391,7 +554,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_SIFT_contrastThreshold(), getFeature2D_SIFT_contrastThreshold(),
getFeature2D_SIFT_edgeThreshold(), getFeature2D_SIFT_edgeThreshold(),
getFeature2D_SIFT_sigma()); getFeature2D_SIFT_sigma());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "SIFT"); if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 3: case 3:
@ -405,6 +568,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_SURF_nOctaveLayers(), getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(), getFeature2D_SURF_extended(),
getFeature2D_SURF_upright()); getFeature2D_SURF_upright());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s (GPU)\n", strategies.at(index).toStdString().c_str());
} }
else else
{ {
@ -414,8 +578,8 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_SURF_nOctaveLayers(), getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(), getFeature2D_SURF_extended(),
getFeature2D_SURF_upright()); getFeature2D_SURF_upright());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
} }
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "SURF");
} }
break; break;
case 4: case 4:
@ -425,7 +589,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_BRISK_thresh(), getFeature2D_BRISK_thresh(),
getFeature2D_BRISK_octaves(), getFeature2D_BRISK_octaves(),
getFeature2D_BRISK_patternScale()); getFeature2D_BRISK_patternScale());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "BRISK"); if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
case 5: case 5:
@ -436,7 +600,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_FREAK_scaleNormalized(), getFeature2D_FREAK_scaleNormalized(),
getFeature2D_FREAK_patternScale(), getFeature2D_FREAK_patternScale(),
getFeature2D_FREAK_nOctaves()); getFeature2D_FREAK_nOctaves());
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "FREAK"); if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", strategies.at(index).toStdString().c_str());
} }
break; break;
default: default:

View File

@ -80,7 +80,9 @@ class Settings
PARAMETER(Feature2D, Dense_varyImgBoundWithScale, bool, false, ""); PARAMETER(Feature2D, Dense_varyImgBoundWithScale, bool, false, "");
PARAMETER(Feature2D, Fast_threshold, int, 10, "Threshold on difference between intensity of the central pixel and pixels of a circle around this pixel."); PARAMETER(Feature2D, Fast_threshold, int, 10, "Threshold on difference between intensity of the central pixel and pixels of a circle around this pixel.");
PARAMETER(Feature2D, Fast_nonmaxSuppression, bool, true, " If true, non-maximum suppression is applied to detected corners (keypoints)."); PARAMETER(Feature2D, Fast_nonmaxSuppression, bool, true, "If true, non-maximum suppression is applied to detected corners (keypoints).");
PARAMETER(Feature2D, Fast_gpu, bool, false, "GPU-FAST: Use GPU version of FAST. This option is enabled only if OpenCV is built with CUDA and GPUs are detected.");
PARAMETER(Feature2D, Fast_keypointsRatio, double, 0.05, "Used with FAST GPU.");
PARAMETER(Feature2D, GFTT_maxCorners, int, 1000, ""); PARAMETER(Feature2D, GFTT_maxCorners, int, 1000, "");
PARAMETER(Feature2D, GFTT_qualityLevel, double, 0.01, ""); PARAMETER(Feature2D, GFTT_qualityLevel, double, 0.01, "");
@ -95,8 +97,9 @@ class Settings
PARAMETER(Feature2D, ORB_edgeThreshold, int, 31, "This is size of the border where the features are not detected. It should roughly match the patchSize parameter."); PARAMETER(Feature2D, ORB_edgeThreshold, int, 31, "This is size of the border where the features are not detected. It should roughly match the patchSize parameter.");
PARAMETER(Feature2D, ORB_firstLevel, int, 0, "It should be 0 in the current implementation."); PARAMETER(Feature2D, ORB_firstLevel, int, 0, "It should be 0 in the current implementation.");
PARAMETER(Feature2D, 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)."); PARAMETER(Feature2D, 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).");
PARAMETER(Feature2D, ORB_scoreType, int, 0, "The default HARRIS_SCORE 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 is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute."); PARAMETER(Feature2D, 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.");
PARAMETER(Feature2D, ORB_patchSize, int, 31, "size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered by a feature will be larger."); PARAMETER(Feature2D, ORB_patchSize, int, 31, "size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered by a feature will be larger.");
PARAMETER(Feature2D, ORB_gpu, bool, false, "GPU-ORB: Use GPU version of ORB. This option is enabled only if OpenCV is built with CUDA and GPUs are detected.");
PARAMETER(Feature2D, MSER_delta, int, 5, ""); PARAMETER(Feature2D, MSER_delta, int, 5, "");
PARAMETER(Feature2D, MSER_minArea, int, 60, ""); PARAMETER(Feature2D, MSER_minArea, int, 60, "");