From 1f261c2f9db912b48be0a3486bcdd1f8ca76eb2f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 30 Jan 2013 18:07:37 +0400 Subject: [PATCH] changed default parameters of SURF, which improved its performance. Restored bi-linear interpolation in SURF descriptor extractor. Added test for SURF homography + check for non-zero (positive) responses. --- modules/nonfree/src/surf.cpp | 37 ++++++++++++++++++++-- modules/nonfree/test/test_features2d.cpp | 6 +++- .../test/test_rotation_and_scale_invariance.cpp | 2 +- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/modules/nonfree/src/surf.cpp b/modules/nonfree/src/surf.cpp index 9a4cd28..bb6d53e 100644 --- a/modules/nonfree/src/surf.cpp +++ b/modules/nonfree/src/surf.cpp @@ -698,11 +698,12 @@ struct SURFInvoker cvGetQuadrangleSubPix( img, &win, &W ); */ - // Nearest neighbour version (faster) float win_offset = -(float)(win_size-1)/2; float start_x = center.x + win_offset*cos_dir + win_offset*sin_dir; float start_y = center.y - win_offset*sin_dir + win_offset*cos_dir; uchar* WIN = win.data; +#if 0 + // Nearest neighbour version (faster) for( i = 0; i < win_size; i++, start_x += sin_dir, start_y += cos_dir ) { float pixel_x = start_x; @@ -714,6 +715,36 @@ struct SURFInvoker WIN[i*win_size + j] = img->at(y, x); } } +#else + int ncols1 = img->cols-1, nrows1 = img->rows-1; + size_t imgstep = img->step; + for( i = 0; i < win_size; i++, start_x += sin_dir, start_y += cos_dir ) + { + double pixel_x = start_x; + double pixel_y = start_y; + for( j = 0; j < win_size; j++, pixel_x += cos_dir, pixel_y -= sin_dir ) + { + int ix = cvFloor(pixel_x), iy = cvFloor(pixel_y); + if( (unsigned)ix < (unsigned)ncols1 && + (unsigned)iy < (unsigned)nrows1 ) + { + float a = (float)(pixel_x - ix), b = (float)(pixel_y - iy); + const uchar* imgptr = &img->at(iy, ix); + WIN[i*win_size + j] = (uchar) + cvRound(imgptr[0]*(1.f - a)*(1.f - b) + + imgptr[1]*a*(1.f - b) + + imgptr[imgstep]*(1.f - a)*b + + imgptr[imgstep+1]*a*b); + } + else + { + int x = std::min(std::max(cvRound(pixel_x), 0), ncols1); + int y = std::min(std::max(cvRound(pixel_y), 0), nrows1); + WIN[i*win_size + j] = img->at(y, x); + } + } + } +#endif } else { @@ -844,10 +875,10 @@ struct SURFInvoker SURF::SURF() { hessianThreshold = 100; - extended = true; + extended = false; upright = false; nOctaves = 4; - nOctaveLayers = 2; + nOctaveLayers = 3; } SURF::SURF(double _threshold, int _nOctaves, int _nOctaveLayers, bool _extended, bool _upright) diff --git a/modules/nonfree/test/test_features2d.cpp b/modules/nonfree/test/test_features2d.cpp index a4cc373..001d628 100644 --- a/modules/nonfree/test/test_features2d.cpp +++ b/modules/nonfree/test/test_features2d.cpp @@ -1114,6 +1114,10 @@ protected: Mat d1, d2; f->operator()(img1, Mat(), kpt1, d1); f->operator()(img1, Mat(), kpt2, d2); + for( size_t i = 0; i < kpt1.size(); i++ ) + CV_Assert(kpt1[i].response > 0 ); + for( size_t i = 0; i < kpt2.size(); i++ ) + CV_Assert(kpt2[i].response > 0 ); vector matches; BFMatcher(NORM_L2, true).match(d1, d2, matches); @@ -1140,5 +1144,5 @@ protected: }; TEST(Features2d_SIFTHomographyTest, regression) { CV_DetectPlanarTest test("SIFT", 80); test.safe_run(); } -//TEST(Features2d_SURFHomographyTest, regression) { CV_DetectPlanarTest test("SURF", 80); test.safe_run(); } +TEST(Features2d_SURFHomographyTest, regression) { CV_DetectPlanarTest test("SURF", 80); test.safe_run(); } diff --git a/modules/nonfree/test/test_rotation_and_scale_invariance.cpp b/modules/nonfree/test/test_rotation_and_scale_invariance.cpp index 6262456..e0e731e 100644 --- a/modules/nonfree/test/test_rotation_and_scale_invariance.cpp +++ b/modules/nonfree/test/test_rotation_and_scale_invariance.cpp @@ -616,7 +616,7 @@ protected: TEST(Features2d_RotationInvariance_Detector_SURF, regression) { DetectorRotationInvarianceTest test(Algorithm::create("Feature2D.SURF"), - 0.45f, + 0.44f, 0.76f); test.safe_run(); } -- 2.7.4