possibly repaired FAST test (however, FAST<7/12> and <5/8> could still do something...
authorVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Tue, 25 Sep 2012 11:50:03 +0000 (15:50 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@itseez.com>
Tue, 25 Sep 2012 11:50:03 +0000 (15:50 +0400)
modules/features2d/src/fast.cpp
modules/features2d/src/fast_score.cpp
modules/features2d/test/test_fast.cpp

index 9beba21..d940463 100644 (file)
@@ -89,7 +89,7 @@ void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bo
         if( i < img.rows - 3 )
         {
             j = 3;
-    #if CV_SSE2
+    #if 0 //CV_SSE2
             for(; j < img.cols - 16 - 3; j += 16, ptr += 16)
             {
                 __m128i m0, m1;
index aa5881e..b897860 100644 (file)
@@ -46,58 +46,39 @@ The references are:
 namespace cv
 {
 
-void makeOffsets(int pixel[25], int row_stride, int patternSize)
+void makeOffsets(int pixel[25], int rowStride, int patternSize)
 {
-    CV_Assert(pixel != 0);
-    switch(patternSize) {
-      case 16:
-        pixel[0] = 0 + row_stride * 3;
-        pixel[1] = 1 + row_stride * 3;
-        pixel[2] = 2 + row_stride * 2;
-        pixel[3] = 3 + row_stride * 1;
-        pixel[4] = 3 + row_stride * 0;
-        pixel[5] = 3 + row_stride * -1;
-        pixel[6] = 2 + row_stride * -2;
-        pixel[7] = 1 + row_stride * -3;
-        pixel[8] = 0 + row_stride * -3;
-        pixel[9] = -1 + row_stride * -3;
-        pixel[10] = -2 + row_stride * -2;
-        pixel[11] = -3 + row_stride * -1;
-        pixel[12] = -3 + row_stride * 0;
-        pixel[13] = -3 + row_stride * 1;
-        pixel[14] = -2 + row_stride * 2;
-        pixel[15] = -1 + row_stride * 3;
-        break;
-      case 12:
-        pixel[0] = 0 + row_stride * 2;
-        pixel[1] = 1 + row_stride * 2;
-        pixel[2] = 2 + row_stride * 1;
-        pixel[3] = 2 + row_stride * 0;
-        pixel[4] = 2 + row_stride * -1;
-        pixel[5] = 1 + row_stride * -2;
-        pixel[6] = 0 + row_stride * -2;
-        pixel[7] = -1 + row_stride * -2;
-        pixel[8] = -2 + row_stride * -1;
-        pixel[9] = -2 + row_stride * 0;
-        pixel[10] = -2 + row_stride * 1;
-        pixel[11] = -1 + row_stride * 2;
-        break;
-      case 8:
-        pixel[0] = 0 + row_stride * 1;
-        pixel[1] = 1 + row_stride * 1;
-        pixel[2] = 1 + row_stride * 0;
-        pixel[3] = 1 + row_stride * -1;
-        pixel[4] = 0 + row_stride * -1;
-        pixel[5] = -1 + row_stride * -1;
-        pixel[6] = 0 + row_stride * 0;
-        pixel[7] = 1 + row_stride * 1;
-        break;
-    }
-    for(int k = patternSize; k < 25; k++)
-      pixel[k] = pixel[k - patternSize];
+    static const int offsets16[][2] =
+    {
+        {0,  3}, { 1,  3}, { 2,  2}, { 3,  1}, { 3, 0}, { 3, -1}, { 2, -2}, { 1, -3},
+        {0, -3}, {-1, -3}, {-2, -2}, {-3, -1}, {-3, 0}, {-3,  1}, {-2,  2}, {-1,  3}
+    };
+    
+    static const int offsets12[][2] =
+    {
+        {0,  2}, { 1,  2}, { 2,  1}, { 2, 0}, { 2, -1}, { 1, -2},
+        {0, -2}, {-1, -2}, {-2, -1}, {-2, 0}, {-2,  1}, {-1,  2}
+    };
+    
+    static const int offsets8[][2] =
+    {
+        {0, 1},  { 1,  1}, { 1, 0}, { 1, -1},
+        {0, -1}, {-1, -1}, {-1, 0}, {-1,  1}
+    };
+        
+    const int (*offsets)[2] = patternSize == 16 ? offsets16 :
+        patternSize == 12 ? offsets12 : patternSize == 8 ? offsets8 : 0;
+        
+    CV_Assert(pixel != 0 && offsets);
+    
+    int k = 0;
+    for( ; k < patternSize; k++ )
+        pixel[k] = offsets[k][0] + offsets[k][1]*rowStride;
+    for( ; k < 25; k++ )
+        pixel[k] = pixel[k - patternSize];
 }
 
-/*static void testCorner(const uchar* ptr, const int pixel[], int K, int N, int threshold) {
+static void testCorner(const uchar* ptr, const int pixel[], int K, int N, int threshold) {
     // check that with the computed "threshold" the pixel is still a corner
     // and that with the increased-by-1 "threshold" the pixel is not a corner anymore
     for( int delta = 0; delta <= 1; delta++ )
@@ -129,12 +110,12 @@ void makeOffsets(int pixel[25], int row_stride, int patternSize)
         CV_Assert( (delta == 0 && std::max(c0, c1) > K) ||
                    (delta == 1 && std::max(c0, c1) <= K) );
     }
-}*/
+}
 
 template<>
 int cornerScore<16>(const uchar* ptr, const int pixel[], int threshold)
 {
-    const int K = 8, N = 16 + K + 1;
+    const int K = 8, N = K*3 + 1;
     int k, v = ptr[0];
     short d[N];
     for( k = 0; k < N; k++ )
@@ -224,7 +205,7 @@ int cornerScore<16>(const uchar* ptr, const int pixel[], int threshold)
 template<>
 int cornerScore<12>(const uchar* ptr, const int pixel[], int threshold)
 {
-    const int K = 6, N = 12 + K + 1;
+    const int K = 6, N = K*3 + 1;
     int k, v = ptr[0];
     short d[N];
     for( k = 0; k < N; k++ )
@@ -304,7 +285,7 @@ int cornerScore<12>(const uchar* ptr, const int pixel[], int threshold)
 template<>
 int cornerScore<8>(const uchar* ptr, const int pixel[], int threshold)
 {
-    const int K = 4, N = 8 + K + 1;
+    const int K = 4, N = K*3 + 1;
     int k, v = ptr[0];
     short d[N];
     for( k = 0; k < N; k++ )
index eef395b..477989d 100644 (file)
@@ -61,7 +61,7 @@ void CV_FastTest::run( int )
   for(int type=0; type <= 2; ++type) {
     Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.jpg");
     Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.jpg");
-    string xml = string(ts->get_data_path()) + "fast/result.xml";
+    string xml = string(ts->get_data_path()) + format("fast/result%d.xml", type);
 
     if (image1.empty() || image2.empty())
     {
@@ -76,7 +76,7 @@ void CV_FastTest::run( int )
     vector<KeyPoint> keypoints1;
     vector<KeyPoint> keypoints2;
     FAST(gray1, keypoints1, 30, true, type);
-    FAST(gray2, keypoints2, 30, true, type);
+    FAST(gray2, keypoints2, (type > 0 ? 30 : 20), true, type);
 
     for(size_t i = 0; i < keypoints1.size(); ++i)
     {
@@ -97,27 +97,32 @@ void CV_FastTest::run( int )
     if (!fs.isOpened())
     {
         fs.open(xml, FileStorage::WRITE);
+        if (!fs.isOpened())
+        {
+            ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+            return;
+        }
         fs << "exp_kps1" << kps1;
         fs << "exp_kps2" << kps2;
         fs.release();
-    }
-
-    if (!fs.isOpened())
         fs.open(xml, FileStorage::READ);
+        if (!fs.isOpened())
+        {
+            ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
+            return;
+        }
+    }
 
     Mat exp_kps1, exp_kps2;
     read( fs["exp_kps1"], exp_kps1, Mat() );
     read( fs["exp_kps2"], exp_kps2, Mat() );
     fs.release();
 
-    // We only have testing data for 9_16 but it actually works equally well for 7_12
-    if ((type==1) || (type==2)){
-        if ( exp_kps1.size != kps1.size || 0 != norm(exp_kps1, kps1, NORM_L2) ||
-             exp_kps2.size != kps2.size || 0 != norm(exp_kps2, kps2, NORM_L2))
-        {
-            ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
-            return;
-        }
+    if ( exp_kps1.size != kps1.size || 0 != norm(exp_kps1, kps1, NORM_L2) ||
+         exp_kps2.size != kps2.size || 0 != norm(exp_kps2, kps2, NORM_L2))
+    {
+        ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
+        return;
     }
 
     /*cv::namedWindow("Img1"); cv::imshow("Img1", image1);