DescriptorExtractor: added defaultNorm() to return default norm type.
authorPeter Andreas Entschev <peter@entschev.com>
Wed, 27 Nov 2013 19:58:40 +0000 (17:58 -0200)
committerPeter Andreas Entschev <peter@entschev.com>
Mon, 9 Dec 2013 11:54:42 +0000 (09:54 -0200)
Added the defaultNorm() method to the DescriptorExtractor class. This method returns the default norm type for each descriptor type. The tests and C/C++ samples were updated to get the norm type directly from the DescriptorExtractor inherited classes.

This was reported in feature report #2182 (http://code.opencv.org/issues/2182). It will make it possible to get the norm type usually applied matching method for each descriptor, instead of passing it manually.

29 files changed:
modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst
modules/features2d/include/opencv2/features2d.hpp
modules/features2d/src/brief.cpp
modules/features2d/src/brisk.cpp
modules/features2d/src/descriptors.cpp
modules/features2d/src/freak.cpp
modules/features2d/src/orb.cpp
modules/features2d/test/test_rotation_and_scale_invariance.cpp
modules/legacy/doc/common_interfaces_of_descriptor_extractors.rst
modules/legacy/include/opencv2/legacy.hpp
modules/nonfree/include/opencv2/nonfree/cuda.hpp
modules/nonfree/include/opencv2/nonfree/features2d.hpp
modules/nonfree/include/opencv2/nonfree/ocl.hpp
modules/nonfree/src/sift.cpp
modules/nonfree/src/surf.cpp
modules/nonfree/src/surf.cuda.cpp
modules/nonfree/src/surf.ocl.cpp
modules/nonfree/test/test_features2d.cpp
modules/nonfree/test/test_surf.cuda.cpp
modules/nonfree/test/test_surf.ocl.cpp
samples/c/find_obj_calonder.cpp
samples/cpp/brief_match_test.cpp
samples/cpp/detector_descriptor_evaluation.cpp
samples/cpp/freak_demo.cpp
samples/cpp/matcher_simple.cpp
samples/cpp/shape_transformation.cpp
samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp
samples/cpp/video_homography.cpp
samples/gpu/surf_keypoint_matcher.cpp

index 83688c0..bf84ed0 100644 (file)
@@ -35,6 +35,7 @@ Abstract base class for computing descriptors for image keypoints. ::
 
         virtual int descriptorSize() const = 0;
         virtual int descriptorType() const = 0;
+        virtual int defaultNorm() const = 0;
 
         static Ptr<DescriptorExtractor> create( const String& descriptorExtractorType );
 
@@ -114,6 +115,7 @@ them into a single color descriptor. ::
         virtual void write( FileStorage& ) const;
         virtual int descriptorSize() const;
         virtual int descriptorType() const;
+        virtual int defaultNorm() const;
     protected:
         ...
     };
@@ -141,6 +143,7 @@ Strecha C., Fua P. *BRIEF: Binary Robust Independent Elementary Features* ,
         virtual void write( FileStorage& ) const;
         virtual int descriptorSize() const;
         virtual int descriptorType() const;
+        virtual int defaultNorm() const;
     protected:
         ...
     };
index 9cbae22..75b591c 100644 (file)
@@ -169,6 +169,7 @@ public:
 
     CV_WRAP virtual int descriptorSize() const = 0;
     CV_WRAP virtual int descriptorType() const = 0;
+    CV_WRAP virtual int defaultNorm() const = 0;
 
     CV_WRAP virtual bool empty() const;
 
@@ -226,6 +227,8 @@ public:
     int descriptorSize() const;
     // returns the descriptor type
     int descriptorType() const;
+    // returns the default norm type
+    int defaultNorm() const;
 
     // Compute the BRISK features on an image
     void operator()(InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints) const;
@@ -320,6 +323,8 @@ public:
     int descriptorSize() const;
     // returns the descriptor type
     int descriptorType() const;
+    // returns the default norm type
+    int defaultNorm() const;
 
     // Compute the ORB features and descriptors on an image
     void operator()(InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints) const;
@@ -377,6 +382,9 @@ public:
     /** returns the descriptor type */
     virtual int descriptorType() const;
 
+    /** returns the default norm type */
+    virtual int defaultNorm() const;
+
     /** select the 512 "best description pairs"
          * @param images grayscale images set
          * @param keypoints set of detected keypoints
@@ -837,6 +845,7 @@ public:
 
     virtual int descriptorSize() const;
     virtual int descriptorType() const;
+    virtual int defaultNorm() const;
 
     virtual bool empty() const;
 
@@ -863,6 +872,7 @@ public:
 
     virtual int descriptorSize() const;
     virtual int descriptorType() const;
+    virtual int defaultNorm() const;
 
     /// @todo read and write for brief
 
index a429451..2521919 100644 (file)
@@ -125,6 +125,11 @@ int BriefDescriptorExtractor::descriptorType() const
     return CV_8UC1;
 }
 
+int BriefDescriptorExtractor::defaultNorm() const
+{
+    return NORM_HAMMING;
+}
+
 void BriefDescriptorExtractor::read( const FileNode& fn)
 {
     int dSize = fn["descriptorSize"];
index 76bded6..a3c5d7e 100644 (file)
@@ -712,6 +712,12 @@ BRISK::descriptorType() const
   return CV_8U;
 }
 
+int
+BRISK::defaultNorm() const
+{
+  return NORM_HAMMING;
+}
+
 BRISK::~BRISK()
 {
   delete[] patternPoints_;
index b79768a..9e0ac5c 100644 (file)
@@ -247,6 +247,11 @@ int OpponentColorDescriptorExtractor::descriptorType() const
     return descriptorExtractor->descriptorType();
 }
 
+int OpponentColorDescriptorExtractor::defaultNorm() const
+{
+    return descriptorExtractor->defaultNorm();
+}
+
 bool OpponentColorDescriptorExtractor::empty() const
 {
     return !descriptorExtractor || descriptorExtractor->empty();
index 086a2e2..4aca4c1 100644 (file)
@@ -623,4 +623,9 @@ int FREAK::descriptorType() const {
     return CV_8U;
 }
 
+int FREAK::defaultNorm() const
+{
+    return NORM_HAMMING;
+}
+
 } // END NAMESPACE CV
index a6e8ffa..ed9716d 100644 (file)
@@ -575,6 +575,11 @@ int ORB::descriptorType() const
     return CV_8U;
 }
 
+int ORB::defaultNorm() const
+{
+    return NORM_HAMMING;
+}
+
 /** Compute the ORB features and descriptors on an image
  * @param img the image to compute the features and descriptors on
  * @param mask the mask to apply
index adfe428..2fe59ca 100644 (file)
@@ -616,8 +616,8 @@ TEST(Features2d_RotationInvariance_Detector_ORB, regression)
 TEST(Features2d_RotationInvariance_Descriptor_BRISK, regression)
 {
     DescriptorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.BRISK"),
-                      Algorithm::create<DescriptorExtractor>("Feature2D.BRISK"),
-                        NORM_HAMMING,
+                                          Algorithm::create<DescriptorExtractor>("Feature2D.BRISK"),
+                                          Algorithm::create<DescriptorExtractor>("Feature2D.BRISK")->defaultNorm(),
                                           0.99f);
     test.safe_run();
 }
@@ -626,7 +626,7 @@ TEST(Features2d_RotationInvariance_Descriptor_ORB, regression)
 {
     DescriptorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
                                           Algorithm::create<DescriptorExtractor>("Feature2D.ORB"),
-                                          NORM_HAMMING,
+                                          Algorithm::create<DescriptorExtractor>("Feature2D.ORB")->defaultNorm(),
                                           0.99f);
     test.safe_run();
 }
@@ -635,7 +635,7 @@ TEST(Features2d_RotationInvariance_Descriptor_ORB, regression)
 //{
 //    DescriptorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
 //                                          Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
-//                                          NORM_HAMMING,
+//                                          Algorithm::create<DescriptorExtractor>("Feature2D.FREAK")->defaultNorm(),
 //                                          0.f);
 //    test.safe_run();
 //}
@@ -667,26 +667,26 @@ TEST(Features2d_ScaleInvariance_Detector_BRISK, regression)
 //TEST(Features2d_ScaleInvariance_Descriptor_BRISK, regression)
 //{
 //    DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.BRISK"),
-//                   Algorithm::create<DescriptorExtractor>("Feature2D.BRISK"),
-//                   NORM_HAMMING,
-//                                     0.99f);
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.BRISK"),
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.BRISK")->defaultNorm(),
+//                                       0.99f);
 //    test.safe_run();
 //}
 
 //TEST(Features2d_ScaleInvariance_Descriptor_ORB, regression)
 //{
 //    DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
-//                                                                      Algorithm::create<DescriptorExtractor>("Feature2D.ORB"),
-//                                                                      NORM_HAMMING,
-//                                     0.01f);
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.ORB"),
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.ORB")->defaultNorm(),
+//                                       0.01f);
 //    test.safe_run();
 //}
 
 //TEST(Features2d_ScaleInvariance_Descriptor_FREAK, regression)
 //{
 //    DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
-//                                     Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
-//                                     NORM_HAMMING,
-//                                     0.01f);
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
+//                                       Algorithm::create<DescriptorExtractor>("Feature2D.FREAK")->defaultNorm(),
+//                                       0.01f);
 //    test.safe_run();
 //}
index 4f13385..2b59a4e 100644 (file)
@@ -28,6 +28,7 @@ Wrapping class for computing descriptors by using the
         virtual void write( FileStorage &fs ) const;
         virtual int descriptorSize() const;
         virtual int descriptorType() const;
+        virtual int defaultNorm() const;
     protected:
         ...
     }
index ed0ac9c..01f726b 100644 (file)
@@ -2765,6 +2765,7 @@ public:
 
     virtual int descriptorSize() const { return classifier_.classes(); }
     virtual int descriptorType() const { return DataType<T>::type; }
+    virtual int defaultNorm() const { return NORM_L1; }
 
     virtual bool empty() const;
 
index 1a5d3b9..0e1f8e5 100644 (file)
@@ -70,6 +70,8 @@ public:
 
     //! returns the descriptor size in float's (64 or 128)
     int descriptorSize() const;
+    //! returns the default norm type
+    int defaultNorm() const;
 
     //! upload host keypoints to device memory
     void uploadKeypoints(const std::vector<KeyPoint>& keypoints, GpuMat& keypointsGPU);
index 4acd747..88a1731 100644 (file)
@@ -66,6 +66,9 @@ public:
     //! returns the descriptor type
     CV_WRAP int descriptorType() const;
 
+    //! returns the default norm type
+    CV_WRAP int defaultNorm() const;
+
     //! finds the keypoints using SIFT algorithm
     void operator()(InputArray img, InputArray mask,
                     std::vector<KeyPoint>& keypoints) const;
@@ -118,6 +121,9 @@ public:
     //! returns the descriptor type
     CV_WRAP int descriptorType() const;
 
+    //! returns the descriptor type
+    CV_WRAP int defaultNorm() const;
+
     //! finds the keypoints using fast hessian detector used in SURF
     void operator()(InputArray img, InputArray mask,
                     CV_OUT std::vector<KeyPoint>& keypoints) const;
index 22b40ae..b06fa39 100644 (file)
@@ -76,6 +76,8 @@ namespace cv
 
             //! returns the descriptor size in float's (64 or 128)
             int descriptorSize() const;
+            //! returns the default norm type
+            int defaultNorm() const;
             //! upload host keypoints to device memory
             void uploadKeypoints(const std::vector<cv::KeyPoint> &keypoints, oclMat &keypointsocl);
             //! download keypoints from device to host memory
index e67138c..4a36c2d 100644 (file)
@@ -717,6 +717,11 @@ int SIFT::descriptorType() const
     return CV_32F;
 }
 
+int SIFT::defaultNorm() const
+{
+    return NORM_L2;
+}
+
 
 void SIFT::operator()(InputArray _image, InputArray _mask,
                       std::vector<KeyPoint>& keypoints) const
index 98d1449..be8d14d 100644 (file)
@@ -884,6 +884,7 @@ SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended,
 
 int SURF::descriptorSize() const { return extended ? 128 : 64; }
 int SURF::descriptorType() const { return CV_32F; }
+int SURF::defaultNorm() const { return NORM_L2; }
 
 void SURF::operator()(InputArray imgarg, InputArray maskarg,
                       CV_OUT std::vector<KeyPoint>& keypoints) const
index 2912d04..4089b50 100644 (file)
@@ -265,6 +265,11 @@ int cv::cuda::SURF_CUDA::descriptorSize() const
     return extended ? 128 : 64;
 }
 
+int cv::cuda::SURF_CUDA::defaultNorm() const
+{
+    return NORM_L2;
+}
+
 void cv::cuda::SURF_CUDA::uploadKeypoints(const std::vector<KeyPoint>& keypoints, GpuMat& keypointsGPU)
 {
     if (keypoints.empty())
index 3b30663..5ade5e5 100644 (file)
@@ -299,6 +299,11 @@ int cv::ocl::SURF_OCL::descriptorSize() const
     return extended ? 128 : 64;
 }
 
+int cv::ocl::SURF_OCL::defaultNorm() const
+{
+    return NORM_L2;
+}
+
 void cv::ocl::SURF_OCL::uploadKeypoints(const std::vector<KeyPoint> &keypoints, oclMat &keypointsGPU)
 {
     if (keypoints.empty())
index 03041b0..3cc5b47 100644 (file)
@@ -1124,7 +1124,7 @@ protected:
             CV_Assert(kpt2[i].response > 0 );
 
         vector<DMatch> matches;
-        BFMatcher(NORM_L2, true).match(d1, d2, matches);
+        BFMatcher(f->defaultNorm(), true).match(d1, d2, matches);
 
         vector<Point2f> pt1, pt2;
         for( size_t i = 0; i < matches.size(); i++ ) {
index 360b798..4011f3c 100644 (file)
@@ -176,7 +176,7 @@ CUDA_TEST_P(SURF, Descriptor)
     cv::Mat descriptors_gold;
     surf_gold(image, cv::noArray(), keypoints, descriptors_gold, true);
 
-    cv::BFMatcher matcher(cv::NORM_L2);
+    cv::BFMatcher matcher(surf.defaultNorm());
     std::vector<cv::DMatch> matches;
     matcher.match(descriptors_gold, cv::Mat(descriptors), matches);
 
index c52b6e3..217460a 100644 (file)
@@ -195,7 +195,7 @@ TEST_P(SURF, DISABLED_Descriptor)
     cv::Mat descriptors_gold;
     surf_gold(image, cv::noArray(), keypoints, descriptors_gold, true);
 
-    cv::BFMatcher matcher(cv::NORM_L2);
+    cv::BFMatcher matcher(surf.defaultNorm());
     std::vector<cv::DMatch> matches;
     matcher.match(descriptors_gold, cv::Mat(descriptors), matches);
 
index cb65517..a7b01c8 100644 (file)
@@ -125,7 +125,7 @@ static void testCalonderClassifier( const string& classifierFilename, const stri
     Mat descriptors2;  de.compute( img2, keypoints2, descriptors2 );
 
     // Match descriptors
-    BFMatcher matcher(NORM_L1);
+    BFMatcher matcher(de.defaultNorm());
     vector<DMatch> matches;
     matcher.match( descriptors1, descriptors2, matches );
 
index 1f12132..bf99ec7 100644 (file)
@@ -106,7 +106,7 @@ int main(int argc, const char ** argv)
 
   //Do matching using features2d
   cout << "matching with BruteForceMatcher<Hamming>" << endl;
-  BFMatcher matcher_popcount(NORM_HAMMING);
+  BFMatcher matcher_popcount(extractor.defaultNorm());
   vector<DMatch> matches_popcount;
   double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
   cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;
index dd3cd80..ccb8979 100644 (file)
@@ -881,9 +881,10 @@ public:
     virtual void readAlgorithm( )
     {
         string classifierFile = data_path + "/features2d/calonder_classifier.rtc";
+        Ptr<DescriptorExtractor> extractor = makePtr<CalonderDescriptorExtractor<float> >( classifierFile );
         defaultDescMatcher = makePtr<VectorDescriptorMatch>(
-            makePtr<CalonderDescriptorExtractor<float> >( classifierFile ),
-            makePtr<BFMatcher>(int(NORM_L2)));
+            extractor,
+            makePtr<BFMatcher>(extractor->defaultNorm()));
         specificDescMatcher = defaultDescMatcher;
     }
 };
index fa58d20..e6429ae 100644 (file)
@@ -96,7 +96,7 @@ int main( int argc, char** argv ) {
     // The standard Hamming distance can be used such as
     // BFMatcher matcher(NORM_HAMMING);
     // or the proposed cascade of hamming distance using SSSE3
-    BFMatcher matcher(NORM_HAMMING);
+    BFMatcher matcher(extractor.defaultNorm());
 
     // detect
     double t = (double)getTickCount();
index c1cd6e4..39d3620 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char** argv)
     extractor.compute(img2, keypoints2, descriptors2);
 
     // matching descriptors
-    BFMatcher matcher(NORM_L2);
+    BFMatcher matcher(extractor.defaultNorm());
     vector<DMatch> matches;
     matcher.match(descriptors1, descriptors2, matches);
 
index abd7eab..5dac0a5 100644 (file)
@@ -45,7 +45,7 @@ int main(int argc, char** argv)
     extractor.compute(img2, keypoints2, descriptors2);
 
     // matching descriptors
-    BFMatcher matcher(NORM_L2);
+    BFMatcher matcher(extractor.defaultNorm());
     vector<DMatch> matches;
     matcher.match(descriptors1, descriptors2, matches);
 
index 56067c8..89b60d4 100644 (file)
@@ -49,7 +49,7 @@ int main( int argc, char** argv )
   extractor.compute( img_2, keypoints_2, descriptors_2 );
 
   //-- Step 3: Matching descriptor vectors with a brute force matcher
-  BFMatcher matcher(NORM_L2);
+  BFMatcher matcher(extractor.defaultNorm());
   std::vector< DMatch > matches;
   matcher.match( descriptors_1, descriptors_2, matches );
 
index bf2559f..cefdc89 100644 (file)
@@ -140,7 +140,7 @@ int main(int ac, char ** av)
 
     vector<DMatch> matches;
 
-    BFMatcher desc_matcher(NORM_HAMMING);
+    BFMatcher desc_matcher(brief.defaultNorm());
 
     vector<Point2f> train_pts, query_pts;
     vector<KeyPoint> train_kpts, query_kpts;
index ba5e364..c267dd4 100644 (file)
@@ -62,7 +62,7 @@ int main(int argc, char* argv[])
     cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl;
 
     // matching descriptors
-    BFMatcher_CUDA matcher(NORM_L2);
+    BFMatcher_CUDA matcher(surf.defaultNorm());
     GpuMat trainIdx, distance;
     matcher.matchSingle(descriptors1GPU, descriptors2GPU, trainIdx, distance);