regression test for bug 3172
authorE Braun <elmar.braun@sh-p.de>
Thu, 31 Jul 2014 22:16:58 +0000 (00:16 +0200)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Fri, 19 Sep 2014 10:47:43 +0000 (14:47 +0400)
modules/features2d/test/test_matchers_algorithmic.cpp

index d76715d..8535461 100644 (file)
@@ -57,6 +57,9 @@ public:
     CV_DescriptorMatcherTest( const string& _name, const Ptr<DescriptorMatcher>& _dmatcher, float _badPart ) :
         badPart(_badPart), name(_name), dmatcher(_dmatcher)
         {}
+
+    static void generateData( Mat& query, Mat& train );
+
 protected:
     static const int dim = 500;
     static const int queryDescCount = 300; // must be even number because we split train data in some cases in two
@@ -64,7 +67,6 @@ protected:
     const float badPart;
 
     virtual void run( int );
-    void generateData( Mat& query, Mat& train );
 
     void emptyDataTest();
     void matchTest( const Mat& query, const Mat& train );
@@ -526,6 +528,81 @@ void CV_DescriptorMatcherTest::run( int )
     radiusMatchTest( query, train );
 }
 
+// bug #3172: test that knnMatch() can handle images with fewer than knn keypoints
+class CV_DescriptorMatcherLowKeypointTest : public cvtest::BaseTest
+{
+public:
+    CV_DescriptorMatcherLowKeypointTest( const string& _name, const Ptr<DescriptorMatcher>& _dmatcher ) :
+        name(_name), dmatcher(_dmatcher)
+        {}
+protected:
+    virtual void run(int);
+
+    void knnMatchTest( const Mat& query, const Mat& train );
+
+private:
+    string name;
+    Ptr<DescriptorMatcher> dmatcher;
+};
+
+void CV_DescriptorMatcherLowKeypointTest::knnMatchTest( const Mat& query, const Mat& train )
+{
+    const int knn = 6;
+    const int queryDescCount = query.rows;
+    vector<vector<DMatch> > matches;
+
+    // three train images, the third one with only one keypoint
+    dmatcher->add( vector<Mat>(1,train.rowRange(0, train.rows/2)) );
+    dmatcher->add( vector<Mat>(1,train.rowRange(train.rows/2, train.rows-1)) );
+    dmatcher->add( vector<Mat>(1,train.rowRange(train.rows-1, train.rows)) );
+    const int trainImgCount = (int)dmatcher->getTrainDescriptors().size();
+
+    dmatcher->knnMatch( query, matches, knn, std::vector<Mat>(), true );
+
+    if( matches.empty() )
+    {
+        ts->printf(cvtest::TS::LOG, "No matches while testing knnMatch() function (3).\n");
+        ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+    }
+    else
+    {
+        int badImgIdxCount = 0, badQueryIdxCount = 0, badTrainIdxCount = 0;
+        for( size_t i = 0; i < matches.size(); i++ )
+        {
+            for( size_t j = 0; j < matches[i].size(); j++ )
+            {
+                const DMatch& match = matches[i][j];
+                if( match.imgIdx < 0 || match.imgIdx >= trainImgCount )
+                {
+                    ++badImgIdxCount;
+                }
+                if( match.queryIdx < 0 || match.queryIdx >= queryDescCount )
+                {
+                    ++badQueryIdxCount;
+                }
+                if( match.trainIdx < 0 )
+                {
+                    ++badTrainIdxCount;
+                }
+            }
+        }
+        if( badImgIdxCount > 0 || badQueryIdxCount > 0 || badTrainIdxCount > 0 )
+        {
+            ts->printf( cvtest::TS::LOG, "%d/%d/%d - wrong image/query/train indices while testing knnMatch() function (3).\n",
+                        badImgIdxCount, badQueryIdxCount, badTrainIdxCount );
+            ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+        }
+    }
+}
+
+void CV_DescriptorMatcherLowKeypointTest::run( int )
+{
+    Mat query, train;
+    CV_DescriptorMatcherTest::generateData( query, train );
+
+    knnMatchTest( query, train );
+}
+
 /****************************************************************************************\
 *                                Tests registrations                                     *
 \****************************************************************************************/
@@ -541,3 +618,15 @@ TEST( Features2d_DescriptorMatcher_FlannBased, regression )
     CV_DescriptorMatcherTest test( "descriptor-matcher-flann-based", Algorithm::create<DescriptorMatcher>("DescriptorMatcher.FlannBasedMatcher"), 0.04f );
     test.safe_run();
 }
+
+TEST( Features2d_DescriptorMatcher_LowKeypoint_BruteForce, regression )
+{
+    CV_DescriptorMatcherLowKeypointTest test( "descriptor-matcher-low-keypoint-brute-force", Algorithm::create<DescriptorMatcher>("DescriptorMatcher.BFMatcher") );
+    test.safe_run();
+}
+
+TEST(Features2d_DescriptorMatcher_LowKeypoint_FlannBased, regression)
+{
+    CV_DescriptorMatcherLowKeypointTest test( "descriptor-matcher-low-keypoint-flann-based", Algorithm::create<DescriptorMatcher>("DescriptorMatcher.FlannBasedMatcher") );
+    test.safe_run();
+}