updated sift wrapper (recalculation angles mode)
authorMaria Dimashova <no@email>
Wed, 19 May 2010 16:02:30 +0000 (16:02 +0000)
committerMaria Dimashova <no@email>
Wed, 19 May 2010 16:02:30 +0000 (16:02 +0000)
modules/features2d/include/opencv2/features2d/features2d.hpp
modules/features2d/src/descriptors.cpp
modules/features2d/src/detectors.cpp
modules/features2d/src/sift.cpp
modules/features2d/src/surf.cpp
samples/c/detectors_sample.cpp

index aa83845..f6582c5 100644 (file)
@@ -224,25 +224,26 @@ public:
         static const int DEFAULT_NOCTAVES = 4;
         static const int DEFAULT_NOCTAVE_LAYERS = 3;
         static const int DEFAULT_FIRST_OCTAVE = -1;
+        enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
+
         CommonParams() : nOctaves(DEFAULT_NOCTAVES), nOctaveLayers(DEFAULT_NOCTAVE_LAYERS),
-                         firstOctave(DEFAULT_FIRST_OCTAVE) {}
-        CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave ) :
+                         firstOctave(DEFAULT_FIRST_OCTAVE), angleMode(FIRST_ANGLE) {}
+        CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave, int _angleMode ) :
                          nOctaves(_nOctaves), nOctaveLayers(_nOctaveLayers),
-                         firstOctave(_firstOctave) {}
+                         firstOctave(_firstOctave), angleMode(_angleMode) {}
         int nOctaves, nOctaveLayers, firstOctave;
+        int angleMode;
     };
 
     struct DetectorParams
     {
         static double GET_DEFAULT_THRESHOLD() { return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
         static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
-        enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
-        DetectorParams() : threshold(GET_DEFAULT_THRESHOLD()), edgeThreshold(GET_DEFAULT_EDGE_THRESHOLD()),
-                           angleMode(FIRST_ANGLE) {}
-        DetectorParams( double _threshold, double _edgeThreshold, int _angleMode ) :
-                threshold(_threshold), edgeThreshold(_edgeThreshold), angleMode(_angleMode) {}
+
+        DetectorParams() : threshold(GET_DEFAULT_THRESHOLD()), edgeThreshold(GET_DEFAULT_EDGE_THRESHOLD()) {}
+        DetectorParams( double _threshold, double _edgeThreshold ) :
+                threshold(_threshold), edgeThreshold(_edgeThreshold) {}
         double threshold, edgeThreshold;
-        int angleMode;
     };
 
     struct DescriptorParams
@@ -250,24 +251,30 @@ public:
         static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
         static const bool DEFAULT_IS_NORMALIZE = true;
         static const int DESCRIPTOR_SIZE = 128;
-        DescriptorParams() : magnification(GET_DEFAULT_MAGNIFICATION()), isNormalize(DEFAULT_IS_NORMALIZE) {}
-        DescriptorParams( double _magnification, bool _isNormalize ) :
-                             magnification(_magnification), isNormalize(_isNormalize) {}
+        DescriptorParams() : magnification(GET_DEFAULT_MAGNIFICATION()), isNormalize(DEFAULT_IS_NORMALIZE),
+                             recalculateAngles(true) {}
+        DescriptorParams( double _magnification, bool _isNormalize, bool _recalculateAngles ) :
+                          magnification(_magnification), isNormalize(_isNormalize),
+                          recalculateAngles(_recalculateAngles) {}
         double magnification;
         bool isNormalize;
+        bool recalculateAngles;
     };
 
     SIFT();
     // sift-detector constructor
-    SIFT( double _threshold, double _edgeThreshold, int _angleMode=DetectorParams::FIRST_ANGLE,
+    SIFT( double _threshold, double _edgeThreshold,
           int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
           int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
-          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE );
+          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
+          int _angleMode=CommonParams::FIRST_ANGLE );
     // sift-descriptor constructor
     SIFT( double _magnification, bool _isNormalize=true,
+          bool _recalculateAngles = true,
           int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
           int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
-          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE );
+          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
+          int _angleMode=CommonParams::FIRST_ANGLE );
     SIFT( const CommonParams& _commParams,
           const DetectorParams& _detectorParams = DetectorParams(),
           const DescriptorParams& _descriptorParams = DescriptorParams() );
@@ -1231,10 +1238,10 @@ class CV_EXPORTS SiftFeatureDetector : public FeatureDetector
 public:
     SiftFeatureDetector( double threshold=SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
                          double edgeThreshold=SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD(),
-                         int angleMode=SIFT::DetectorParams::FIRST_ANGLE,
                          int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
                          int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
-                         int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE );
+                         int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
+                         int angleMode=SIFT::CommonParams::FIRST_ANGLE );
 protected:
     virtual void detectImpl( const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints ) const;
 
@@ -1291,10 +1298,11 @@ protected:
 class CV_EXPORTS SiftDescriptorExtractor : public DescriptorExtractor
 {
 public:
-    SiftDescriptorExtractor( double magnification, bool isNormalize=true,
+    SiftDescriptorExtractor( double magnification, bool isNormalize=true, bool recalculateAngles=true,
                              int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
                              int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
-                             int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE );
+                             int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
+                             int angleMode=SIFT::CommonParams::FIRST_ANGLE );
 
     virtual void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors) const;
 
@@ -1408,10 +1416,7 @@ public:
      * query         The query set of descriptors
      * matches       Indices of the closest matches from the training set
      */
-
-
-    // TODO: remove vector<double>* distances = 0 ???
-    void match( const Mat& query, vector<int>& matches, vector<double>* distances = 0 ) const;
+    void match( const Mat& query, vector<int>& matches ) const;
 
     /*
      * Find the best matches between two descriptor sets, with constraints
@@ -1479,15 +1484,10 @@ inline void DescriptorMatcher::add( const Mat& descriptors )
     }
 }
 
-inline void DescriptorMatcher::match( const Mat& query, vector<int>& matches, vector<double>* distances ) const
+inline void DescriptorMatcher::match( const Mat& query, vector<int>& matches ) const
 {
-    if( distances )
-        matchImpl( query, train, Mat(), matches, *distances );
-    else
-    {
-        vector<double> innDistances;
-        matchImpl( query, train, Mat(), matches, innDistances );
-    }
+    vector<double> innDistances;
+    matchImpl( query, train, Mat(), matches, innDistances );
 }
 
 inline void DescriptorMatcher::match( const Mat& query, const Mat& mask,
index d7092c6..5951dcf 100644 (file)
@@ -78,9 +78,9 @@ void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints,
 /****************************************************************************************\
 *                                SiftDescriptorExtractor                                  *
 \****************************************************************************************/
-SiftDescriptorExtractor::SiftDescriptorExtractor( double magnification, bool isNormalize,
-                                                  int nOctaves, int nOctaveLayers, int firstOctave )
-    : sift( magnification, isNormalize, nOctaves, nOctaveLayers, firstOctave )
+SiftDescriptorExtractor::SiftDescriptorExtractor( double magnification, bool isNormalize, bool recalculateAngles,
+                                                  int nOctaves, int nOctaveLayers, int firstOctave, int angleMode )
+    : sift( magnification, isNormalize, recalculateAngles, nOctaves, nOctaveLayers, firstOctave, angleMode )
 {}
 
 void SiftDescriptorExtractor::compute( const Mat& image,
index 484e975..a0288d4 100644 (file)
@@ -152,9 +152,9 @@ void StarFeatureDetector::detectImpl( const Mat& image, const Mat& mask, vector<
 /*
     SiftFeatureDetector
 */
-SiftFeatureDetector::SiftFeatureDetector(double threshold, double edgeThreshold, int angleMode,
-                                         int nOctaves, int nOctaveLayers, int firstOctave) :
-    sift(threshold, edgeThreshold, angleMode, nOctaves, nOctaveLayers, firstOctave)
+SiftFeatureDetector::SiftFeatureDetector(double threshold, double edgeThreshold,
+                                         int nOctaves, int nOctaveLayers, int firstOctave, int angleMode) :
+    sift(threshold, edgeThreshold, nOctaves, nOctaveLayers, firstOctave, angleMode)
 {
 }
 
index b66fc5a..de32eb1 100644 (file)
@@ -47,8 +47,8 @@
 // MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 #include "precomp.hpp"
-#include<iostream>
-#include<limits>
+#include <iostream>
+#include <limits>
 
 #define log2(a) (log((a))/CV_LOG2)
 
@@ -1981,18 +1981,18 @@ using namespace cv;
 SIFT::SIFT()
 {}
 
-SIFT::SIFT( double _threshold, double _edgeThreshold, int _angleMode,
-            int _nOctaves, int _nOctaveLayers, int _firstOctave )
+SIFT::SIFT( double _threshold, double _edgeThreshold, int _nOctaves,
+            int _nOctaveLayers, int _firstOctave, int _angleMode )
 {
-    detectorParams = DetectorParams(_threshold, _edgeThreshold, _angleMode);
-    commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave);
+    detectorParams = DetectorParams(_threshold, _edgeThreshold);
+    commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave, _angleMode);
 }
 
-SIFT::SIFT( double _magnification, bool _isNormalize,
-            int _nOctaves, int _nOctaveLayers, int _firstOctave )
+SIFT::SIFT( double _magnification, bool _isNormalize, bool _recalculateAngles, int _nOctaves,
+            int _nOctaveLayers, int _firstOctave, int _angleMode )
 {
-    descriptorParams = DescriptorParams(_magnification, _isNormalize);
-    commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave);
+    descriptorParams = DescriptorParams(_magnification, _isNormalize, _recalculateAngles);
+    commParams = CommonParams(_nOctaves, _nOctaveLayers, _firstOctave, _angleMode);
 }
 
 SIFT::SIFT( const CommonParams& _commParams,
@@ -2015,6 +2015,31 @@ inline void ocvKeypointToVl( const KeyPoint& ocvKeypoint, const VL::Sift& vlSift
     vlKeypoint = vlSift.getKeypoint(ocvKeypoint.pt.x, ocvKeypoint.pt.y, ocvKeypoint.size);
 }
 
+float computeKeypointOrientations( VL::Sift& sift, const VL::Sift::Keypoint& keypoint, int angleMode )
+{
+    float angleVal = -1;
+    VL::float_t angles[4];
+    int angleCount = sift.computeKeypointOrientations(angles, keypoint);
+    if( angleCount > 0 )
+    {
+        if( angleMode == SIFT::CommonParams::FIRST_ANGLE )
+        {
+            angleVal = angles[0];
+        }
+        else if( angleMode == SIFT::CommonParams::AVERAGE_ANGLE )
+        {
+            for( int i = 0; i < angleCount; i++ )
+                angleVal += angles[i];
+            angleVal /= angleCount;
+        }
+        else
+        {
+          assert(0);
+        }
+    }
+    return angleVal;
+}
+
 // detectors
 void SIFT::operator()(const Mat& img, const Mat& mask,
                       vector<KeyPoint>& keypoints) const
@@ -2038,27 +2063,10 @@ void SIFT::operator()(const Mat& img, const Mat& mask,
 
     for( VL::Sift::KeypointsConstIter iter = vlsift.keypointsBegin(); iter != vlsift.keypointsEnd(); ++iter )
     {
-        VL::float_t angles[4];
-        int angleCount = vlsift.computeKeypointOrientations(angles, *iter);
-        if( angleCount > 0 )
+        float angleVal = computeKeypointOrientations( vlsift, *iter, commParams.angleMode );
+        if( angleVal >= 0 )
         {
-            double angleVal = 0;
-            if( detectorParams.angleMode == DetectorParams::FIRST_ANGLE )
-            {
-                angleVal = angles[0];
-            }
-            else if( detectorParams.angleMode == DetectorParams::AVERAGE_ANGLE )
-            {
-                for( int i = 0; i < angleCount; i++ )
-                    angleVal += angles[i];
-                angleVal /= angleCount;
-            }
-            else
-            {
-              assert(0);
-            }
-
-            keypoints.push_back( vlKeypointToOcv(*iter, angleVal*180.0/CV_PI ) );
+            keypoints.push_back( vlKeypointToOcv(*iter, angleVal*180.0/CV_PI) );
         }
     }
 }
@@ -2093,6 +2101,13 @@ void SIFT::operator()(const Mat& img, const Mat& mask,
     {
         VL::Sift::Keypoint vlkpt;
         ocvKeypointToVl( *iter, vlsift, vlkpt );
-        vlsift.computeKeypointDescriptor((VL::float_t*)descriptors.ptr(pi), vlkpt, iter->angle*CV_PI/180.0);
+        float angleVal = iter->angle*CV_PI/180.0;
+        if( descriptorParams.recalculateAngles )
+        {
+            float recalcAngleVal = computeKeypointOrientations( vlsift, vlkpt, commParams.angleMode );
+            if( recalcAngleVal >= 0 )
+                angleVal = recalcAngleVal;
+        }
+        vlsift.computeKeypointDescriptor((VL::float_t*)descriptors.ptr(pi), vlkpt, angleVal);
     }
 }
index 9dd1e84..7c96b01 100644 (file)
@@ -437,7 +437,7 @@ struct SURFInvoker
             maxSize = std::max(maxSize, ((CvSURFPoint*)cvGetSeqElem( keypoints, k ))->size);
         
         maxSize = cvCeil((PATCH_SZ+1)*maxSize*1.2f/9.0f);
-        Ptr<CvMat> winbuf = cvCreateMat( 1, maxSize*maxSize, CV_8U );
+        Ptr<CvMat> winbuf = cvCreateMat( 1, maxSize > 0 ? maxSize*maxSize : 1, CV_8U );
         
         for( k = k1; k < k2; k++ )
         {
index 3c0ca6f..6031e0a 100644 (file)
@@ -14,8 +14,7 @@ inline Point2f applyHomography( const Mat_<double>& H, const Point2f& pt )
 
 void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr,
                           const vector<KeyPoint>& keypoints1, const vector<KeyPoint>& keypoints2,
-                          const vector<int>& matches, const vector<double>& distances,
-                          float maxDist, Mat& drawImg )
+                          const vector<int>& matches, float maxDist, Mat& drawImg )
 {
     Scalar RED = CV_RGB(255, 0, 0);
     Scalar PINK = CV_RGB(255,130,230);
@@ -49,9 +48,8 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr
     Mat vec1(3, 1, CV_32FC1), vec2;
     float err = 3;
     vector<int>::const_iterator mit = matches.begin();
-    vector<double>::const_iterator dit = distances.begin();
-    assert( matches.size() == distances.size() && matches.size() == keypoints1.size() );
-    for( int i1 = 0; mit < matches.end(); ++mit, ++dit, i1++ )
+    assert( matches.size() == keypoints1.size() );
+    for( int i1 = 0; mit < matches.end(); ++mit, i1++ )
     {
         Point2f pt1 = keypoints1[i1].pt, pt2 = keypoints2[*mit].pt;
         Point2f diff = applyHomography(transfMtr, pt1) - pt2;
@@ -63,12 +61,13 @@ void drawCorrespondences( const Mat& img1, const Mat& img2, const Mat& transfMtr
         }
         else
         {
-            if( *dit > maxDist )
+            /*if( *dit > maxDist )
             {
                 circle(drawImg, pt1, 3, PINK);
                 circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, PINK);
             }
-            else
+            // TODO add key point filter
+            else*/
             {
                 circle(drawImg, pt1, 3, BLUE);
                 circle(drawImg, Point2f(pt2.x+img1.cols, pt2.y), 3, BLUE);
@@ -93,8 +92,7 @@ FeatureDetector* createDetector( const string& detectorType )
     else if( !detectorType.compare( "SIFT" ) )
     {
         fd = new SiftFeatureDetector(SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
-                                     SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD(),
-                                     SIFT::DetectorParams::FIRST_ANGLE);
+                                     SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD());
     }
     else if( !detectorType.compare( "SURF" ) )
        {
@@ -184,17 +182,16 @@ void iter( Ptr<FeatureDetector> detector, Ptr<DescriptorExtractor> descriptor,
 
     cout << "< Matching keypoints by descriptors... ";
     vector<int> matches;
-    vector<double> distances;
     Ptr<DescriptorMatcher> matcher = createDescMatcher();
     matcher->add( descs2 );
-    matcher->match( descs1, matches, &distances );
+    matcher->match( descs1, matches );
     cout << ">" << endl;
 
     // TODO time
 
     Mat drawImg;
     drawCorrespondences( img1, img2, transfMtr, keypoints1, keypoints2,
-                         matches, distances, maxDist, drawImg );
+                         matches, maxDist, drawImg );
     imshow( winName, drawImg);
 }