From 7e5c11a920ba1b890f92c299709e3c794f9baf32 Mon Sep 17 00:00:00 2001 From: Maria Dimashova Date: Thu, 25 Nov 2010 15:59:37 +0000 Subject: [PATCH] added tests for some detectors; made features2d object create functions as static classes methods; fixed OpponentColorDescriptorExtractor, BriefDescriptorExtractor (on rgb); renamed DynamicDetector --- .../include/opencv2/features2d/features2d.hpp | 92 ++++----- modules/features2d/src/brief.cpp | 24 ++- modules/features2d/src/descriptors.cpp | 60 +++--- modules/features2d/src/detectors.cpp | 103 ++++++----- modules/features2d/src/dynamic.cpp | 115 ++++++++---- modules/features2d/src/matchers.cpp | 118 ++++++------ samples/cpp/bagofwords_classification.cpp | 6 +- samples/cpp/build3dmodel.cpp | 4 +- samples/cpp/descriptor_extractor_matcher.cpp | 6 +- samples/cpp/generic_descriptor_match.cpp | 2 +- samples/cpp/matching_to_many_images.cpp | 6 +- .../cv/src/adetectordescriptor_evaluation.cpp | 12 +- tests/cv/src/afeatures2d.cpp | 174 ++++++++++-------- 13 files changed, 400 insertions(+), 322 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index 100d44f802..f6a56707e5 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -1250,11 +1250,14 @@ public: */ void detect( const vector& images, vector >& keypoints, const vector& masks=vector() ) const; - // Read detector object from a file node + // Read detector object from a file node. virtual void read( const FileNode& ); - // Read detector object from a file node + // Read detector object from a file node. virtual void write( FileStorage& ) const; + // Create feature detector by detector name. + static Ptr create( const string& detectorType ); + protected: virtual void detectImpl( const Mat& image, vector& keypoints, const Mat& mask=Mat() ) const = 0; /* @@ -1416,7 +1419,7 @@ public: * gridRows Grid rows count. * gridCols Grid column count. */ - GridAdaptedFeatureDetector( const Ptr& detector, int maxTotalKeypoints, + GridAdaptedFeatureDetector( const Ptr& detector, int maxTotalKeypoints=1000, int gridRows=4, int gridCols=4 ); // TODO implement read/write @@ -1448,19 +1451,15 @@ protected: int levels; }; -/* - * Dynamic Feature Detectors - */ - -/** \brief A feature detector parameter adjuster, this is used by the DynamicDetector +/** \brief A feature detector parameter adjuster, this is used by the DynamicAdaptedFeatureDetector * and is a wrapper for FeatureDetector that allow them to be adjusted after a detection */ -class CV_EXPORTS AdjusterAdapter: public FeatureDetector { -public: +class CV_EXPORTS AdjusterAdapter: public FeatureDetector +{ +public: /** pure virtual interface */ - virtual ~AdjusterAdapter() { - } + virtual ~AdjusterAdapter() {} /** too few features were detected so, adjust the detector params accordingly * \param min the minimum number of desired features * \param n_detected the number previously detected @@ -1475,6 +1474,8 @@ public: * \return false if the parameters can't be adjusted any more */ virtual bool good() const = 0; + + static Ptr create( const string& detectorType ); }; /** \brief an adaptively adjusting detector that iteratively detects until the desired number * of features are detected. @@ -1485,24 +1486,24 @@ public: * sample usage: //will create a detector that attempts to find 100 - 110 FAST Keypoints, and will at most run //FAST feature detection 10 times until that number of keypoints are found - Ptr detector(new DynamicDetector (100, 110, 10,new FastAdjuster(20,true))); + Ptr detector(new DynamicAdaptedFeatureDetector(new FastAdjuster(20,true),100, 110, 10)); */ -class CV_EXPORTS DynamicDetector: public FeatureDetector { +class CV_EXPORTS DynamicAdaptedFeatureDetector: public FeatureDetector +{ public: - /** \param min_features the minimum desired features + /** \param adjaster an AdjusterAdapter that will do the detection and parameter adjustment * \param max_features the maximum desired number of features * \param max_iters the maximum number of times to try to adjust the feature detector params * for the FastAdjuster this can be high, but with Star or Surf this can get time consuming - * \param a an AdjusterAdapter that will do the detection and parameter adjustment + * \param min_features the minimum desired features */ - DynamicDetector(int min_features, int max_features, int max_iters, - const Ptr& a); + DynamicAdaptedFeatureDetector( const Ptr& adjaster, int min_features=400, int max_features=500, int max_iters=5 ); + protected: - virtual void detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask = - cv::Mat()) const; + virtual void detectImpl( const Mat& image, vector& keypoints, const Mat& mask=Mat() ) const; + private: int escape_iters_; int min_features_, max_features_; @@ -1512,7 +1513,8 @@ private: /**\brief an adjust for the FAST detector. This will basically decrement or increment the * threshhold by 1 */ -class CV_EXPORTS FastAdjuster: public AdjusterAdapter { +class CV_EXPORTS FastAdjuster: public AdjusterAdapter +{ public: /**\param init_thresh the initial threshhold to start with, default = 20 * \param nonmax whether to use non max or not for fast feature detection @@ -1521,50 +1523,50 @@ public: virtual void tooFew(int min, int n_detected); virtual void tooMany(int max, int n_detected); virtual bool good() const; + protected: - virtual void detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask = - cv::Mat()) const; + virtual void detectImpl( const Mat& image, vector& keypoints, const Mat& mask=Mat() ) const; + int thresh_; bool nonmax_; - }; /** An adjuster for StarFeatureDetector, this one adjusts the responseThreshold for now * TODO find a faster way to converge the parameters for Star - use CvStarDetectorParams */ -struct CV_EXPORTS StarAdjuster: public AdjusterAdapter { +class CV_EXPORTS StarAdjuster: public AdjusterAdapter +{ +public: StarAdjuster(double initial_thresh = 30.0); virtual void tooFew(int min, int n_detected); virtual void tooMany(int max, int n_detected); virtual bool good() const; + protected: - virtual void detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask = - cv::Mat()) const; + virtual void detectImpl( const Mat& image, vector& keypoints, const Mat& mask=Mat() ) const; + double thresh_; CvStarDetectorParams params_; //todo use these instead of thresh_ }; -struct CV_EXPORTS SurfAdjuster: public AdjusterAdapter { - SurfAdjuster(); +class CV_EXPORTS SurfAdjuster: public AdjusterAdapter +{ +public: + SurfAdjuster(); virtual void tooFew(int min, int n_detected); virtual void tooMany(int max, int n_detected); virtual bool good() const; + protected: - virtual void detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask = - cv::Mat()) const; + virtual void detectImpl( const Mat& image, vector& keypoints, const Mat& mask=Mat() ) const; + double thresh_; }; - CV_EXPORTS Mat windowedMatchingMask( const vector& keypoints1, const vector& keypoints2, float maxDeltaX, float maxDeltaY ); -CV_EXPORTS Ptr createFeatureDetector( const string& detectorType ); - /****************************************************************************************\ * DescriptorExtractor * \****************************************************************************************/ @@ -1606,6 +1608,8 @@ public: virtual int descriptorSize() const = 0; virtual int descriptorType() const = 0; + static Ptr create( const string& descriptorExtractorType ); + protected: virtual void computeImpl( const Mat& image, vector& keypoints, Mat& descriptors ) const = 0; @@ -1771,8 +1775,6 @@ protected: PixelTestFn test_fn_; }; -CV_EXPORTS Ptr createDescriptorExtractor( const string& descriptorExtractorType ); - /****************************************************************************************\ * Distance * \****************************************************************************************/ @@ -1981,6 +1983,7 @@ public: // but with empty train data. virtual Ptr clone( bool emptyTrainData=false ) const = 0; + static Ptr create( const string& descriptorMatcherType ); protected: /* * Class to work with descriptors from several images as with one merged matrix. @@ -2265,9 +2268,6 @@ protected: int addedDescCount; }; - -CV_EXPORTS Ptr createDescriptorMatcher( const string& descriptorMatcherType ); - /****************************************************************************************\ * GenericDescriptorMatcher * \****************************************************************************************/ @@ -2372,6 +2372,9 @@ public: // but with empty train data. virtual Ptr clone( bool emptyTrainData=false ) const = 0; + static Ptr create( const string& genericDescritptorMatcherType, + const string ¶msFilename=string() ); + protected: // In fact the matching is implemented only by the following two methods. These methods suppose // that the class object has been trained already. Public match methods call these methods @@ -2557,9 +2560,6 @@ protected: int prevTrainCount; }; -CV_EXPORTS Ptr createGenericDescriptorMatcher( const string& genericDescritptorMatcherType, - const string ¶msFilename = string () ); - /****************************************************************************************\ * VectorDescriptorMatcher * \****************************************************************************************/ diff --git a/modules/features2d/src/brief.cpp b/modules/features2d/src/brief.cpp index 74ffff395b..f79dd85e07 100644 --- a/modules/features2d/src/brief.cpp +++ b/modules/features2d/src/brief.cpp @@ -92,15 +92,17 @@ void pixelTests64(const Mat& sum, const std::vector& keypoints, Mat& d namespace cv { + HammingLUT::ResultType HammingLUT::operator()( const unsigned char* a, const unsigned char* b, int size ) const - { - ResultType result = 0; - for (int i = 0; i < size; i++) - { - result += byteBitsLookUp(a[i] ^ b[i]); - } - return result; - } +{ + ResultType result = 0; + for (int i = 0; i < size; i++) + { + result += byteBitsLookUp(a[i] ^ b[i]); + } + return result; +} + Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned char* b, int size) const { #if __GNUC__ @@ -116,6 +118,7 @@ Hamming::ResultType Hamming::operator()(const unsigned char* a, const unsigned c return HammingLUT()(a,b,size); #endif } + BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) : bytes_(bytes), test_fn_(NULL) { @@ -150,12 +153,15 @@ void BriefDescriptorExtractor::computeImpl(const Mat& image, std::vector& keypoints, } } +Ptr DescriptorExtractor::create(const string& descriptorExtractorType) +{ + DescriptorExtractor* de = 0; + + int pos = 0; + if (!descriptorExtractorType.compare("SIFT")) + { + de = new SiftDescriptorExtractor(); + } + else if (!descriptorExtractorType.compare("SURF")) + { + de = new SurfDescriptorExtractor(); + } + else if (!descriptorExtractorType.compare("BRIEF")) + { + de = new BriefDescriptorExtractor(); + } + else if ( (pos=descriptorExtractorType.find("Opponent")) == 0) + { + pos += string("Opponent").size(); + de = new OpponentColorDescriptorExtractor( DescriptorExtractor::create(descriptorExtractorType.substr(pos)) ); + } + return de; +} + /****************************************************************************************\ * SiftDescriptorExtractor * \****************************************************************************************/ @@ -231,7 +256,9 @@ int SurfDescriptorExtractor::descriptorType() const \****************************************************************************************/ OpponentColorDescriptorExtractor::OpponentColorDescriptorExtractor( const Ptr& _descriptorExtractor ) : descriptorExtractor(_descriptorExtractor) -{} +{ + CV_Assert( !descriptorExtractor.empty() ); +} void convertBGRImageToOpponentColorSpace( const Mat& bgrImage, vector& opponentChannels ) { @@ -305,7 +332,7 @@ void OpponentColorDescriptorExtractor::computeImpl( const Mat& bgrImage, vector< // Compute descriptors three times, once for each Opponent channel // and concatenate into a single color surf descriptor int descriptorSize = descriptorExtractor->descriptorSize(); - descriptors.create( static_cast(keypoints.size()), 3*descriptorSize, CV_32FC1 ); + descriptors.create( static_cast(keypoints.size()), 3*descriptorSize, descriptorExtractor->descriptorType() ); for( int i = 0; i < 3/*channel count*/; i++ ) { CV_Assert( opponentChannels[i].type() == CV_8UC1 ); @@ -333,34 +360,5 @@ int OpponentColorDescriptorExtractor::descriptorType() const { return descriptorExtractor->descriptorType(); } -/****************************************************************************************\ -* Factory function for descriptor extractor creating * -\****************************************************************************************/ - -Ptr createDescriptorExtractor(const string& descriptorExtractorType) -{ - DescriptorExtractor* de = 0; - if (!descriptorExtractorType.compare("SIFT")) - { - de = new SiftDescriptorExtractor(); - } - else if (!descriptorExtractorType.compare("SURF")) - { - de = new SurfDescriptorExtractor(); - } - else if (!descriptorExtractorType.compare("OpponentSIFT")) - { - de = new OpponentColorDescriptorExtractor(new SiftDescriptorExtractor); - } - else if (!descriptorExtractorType.compare("OpponentSURF")) - { - de = new OpponentColorDescriptorExtractor(new SurfDescriptorExtractor); - } - else if (!descriptorExtractorType.compare("BRIEF")) - { - de = new BriefDescriptorExtractor(); - } - return de; -} } diff --git a/modules/features2d/src/detectors.cpp b/modules/features2d/src/detectors.cpp index 4c42043469..17f6cfc71b 100644 --- a/modules/features2d/src/detectors.cpp +++ b/modules/features2d/src/detectors.cpp @@ -97,6 +97,60 @@ void FeatureDetector::read( const FileNode& ) void FeatureDetector::write( FileStorage& ) const {} +Ptr FeatureDetector::create( const string& detectorType ) +{ + FeatureDetector* fd = 0; + int pos = 0; + + if( !detectorType.compare( "FAST" ) ) + { + fd = new FastFeatureDetector(); + } + else if( !detectorType.compare( "STAR" ) ) + { + fd = new StarFeatureDetector(); + } + else if( !detectorType.compare( "SIFT" ) ) + { + fd = new SiftFeatureDetector(); + } + else if( !detectorType.compare( "SURF" ) ) + { + fd = new SurfFeatureDetector(); + } + else if( !detectorType.compare( "MSER" ) ) + { + fd = new MserFeatureDetector(); + } + else if( !detectorType.compare( "GFTT" ) ) + { + fd = new GoodFeaturesToTrackDetector(); + } + else if( !detectorType.compare( "HARRIS" ) ) + { + GoodFeaturesToTrackDetector::Params params; + params.useHarrisDetector = true; + fd = new GoodFeaturesToTrackDetector(params); + } + else if( (pos=detectorType.find("Grid")) == 0 ) + { + pos += string("Grid").size(); + fd = new GridAdaptedFeatureDetector( FeatureDetector::create(detectorType.substr(pos)) ); + } + else if( (pos=detectorType.find("Pyramid")) == 0 ) + { + pos += string("Pyramid").size(); + fd = new PyramidAdaptedFeatureDetector( FeatureDetector::create(detectorType.substr(pos)) ); + } + else if( (pos=detectorType.find("Dynamic")) == 0 ) + { + pos += string("Dynamic").size(); + fd = new DynamicAdaptedFeatureDetector( AdjusterAdapter::create(detectorType.substr(pos)) ); + } + + return fd; +} + /* * FastFeatureDetector */ @@ -519,53 +573,4 @@ void PyramidAdaptedFeatureDetector::detectImpl( const Mat& image, vector createFeatureDetector( const string& detectorType ) -{ - FeatureDetector* fd = 0; - if( !detectorType.compare( "FAST" ) ) - { - fd = new FastFeatureDetector(); - } - else if( !detectorType.compare( "DynamicFAST" ) ) - { - fd = new DynamicDetector(400,500,5,new FastAdjuster()); - } - else if( !detectorType.compare( "STAR" ) ) - { - fd = new StarFeatureDetector(); - } - else if( !detectorType.compare( "DynamicSTAR" ) ) - { - fd = new DynamicDetector(400,500,5,new StarAdjuster()); - } - else if( !detectorType.compare( "SIFT" ) ) - { - fd = new SiftFeatureDetector(SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(), - SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD()); - } - else if( !detectorType.compare( "SURF" ) ) - { - fd = new SurfFeatureDetector(); - } - else if( !detectorType.compare( "DynamicSURF" ) ) - { - fd =new DynamicDetector(400,500,5,new SurfAdjuster()); - } - else if( !detectorType.compare( "MSER" ) ) - { - fd = new MserFeatureDetector(); - } - else if( !detectorType.compare( "GFTT" ) ) - { - fd = new GoodFeaturesToTrackDetector(); - } - else if( !detectorType.compare( "HARRIS" ) ) - { - GoodFeaturesToTrackDetector::Params params; - params.useHarrisDetector = true; - fd = new GoodFeaturesToTrackDetector(params); - } - return fd; -} - } diff --git a/modules/features2d/src/dynamic.cpp b/modules/features2d/src/dynamic.cpp index 67f64fd96e..6039b9edd3 100644 --- a/modules/features2d/src/dynamic.cpp +++ b/modules/features2d/src/dynamic.cpp @@ -41,14 +41,16 @@ //M*/ #include "precomp.hpp" -namespace cv { -DynamicDetector::DynamicDetector(int min_features, - int max_features, int max_iters, const Ptr& a) : - escape_iters_(max_iters), min_features_(min_features), max_features_( - max_features), adjuster_(a) { -} -void DynamicDetector::detectImpl(const cv::Mat& image, std::vector< - cv::KeyPoint>& keypoints, const cv::Mat& mask) const { +namespace cv +{ + +DynamicAdaptedFeatureDetector::DynamicAdaptedFeatureDetector(const Ptr& a, + int min_features, int max_features, int max_iters ) : + escape_iters_(max_iters), min_features_(min_features), max_features_(max_features), adjuster_(a) +{} + +void DynamicAdaptedFeatureDetector::detectImpl(const Mat& image, vector& keypoints, const Mat& mask) const +{ //for oscillation testing bool down = false; bool up = false; @@ -62,88 +64,131 @@ void DynamicDetector::detectImpl(const cv::Mat& image, std::vector< //break if the desired number hasn't been reached. int iter_count = escape_iters_; - do { + do + { keypoints.clear(); //the adjuster takes care of calling the detector with updated parameters adjuster.detect(image, keypoints,mask); - if (int(keypoints.size()) < min_features_) { + if (int(keypoints.size()) < min_features_) + { down = true; adjuster.tooFew(min_features_, keypoints.size()); - } else if (int(keypoints.size()) > max_features_) { + } + else if (int(keypoints.size()) > max_features_) + { up = true; adjuster.tooMany(max_features_, keypoints.size()); - } else + } + else thresh_good = true; - } while (--iter_count >= 0 && !(down && up) && !thresh_good - && adjuster.good()); + } + while (--iter_count >= 0 && !(down && up) && !thresh_good && adjuster.good()); } FastAdjuster::FastAdjuster(int init_thresh, bool nonmax) : - thresh_(init_thresh), nonmax_(nonmax) { -} -void FastAdjuster::detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask) const { + thresh_(init_thresh), nonmax_(nonmax) +{} + +void FastAdjuster::detectImpl(const Mat& image, vector& keypoints, const Mat& mask) const +{ FastFeatureDetector(thresh_, nonmax_).detect(image, keypoints, mask); } -void FastAdjuster::tooFew(int min, int n_detected) { + +void FastAdjuster::tooFew(int min, int n_detected) +{ //fast is easy to adjust thresh_--; } -void FastAdjuster::tooMany(int max, int n_detected) { + +void FastAdjuster::tooMany(int max, int n_detected) +{ //fast is easy to adjust thresh_++; } //return whether or not the threshhold is beyond //a useful point -bool FastAdjuster::good() const { +bool FastAdjuster::good() const +{ return (thresh_ > 1) && (thresh_ < 200); } StarAdjuster::StarAdjuster(double initial_thresh) : - thresh_(initial_thresh) { -} -void StarAdjuster::detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask) const { + thresh_(initial_thresh) +{} + +void StarAdjuster::detectImpl(const Mat& image, vector& keypoints, const Mat& mask) const +{ StarFeatureDetector detector_tmp(16, thresh_, 10, 8, 3); detector_tmp.detect(image, keypoints, mask); } -void StarAdjuster::tooFew(int min, int n_detected) { + +void StarAdjuster::tooFew(int min, int n_detected) +{ thresh_ *= 0.9; if (thresh_ < 1.1) thresh_ = 1.1; } -void StarAdjuster::tooMany(int max, int n_detected) { + +void StarAdjuster::tooMany(int max, int n_detected) +{ thresh_ *= 1.1; } -bool StarAdjuster::good() const { +bool StarAdjuster::good() const +{ return (thresh_ > 2) && (thresh_ < 200); } SurfAdjuster::SurfAdjuster() : - thresh_(400.0) { -} -void SurfAdjuster::detectImpl(const cv::Mat& image, - std::vector& keypoints, const cv::Mat& mask) const { + thresh_(400.0) +{} + +void SurfAdjuster::detectImpl(const Mat& image, vector& keypoints, const cv::Mat& mask) const +{ SurfFeatureDetector detector_tmp(thresh_); detector_tmp.detect(image, keypoints, mask); } -void SurfAdjuster::tooFew(int min, int n_detected) { + +void SurfAdjuster::tooFew(int min, int n_detected) +{ thresh_ *= 0.9; if (thresh_ < 1.1) thresh_ = 1.1; } -void SurfAdjuster::tooMany(int max, int n_detected) { + +void SurfAdjuster::tooMany(int max, int n_detected) +{ thresh_ *= 1.1; } //return whether or not the threshhold is beyond //a useful point -bool SurfAdjuster::good() const { +bool SurfAdjuster::good() const +{ return (thresh_ > 2) && (thresh_ < 1000); } +Ptr AdjusterAdapter::create( const string& detectorType ) +{ + Ptr adapter; + + if( !detectorType.compare( "FAST" ) ) + { + adapter = new FastAdjuster(); + } + else if( !detectorType.compare( "STAR" ) ) + { + adapter = new StarAdjuster(); + } + else if( !detectorType.compare( "SURF" ) ) + { + adapter = new SurfAdjuster(); + } + + return adapter; +} + } diff --git a/modules/features2d/src/matchers.cpp b/modules/features2d/src/matchers.cpp index b7bfbb88c1..0a99d84c59 100755 --- a/modules/features2d/src/matchers.cpp +++ b/modules/features2d/src/matchers.cpp @@ -322,7 +322,39 @@ bool DescriptorMatcher::isMaskedOut( const vector& masks, int queryIdx ) return !masks.empty() && outCount == masks.size() ; } +/* + * Factory function for DescriptorMatcher creating + */ +Ptr DescriptorMatcher::create( const string& descriptorMatcherType ) +{ + DescriptorMatcher* dm = 0; + if( !descriptorMatcherType.compare( "FlannBased" ) ) + { + dm = new FlannBasedMatcher(); + } + else if( !descriptorMatcherType.compare( "BruteForce" ) ) // L2 + { + dm = new BruteForceMatcher >(); + } + else if( !descriptorMatcherType.compare( "BruteForce-L1" ) ) + { + dm = new BruteForceMatcher >(); + } + else if( !descriptorMatcherType.compare("BruteForce-Hamming") ) + { + dm = new BruteForceMatcher(); + } + else if( !descriptorMatcherType.compare( "BruteForce-HammingLUT") ) + { + dm = new BruteForceMatcher(); + } + + return dm; +} +/* + * BruteForce L2 specialization + */ template<> void BruteForceMatcher >::knnMatchImpl( const Mat& queryDescriptors, vector >& matches, int knn, const vector& masks, bool compactResult ) @@ -585,36 +617,6 @@ void FlannBasedMatcher::radiusMatchImpl( const Mat& queryDescriptors, vector createDescriptorMatcher( const string& descriptorMatcherType ) -{ - DescriptorMatcher* dm = 0; - if( !descriptorMatcherType.compare( "FlannBased" ) ) - { - dm = new FlannBasedMatcher(); - } - else if( !descriptorMatcherType.compare( "BruteForce" ) ) // L2 - { - dm = new BruteForceMatcher >(); - } - else if( !descriptorMatcherType.compare( "BruteForce-L1" ) ) - { - dm = new BruteForceMatcher >(); - } - else if( !descriptorMatcherType.compare("BruteForce-Hamming") ) - { - dm = new BruteForceMatcher(); - } - else if( !descriptorMatcherType.compare( "BruteForce-HammingLUT") ) - { - dm = new BruteForceMatcher(); - } - - return dm; -} - /****************************************************************************************\ * GenericDescriptorMatcher * \****************************************************************************************/ @@ -847,6 +849,34 @@ void GenericDescriptorMatcher::read( const FileNode& ) void GenericDescriptorMatcher::write( FileStorage& ) const {} +/* + * Factory function for GenericDescriptorMatch creating + */ +Ptr GenericDescriptorMatcher::create( const string& genericDescritptorMatcherType, + const string ¶msFilename ) +{ + Ptr descriptorMatcher; + if( ! genericDescritptorMatcherType.compare("ONEWAY") ) + { + descriptorMatcher = new OneWayDescriptorMatcher(); + } + else if( ! genericDescritptorMatcherType.compare("FERN") ) + { + descriptorMatcher = new FernDescriptorMatcher(); + } + + if( !paramsFilename.empty() && !descriptorMatcher.empty() ) + { + FileStorage fs = FileStorage( paramsFilename, FileStorage::READ ); + if( fs.isOpened() ) + { + descriptorMatcher->read( fs.root() ); + fs.release(); + } + } + return descriptorMatcher; +} + /****************************************************************************************\ * OneWayDescriptorMatcher * \****************************************************************************************/ @@ -1238,32 +1268,4 @@ Ptr VectorDescriptorMatcher::clone( bool emptyTrainDat return new VectorDescriptorMatcher( extractor, matcher->clone(emptyTrainData) ); } -/* - * Factory function for GenericDescriptorMatch creating - */ -Ptr createGenericDescriptorMatcher( const string& genericDescritptorMatcherType, - const string ¶msFilename ) -{ - Ptr descriptorMatcher; - if( ! genericDescritptorMatcherType.compare("ONEWAY") ) - { - descriptorMatcher = new OneWayDescriptorMatcher(); - } - else if( ! genericDescritptorMatcherType.compare("FERN") ) - { - descriptorMatcher = new FernDescriptorMatcher(); - } - - if( !paramsFilename.empty() && !descriptorMatcher.empty() ) - { - FileStorage fs = FileStorage( paramsFilename, FileStorage::READ ); - if( fs.isOpened() ) - { - descriptorMatcher->read( fs.root() ); - fs.release(); - } - } - return descriptorMatcher; -} - } diff --git a/samples/cpp/bagofwords_classification.cpp b/samples/cpp/bagofwords_classification.cpp index 5c621e981c..ed5a812733 100644 --- a/samples/cpp/bagofwords_classification.cpp +++ b/samples/cpp/bagofwords_classification.cpp @@ -2552,8 +2552,8 @@ int main(int argc, char** argv) } // Create detector, descriptor, matcher. - Ptr featureDetector = createFeatureDetector( ddmParams.detectorType ); - Ptr descExtractor = createDescriptorExtractor( ddmParams.descriptorType ); + Ptr featureDetector = FeatureDetector::create( ddmParams.detectorType ); + Ptr descExtractor = DescriptorExtractor::create( ddmParams.descriptorType ); Ptr bowExtractor; if( featureDetector.empty() || descExtractor.empty() ) { @@ -2561,7 +2561,7 @@ int main(int argc, char** argv) return -1; } { - Ptr descMatcher = createDescriptorMatcher( ddmParams.matcherType ); + Ptr descMatcher = DescriptorMatcher::create( ddmParams.matcherType ); if( featureDetector.empty() || descExtractor.empty() || descMatcher.empty() ) { cout << "descMatcher was not created" << endl; diff --git a/samples/cpp/build3dmodel.cpp b/samples/cpp/build3dmodel.cpp index b910e2bc9b..103f9746d2 100644 --- a/samples/cpp/build3dmodel.cpp +++ b/samples/cpp/build3dmodel.cpp @@ -651,8 +651,8 @@ int main(int argc, char** argv) Size calibratedImageSize; readCameraMatrix(intrinsicsFilename, cameraMatrix, distCoeffs, calibratedImageSize); - Ptr detector = createFeatureDetector(detectorName); - Ptr descriptorExtractor = createDescriptorExtractor(descriptorExtractorName); + Ptr detector = FeatureDetector::create(detectorName); + Ptr descriptorExtractor = DescriptorExtractor::create(descriptorExtractorName); string modelIndexFilename = format("%s_segm/frame_index.yml", modelName); if(!readModelViews( modelIndexFilename, modelBox, imageList, roiList, poseList)) diff --git a/samples/cpp/descriptor_extractor_matcher.cpp b/samples/cpp/descriptor_extractor_matcher.cpp index 275b78bb4a..c7e88b96d0 100644 --- a/samples/cpp/descriptor_extractor_matcher.cpp +++ b/samples/cpp/descriptor_extractor_matcher.cpp @@ -223,9 +223,9 @@ int main(int argc, char** argv) ransacReprojThreshold = atof(argv[7]); cout << "< Creating detector, descriptor extractor and descriptor matcher ..." << endl; - Ptr detector = createFeatureDetector( argv[1] ); - Ptr descriptorExtractor = createDescriptorExtractor( argv[2] ); - Ptr descriptorMatcher = createDescriptorMatcher( argv[3] ); + Ptr detector = FeatureDetector::create( argv[1] ); + Ptr descriptorExtractor = DescriptorExtractor::create( argv[2] ); + Ptr descriptorMatcher = DescriptorMatcher::create( argv[3] ); int mactherFilterType = getMatcherFilterType( argv[4] ); bool eval = !isWarpPerspective ? false : (atoi(argv[6]) == 0 ? false : true); cout << ">" << endl; diff --git a/samples/cpp/generic_descriptor_match.cpp b/samples/cpp/generic_descriptor_match.cpp index 30966a60df..c6ce5f06e6 100644 --- a/samples/cpp/generic_descriptor_match.cpp +++ b/samples/cpp/generic_descriptor_match.cpp @@ -29,7 +29,7 @@ int main(int argc, char** argv) std::string alg_name = std::string(argv[3]); std::string params_filename = std::string(argv[4]); - Ptr descriptorMatcher = createGenericDescriptorMatcher(alg_name, params_filename); + Ptr descriptorMatcher = GenericDescriptorMatcher::create(alg_name, params_filename); if( descriptorMatcher == 0 ) { printf ("Cannot create descriptor\n"); diff --git a/samples/cpp/matching_to_many_images.cpp b/samples/cpp/matching_to_many_images.cpp index 7e68b25f5b..345594e53a 100644 --- a/samples/cpp/matching_to_many_images.cpp +++ b/samples/cpp/matching_to_many_images.cpp @@ -62,9 +62,9 @@ bool createDetectorDescriptorMatcher( const string& detectorType, const string& Ptr& descriptorMatcher ) { cout << "< Creating feature detector, descriptor extractor and descriptor matcher ..." << endl; - featureDetector = createFeatureDetector( detectorType ); - descriptorExtractor = createDescriptorExtractor( descriptorType ); - descriptorMatcher = createDescriptorMatcher( matcherType ); + featureDetector = FeatureDetector::create( detectorType ); + descriptorExtractor = DescriptorExtractor::create( descriptorType ); + descriptorMatcher = DescriptorMatcher::create( matcherType ); cout << ">" << endl; bool isCreated = !( featureDetector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty() ); diff --git a/tests/cv/src/adetectordescriptor_evaluation.cpp b/tests/cv/src/adetectordescriptor_evaluation.cpp index f715df4124..071114ee89 100644 --- a/tests/cv/src/adetectordescriptor_evaluation.cpp +++ b/tests/cv/src/adetectordescriptor_evaluation.cpp @@ -686,8 +686,8 @@ inline void readKeypoints( FileStorage& fs, vector& keypoints, int img void DetectorQualityTest::readAlgorithm () { - defaultDetector = createFeatureDetector( algName ); - specificDetector = createFeatureDetector( algName ); + defaultDetector = FeatureDetector::create( algName ); + specificDetector = FeatureDetector::create( algName ); if( defaultDetector == 0 ) { ts->printf(CvTS::LOG, "Algorithm can not be read\n"); @@ -960,13 +960,13 @@ void DescriptorQualityTest::writePlotData( int di ) const void DescriptorQualityTest::readAlgorithm( ) { - defaultDescMatcher = createGenericDescriptorMatcher( algName ); - specificDescMatcher = createGenericDescriptorMatcher( algName ); + defaultDescMatcher = GenericDescriptorMatcher::create( algName ); + specificDescMatcher = GenericDescriptorMatcher::create( algName ); if( defaultDescMatcher == 0 ) { - Ptr extractor = createDescriptorExtractor( algName ); - Ptr matcher = createDescriptorMatcher( matcherName ); + Ptr extractor = DescriptorExtractor::create( algName ); + Ptr matcher = DescriptorMatcher::create( matcherName ); defaultDescMatcher = new VectorDescriptorMatch( extractor, matcher ); specificDescMatcher = new VectorDescriptorMatch( extractor, matcher ); diff --git a/tests/cv/src/afeatures2d.cpp b/tests/cv/src/afeatures2d.cpp index c7d07e009a..946fa72535 100644 --- a/tests/cv/src/afeatures2d.cpp +++ b/tests/cv/src/afeatures2d.cpp @@ -73,6 +73,7 @@ protected: void CV_FeatureDetectorTest::emptyDataTest() { + // One image. Mat image; vector keypoints; try @@ -81,14 +82,28 @@ void CV_FeatureDetectorTest::emptyDataTest() } catch(...) { - ts->printf( CvTS::LOG, "emptyDataTest: Detect() on empty image must not generate exception\n" ); + ts->printf( CvTS::LOG, "detect() on empty image must not generate exception (1)\n" ); ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); return; } if( !keypoints.empty() ) { - ts->printf( CvTS::LOG, "emptyDataTest: Detect() on empty image must return empty keypoints vector\n" ); + ts->printf( CvTS::LOG, "detect() on empty image must return empty keypoints vector (1)\n" ); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); + return; + } + + // Several images. + vector images; + vector > keypointCollection; + try + { + fdetector->detect( images, keypointCollection ); + } + catch(...) + { + ts->printf( CvTS::LOG, "detect() on empty image vector must not generate exception (2)\n" ); ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); return; } @@ -120,7 +135,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector& validK { ts->printf( CvTS::LOG, "Bad keypoints count ratio (validCount = %d, calcCount = %d)!\n", validKeypoints.size(), calcKeypoints.size() ); - ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY ); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); return; } @@ -146,7 +161,7 @@ void CV_FeatureDetectorTest::compareKeypointSets( const vector& validK if( !isSimilarKeypoints( validKeypoints[v], calcKeypoints[nearestIdx] ) ) badPointCount++; } - ts->printf( CvTS::LOG, "regressionTest: badPointCount = %d; validPointCount = %d; calcPointCount = %d\n", + ts->printf( CvTS::LOG, "badPointCount = %d; validPointCount = %d; calcPointCount = %d\n", badPointCount, validKeypoints.size(), calcKeypoints.size() ); if( badPointCount > 0.9 * commonPointCount ) { @@ -164,7 +179,7 @@ void CV_FeatureDetectorTest::regressionTest() string resFilename = string(ts->get_data_path()) + DETECTOR_DIR + "/" + string(name) + ".xml.gz"; // Read the test image. - Mat image = imread( imgFilename, 0 ); + Mat image = imread( imgFilename ); if( image.empty() ) { ts->printf( CvTS::LOG, "image %s can not be read \n", imgFilename.c_str() ); @@ -241,8 +256,9 @@ static void writeMatInBin( const Mat& mat, const string& filename ) fwrite( (void*)&mat.rows, sizeof(int), 1, f ); fwrite( (void*)&mat.cols, sizeof(int), 1, f ); fwrite( (void*)&type, sizeof(int), 1, f ); - fwrite( (void*)&mat.step, sizeof(int), 1, f ); - fwrite( (void*)mat.data, 1, mat.step*mat.rows, f ); + int dataSize = mat.step * mat.rows * mat.channels(); + fwrite( (void*)&dataSize, sizeof(int), 1, f ); + fwrite( (void*)mat.data, 1, dataSize, f ); fclose(f); } } @@ -252,14 +268,14 @@ static Mat readMatFromBin( const string& filename ) FILE* f = fopen( filename.c_str(), "rb" ); if( f ) { - int rows, cols, type, step; + int rows, cols, type, dataSize; fread( (void*)&rows, sizeof(int), 1, f ); fread( (void*)&cols, sizeof(int), 1, f ); fread( (void*)&type, sizeof(int), 1, f ); - fread( (void*)&step, sizeof(int), 1, f ); + fread( (void*)&dataSize, sizeof(int), 1, f ); - uchar* data = (uchar*)cvAlloc(step*rows); - fread( (void*)data, 1, step*rows, f ); + uchar* data = (uchar*)cvAlloc(dataSize); + fread( (void*)data, 1, dataSize, f ); fclose(f); return Mat( rows, cols, type, data ); @@ -300,7 +316,7 @@ protected: if( dist > maxDistDif) { stringstream ss; - ss << "Discance between valid and computed " << y << "-descriptors > " << maxDistDif << endl; + ss << "Discance between valid and computed " << y << "-descriptors " << dist << ">" << maxDistDif << endl; ts->printf(CvTS::LOG, ss.str().c_str() ); ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY ); return; @@ -309,13 +325,15 @@ protected: maxDist = dist; } stringstream ss; - ss << "regressionTest: Max discance between valid and computed descriptors " << maxDist << endl; + ss << "Max distance between valid and computed descriptors " << maxDist << endl; ts->printf(CvTS::LOG, ss.str().c_str() ); } void emptyDataTest() { assert( !dextractor.empty() ); + + // One image. Mat image; vector keypoints; Mat descriptors; @@ -326,7 +344,7 @@ protected: } catch(...) { - ts->printf( CvTS::LOG, "emptyDataTest: compute() on empty image and empty keypoints must not generate exception\n"); + ts->printf( CvTS::LOG, "compute() on empty image and empty keypoints must not generate exception (1)\n"); ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA ); } @@ -337,7 +355,21 @@ protected: } catch(...) { - ts->printf( CvTS::LOG, "emptyDataTest: compute() on nonempty image and empty keypoints must not generate exception\n"); + ts->printf( CvTS::LOG, "compute() on nonempty image and empty keypoints must not generate exception (1)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA ); + } + + // Several images. + vector images; + vector > keypointsCollection; + vector descriptorsCollection; + try + { + dextractor->compute( images, keypointsCollection, descriptorsCollection ); + } + catch(...) + { + ts->printf( CvTS::LOG, "compute() on empty images and empty keypoints collection must not generate exception (2)\n"); ts->set_failed_test_info( CvTS::FAIL_INVALID_TEST_DATA ); } } @@ -348,7 +380,8 @@ protected: // Read the test image. string imgFilename = string(ts->get_data_path()) + FEATURES2D_DIR + "/" + IMAGE_FILENAME; - Mat img = imread( imgFilename, 0 ); + + Mat img = imread( imgFilename ); if( img.empty() ) { ts->printf( CvTS::LOG, "image %s can not be read\n", imgFilename.c_str() ); @@ -366,7 +399,7 @@ protected: double t = (double)getTickCount(); dextractor->compute( img, keypoints, calcDescriptors ); t = getTickCount() - t; - ts->printf(CvTS::LOG, "\nregressionTest: Average time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime ); + ts->printf(CvTS::LOG, "\nAverage time of computiting one descriptor = %g ms (previous time = %g ms)\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime ); if( calcDescriptors.rows != (int)keypoints.size() ) { @@ -486,13 +519,20 @@ protected: virtual void run( int ); void generateData( Mat& query, Mat& train ); - int testMatch( const Mat& query, const Mat& train ); - int testKnnMatch( const Mat& query, const Mat& train ); - int testRadiusMatch( const Mat& query, const Mat& train ); + void emptyDataTest(); + void matchTest( const Mat& query, const Mat& train ); + void knnMatchTest( const Mat& query, const Mat& train ); + void radiusMatchTest( const Mat& query, const Mat& train ); Ptr dmatcher; }; +void CV_DescriptorMatcherTest::emptyDataTest() +{ + assert( !dmatcher.empty() ); + +} + void CV_DescriptorMatcherTest::generateData( Mat& query, Mat& train ) { RNG& rng = theRNG(); @@ -525,21 +565,19 @@ void CV_DescriptorMatcherTest::generateData( Mat& query, Mat& train ) } } -int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train ) +void CV_DescriptorMatcherTest::matchTest( const Mat& query, const Mat& train ) { dmatcher->clear(); // test const version of match() - int res = CvTS::OK; { vector matches; dmatcher->match( query, train, matches ); - int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (1)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } else { @@ -552,12 +590,11 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train ) } if( (float)badCount > (float)queryDescCount*badPart ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (1)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } } - res = curRes != CvTS::OK ? curRes : res; } // test version of match() with add() @@ -577,11 +614,10 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train ) dmatcher->match( query, matches, masks ); - int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test match() function (2)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } else { @@ -607,30 +643,27 @@ int CV_DescriptorMatcherTest::testMatch( const Mat& query, const Mat& train ) { ts->printf( CvTS::LOG, "%f - too large bad matches part while test match() function (2)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY ); } } - res = curRes != CvTS::OK ? curRes : res; } - return res; } -int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train ) +void CV_DescriptorMatcherTest::knnMatchTest( const Mat& query, const Mat& train ) { dmatcher->clear(); // test const version of knnMatch() - int res = CvTS::OK; { const int knn = 3; vector > matches; dmatcher->knnMatch( query, train, matches, knn ); - int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (1)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } else { @@ -653,12 +686,11 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train ) } if( (float)badCount > (float)queryDescCount*badPart ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (1)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } } - res = curRes != CvTS::OK ? curRes : res; } // test version of knnMatch() with add() @@ -679,11 +711,10 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train ) dmatcher->knnMatch( query, matches, knn, masks ); - int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test knnMatch() function (2)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } else { @@ -721,28 +752,25 @@ int CV_DescriptorMatcherTest::testKnnMatch( const Mat& query, const Mat& train ) { ts->printf( CvTS::LOG, "%f - too large bad matches part while test knnMatch() function (2)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY ); } } - res = curRes != CvTS::OK ? curRes : res; } - return res; } -int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& train ) +void CV_DescriptorMatcherTest::radiusMatchTest( const Mat& query, const Mat& train ) { dmatcher->clear(); // test const version of match() - int res = CvTS::OK; { const float radius = 1.f/countFactor; vector > matches; dmatcher->radiusMatch( query, train, matches, radius ); - int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } else { @@ -760,12 +788,11 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai } if( (float)badCount > (float)queryDescCount*badPart ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (1)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } } - res = curRes != CvTS::OK ? curRes : res; } // test version of match() with add() @@ -790,10 +817,9 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai int curRes = CvTS::OK; if( (int)matches.size() != queryDescCount ) { - curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf(CvTS::LOG, "Incorrect matches count while test radiusMatch() function (1)\n"); + ts->set_failed_test_info( CvTS::FAIL_INVALID_OUTPUT ); } - res = curRes != CvTS::OK ? curRes : res; int badCount = 0; int shift = dmatcher->isMaskSupported() ? 1 : 0; @@ -831,10 +857,9 @@ int CV_DescriptorMatcherTest::testRadiusMatch( const Mat& query, const Mat& trai curRes = CvTS::FAIL_INVALID_OUTPUT; ts->printf( CvTS::LOG, "%f - too large bad matches part while test radiusMatch() function (2)\n", (float)badCount/(float)queryDescCount ); + ts->set_failed_test_info( CvTS::FAIL_BAD_ACCURACY ); } - res = curRes != CvTS::OK ? curRes : res; } - return res; } void CV_DescriptorMatcherTest::run( int ) @@ -842,18 +867,11 @@ void CV_DescriptorMatcherTest::run( int ) Mat query, train; generateData( query, train ); - int res = CvTS::OK, curRes; - - curRes = testMatch( query, train ); - res = curRes != CvTS::OK ? curRes : res; + matchTest( query, train ); - curRes = testKnnMatch( query, train ); - res = curRes != CvTS::OK ? curRes : res; + knnMatchTest( query, train ); - curRes = testRadiusMatch( query, train ); - res = curRes != CvTS::OK ? curRes : res; - - ts->set_failed_test_info( res ); + radiusMatchTest( query, train ); } /****************************************************************************************\ @@ -862,31 +880,33 @@ void CV_DescriptorMatcherTest::run( int ) /* * Detectors - * "detector-fast, detector-gftt, detector-harris, detector-mser, detector-sift, detector-star, detector-surf" + * "detector-fast, detector-gftt, detector-harris, detector-mser, detector-sift, detector-star, detector-surf, detector-grid-fast, detector-pyramid-fast" */ -CV_FeatureDetectorTest fastTest( "detector-fast", createFeatureDetector("FAST") ); -CV_FeatureDetectorTest gfttTest( "detector-gftt", createFeatureDetector("GFTT") ); -CV_FeatureDetectorTest harrisTest( "detector-harris", createFeatureDetector("HARRIS") ); -CV_FeatureDetectorTest mserTest( "detector-mser", createFeatureDetector("MSER") ); -CV_FeatureDetectorTest siftTest( "detector-sift", createFeatureDetector("SIFT") ); -CV_FeatureDetectorTest starTest( "detector-star", createFeatureDetector("STAR") ); -CV_FeatureDetectorTest surfTest( "detector-surf", createFeatureDetector("SURF") ); +CV_FeatureDetectorTest fastTest( "detector-fast", FeatureDetector::create("FAST") ); +CV_FeatureDetectorTest gfttTest( "detector-gftt", FeatureDetector::create("GFTT") ); +CV_FeatureDetectorTest harrisTest( "detector-harris", FeatureDetector::create("HARRIS") ); +CV_FeatureDetectorTest mserTest( "detector-mser", FeatureDetector::create("MSER") ); +CV_FeatureDetectorTest siftTest( "detector-sift", FeatureDetector::create("SIFT") ); +CV_FeatureDetectorTest starTest( "detector-star", FeatureDetector::create("STAR") ); +CV_FeatureDetectorTest surfTest( "detector-surf", FeatureDetector::create("SURF") ); +CV_FeatureDetectorTest gridFastfTest( "detector-grid-fast", FeatureDetector::create("GridFAST") ); +CV_FeatureDetectorTest pyramidFastTest( "detector-pyramid-fast", FeatureDetector::create("PyramidFAST") ); /* * Descriptors - * "descriptor-sift, descriptor-surf, descriptor-calonder-uchar, descriptor-calonder-float, descriptor-brief" + * "descriptor-sift, descriptor-surf, descriptor-calonder-uchar, descriptor-calonder-float, descriptor-brief, descriptor-opponent-sift, descriptor-opponent-surf" */ CV_DescriptorExtractorTest > siftDescriptorTest( "descriptor-sift", 0.03f, - createDescriptorExtractor("SIFT"), 8.06652f ); + DescriptorExtractor::create("SIFT"), 8.06652f ); CV_DescriptorExtractorTest > surfDescriptorTest( "descriptor-surf", 0.035f, - createDescriptorExtractor("SURF"), 0.147372f ); + DescriptorExtractor::create("SURF"), 0.147372f ); CV_DescriptorExtractorTest briefDescriptorTest( "descriptor-brief", 1, - createDescriptorExtractor("BRIEF"), 0.00527548 ); + DescriptorExtractor::create("BRIEF"), 0.00527548 ); -//CV_DescriptorExtractorTest oppSiftDescriptorTest( "descriptor-opponent-sift", 0.008f, -// createDescriptorExtractor("OpponentSIFT"), 8.06652f ); -//CV_DescriptorExtractorTest oppurfDescriptorTest( "descriptor-opponent-surf", 0.02f, -// createDescriptorExtractor("OpponentSURF"), 0.147372f ); +CV_DescriptorExtractorTest > oppSiftDescriptorTest( "descriptor-opponent-sift", 0.008f, + DescriptorExtractor::create("OpponentSIFT"), 8.06652f ); +CV_DescriptorExtractorTest > oppurfDescriptorTest( "descriptor-opponent-surf", 0.02f, + DescriptorExtractor::create("OpponentSURF"), 0.147372f ); #if CV_SSE2 CV_CalonderDescriptorExtractorTest > ucharCalonderTest( "descriptor-calonder-uchar", @@ -899,8 +919,10 @@ CV_CalonderDescriptorExtractorTest > floatCalonderTest( "descri /* * Matchers + * "descriptor-matcher-brute-force, descriptor-matcher-flann-based" */ CV_DescriptorMatcherTest bruteForceMatcherTest( "descriptor-matcher-brute-force", new BruteForceMatcher >, 0.01f ); CV_DescriptorMatcherTest flannBasedMatcherTest( "descriptor-matcher-flann-based", new FlannBasedMatcher, 0.04f ); +