From c78d056ef69a71794e133cba7e09b44be52b9ca0 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 27 Apr 2012 13:06:16 +0000 Subject: [PATCH] added BruteForceMatcher (the older variant of BFMatcher) to legacy (ticket #1796). added test for it. Renamed legacy tests to "Legacy_*" --- .../include/opencv2/features2d/features2d.hpp | 88 --------------- modules/features2d/test/test_bruteforcematcher.cpp | 122 --------------------- modules/legacy/include/opencv2/legacy/legacy.hpp | 104 ++++++++++++++++++ modules/legacy/test/test_bruteforcematcher.cpp | 115 +++++++++++++++++++ modules/legacy/test/test_em.cpp | 4 +- modules/legacy/test/test_nearestneighbors.cpp | 6 +- modules/legacy/test/test_optflow.cpp | 2 +- modules/legacy/test/test_pyrsegmentation.cpp | 2 +- modules/legacy/test/test_stereomatching.cpp | 2 +- modules/legacy/test/test_subdivisions.cpp | 2 +- 10 files changed, 228 insertions(+), 219 deletions(-) delete mode 100644 modules/features2d/test/test_bruteforcematcher.cpp create mode 100644 modules/legacy/test/test_bruteforcematcher.cpp diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index 161aa2a..fe81c1f 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -737,94 +737,6 @@ protected: PixelTestFn test_fn_; }; -/****************************************************************************************\ -* Distance * -\****************************************************************************************/ -template -struct CV_EXPORTS Accumulator -{ - typedef T Type; -}; - -template<> struct Accumulator { typedef float Type; }; -template<> struct Accumulator { typedef float Type; }; -template<> struct Accumulator { typedef float Type; }; -template<> struct Accumulator { typedef float Type; }; - -/* - * Squared Euclidean distance functor - */ -template -struct CV_EXPORTS SL2 -{ - typedef T ValueType; - typedef typename Accumulator::Type ResultType; - - ResultType operator()( const T* a, const T* b, int size ) const - { - return normL2Sqr(a, b, size); - } -}; - -/* - * Euclidean distance functor - */ -template -struct CV_EXPORTS L2 -{ - typedef T ValueType; - typedef typename Accumulator::Type ResultType; - - ResultType operator()( const T* a, const T* b, int size ) const - { - return (ResultType)sqrt((double)normL2Sqr(a, b, size)); - } -}; - -/* - * Manhattan distance (city block distance) functor - */ -template -struct CV_EXPORTS L1 -{ - typedef T ValueType; - typedef typename Accumulator::Type ResultType; - - ResultType operator()( const T* a, const T* b, int size ) const - { - return normL1(a, b, size); - } -}; - -/* - * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor - * bit count of A exclusive XOR'ed with B - */ -struct CV_EXPORTS Hamming -{ - typedef unsigned char ValueType; - typedef int ResultType; - - /** this will count the bits in a ^ b - */ - ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const - { - return normHamming(a, b, size); - } -}; - -typedef Hamming HammingLUT; - -template struct CV_EXPORTS HammingMultilevel -{ - typedef unsigned char ValueType; - typedef int ResultType; - - ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const - { - return normHamming(a, b, size, cellsize); - } -}; /****************************************************************************************\ * DMatch * diff --git a/modules/features2d/test/test_bruteforcematcher.cpp b/modules/features2d/test/test_bruteforcematcher.cpp deleted file mode 100644 index f2fdca1..0000000 --- a/modules/features2d/test/test_bruteforcematcher.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "test_precomp.hpp" - -#if 0 -using namespace cv; - -class BruteForceMatcherTest : public cvtest::BaseTest -{ -public: - BruteForceMatcherTest(); -protected: - void run( int ); -}; - -struct CV_EXPORTS L2Fake : public L2 -{ -}; - -BruteForceMatcherTest::BruteForceMatcherTest() : cvtest::BaseTest( "BruteForceMatcher", "BruteForceMatcher::matchImpl") -{ - support_testing_modes = cvtest::TS::TIMING_MODE; -} - -void BruteForceMatcherTest::run( int ) -{ - const int dimensions = 64; - const int descriptorsNumber = 5000; - - Mat train = Mat( descriptorsNumber, dimensions, CV_32FC1); - Mat query = Mat( descriptorsNumber, dimensions, CV_32FC1); - - Mat permutation( 1, descriptorsNumber, CV_32SC1 ); - for( int i=0;i( 0, i ) = i; - - //RNG rng = RNG( cvGetTickCount() ); - RNG rng = RNG( *ts->get_rng() ); - randShuffle( permutation, 1, &rng ); - - float boundary = 500.f; - for( int row=0;row( permutation.at( 0, row ), col ) = bit*boundary + rng.uniform( 0.f, boundary ); - query.at( row, col ) = bit*boundary + rng.uniform( 0.f, boundary ); - } - } - - vector specMatches, genericMatches; - BruteForceMatcher > specMatcher; - BruteForceMatcher genericMatcher; - - int64 time0 = cvGetTickCount(); - specMatcher.match( query, train, specMatches ); - int64 time1 = cvGetTickCount(); - genericMatcher.match( query, train, genericMatches ); - int64 time2 = cvGetTickCount(); - - float specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency(); - ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time s: %f, us per pair: %f\n", - specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) ); - - float genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency(); - ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time s: %f, us per pair: %f\n", - genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) ); - - if( (int)specMatches.size() != descriptorsNumber || (int)genericMatches.size() != descriptorsNumber ) - ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); - for( int i=0;i( 0, i ) ) - { - ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); - break; - } - } - - - //Test mask - Mat mask( query.rows, train.rows, CV_8UC1 ); - rng.fill( mask, RNG::UNIFORM, 0, 2 ); - - - time0 = cvGetTickCount(); - specMatcher.match( query, train, specMatches, mask ); - time1 = cvGetTickCount(); - genericMatcher.match( query, train, genericMatches, mask ); - time2 = cvGetTickCount(); - - specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency(); - ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time with mask s: %f, us per pair: %f\n", - specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) ); - - genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency(); - ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time with mask s: %f, us per pair: %f\n", - genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) ); - - if( specMatches.size() != genericMatches.size() ) - ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); - - for( size_t i=0;iset_failed_test_info( cvtest::TS::FAIL_MISMATCH ); - break; - } - } -} - -BruteForceMatcherTest taBruteForceMatcherTest; -#endif diff --git a/modules/legacy/include/opencv2/legacy/legacy.hpp b/modules/legacy/include/opencv2/legacy/legacy.hpp index 1f0909b..28b7ec4 100644 --- a/modules/legacy/include/opencv2/legacy/legacy.hpp +++ b/modules/legacy/include/opencv2/legacy/legacy.hpp @@ -2840,6 +2840,110 @@ bool CalonderDescriptorExtractor::empty() const return classifier_.trees_.empty(); } + +////////////////////// Distance & Brute Force Matcher ////////////////////////// + +template +struct CV_EXPORTS Accumulator +{ + typedef T Type; +}; + +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; + +/* + * Squared Euclidean distance functor + */ +template +struct CV_EXPORTS SL2 +{ + enum { normType = NORM_L2SQR }; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return normL2Sqr(a, b, size); + } +}; + +/* + * Euclidean distance functor + */ +template +struct CV_EXPORTS L2 +{ + enum { normType = NORM_L2 }; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return (ResultType)sqrt((double)normL2Sqr(a, b, size)); + } +}; + +/* + * Manhattan distance (city block distance) functor + */ +template +struct CV_EXPORTS L1 +{ + enum { normType = NORM_L1 }; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return normL1(a, b, size); + } +}; + +/* + * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor + * bit count of A exclusive XOR'ed with B + */ +struct CV_EXPORTS Hamming +{ + enum { normType = NORM_HAMMING }; + typedef unsigned char ValueType; + typedef int ResultType; + + /** this will count the bits in a ^ b + */ + ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const + { + return normHamming(a, b, size); + } +}; + +typedef Hamming HammingLUT; + +template struct CV_EXPORTS HammingMultilevel +{ + enum { normType = NORM_HAMMING + (cellsize>1) }; + typedef unsigned char ValueType; + typedef int ResultType; + + ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const + { + return normHamming(a, b, size, cellsize); + } +}; + + +template +class CV_EXPORTS BruteForceMatcher : public BFMatcher +{ +public: + BruteForceMatcher( Distance d = Distance() ) : BFMatcher(Distance::normType, false) {} + virtual ~BruteForceMatcher() {} +}; + + /****************************************************************************************\ * Planar Object Detection * \****************************************************************************************/ diff --git a/modules/legacy/test/test_bruteforcematcher.cpp b/modules/legacy/test/test_bruteforcematcher.cpp new file mode 100644 index 0000000..b9b2502 --- /dev/null +++ b/modules/legacy/test/test_bruteforcematcher.cpp @@ -0,0 +1,115 @@ +#include "test_precomp.hpp" + +using namespace cv; + +struct CV_EXPORTS L2Fake : public L2 +{ + enum { normType = NORM_L2 }; +}; + +class CV_BruteForceMatcherTest : public cvtest::BaseTest +{ +public: + CV_BruteForceMatcherTest() {} +protected: + void run( int ) + { + const int dimensions = 64; + const int descriptorsNumber = 5000; + + Mat train = Mat( descriptorsNumber, dimensions, CV_32FC1); + Mat query = Mat( descriptorsNumber, dimensions, CV_32FC1); + + Mat permutation( 1, descriptorsNumber, CV_32SC1 ); + for( int i=0;i( 0, i ) = i; + + //RNG rng = RNG( cvGetTickCount() ); + RNG rng; + randShuffle( permutation, 1, &rng ); + + float boundary = 500.f; + for( int row=0;row( permutation.at( 0, row ), col ) = bit*boundary + rng.uniform( 0.f, boundary ); + query.at( row, col ) = bit*boundary + rng.uniform( 0.f, boundary ); + } + } + + vector specMatches, genericMatches; + BruteForceMatcher > specMatcher; + BruteForceMatcher genericMatcher; + + int64 time0 = cvGetTickCount(); + specMatcher.match( query, train, specMatches ); + int64 time1 = cvGetTickCount(); + genericMatcher.match( query, train, genericMatches ); + int64 time2 = cvGetTickCount(); + + float specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency(); + ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time s: %f, us per pair: %f\n", + specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) ); + + float genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency(); + ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time s: %f, us per pair: %f\n", + genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) ); + + if( (int)specMatches.size() != descriptorsNumber || (int)genericMatches.size() != descriptorsNumber ) + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + for( int i=0;i( 0, i ) ) + { + ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); + break; + } + } + + + //Test mask + Mat mask( query.rows, train.rows, CV_8UC1 ); + rng.fill( mask, RNG::UNIFORM, 0, 2 ); + + + time0 = cvGetTickCount(); + specMatcher.match( query, train, specMatches, mask ); + time1 = cvGetTickCount(); + genericMatcher.match( query, train, genericMatches, mask ); + time2 = cvGetTickCount(); + + specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency(); + ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time with mask s: %f, us per pair: %f\n", + specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) ); + + genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency(); + ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time with mask s: %f, us per pair: %f\n", + genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) ); + + if( specMatches.size() != genericMatches.size() ) + ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); + + for( size_t i=0;iset_failed_test_info( cvtest::TS::FAIL_MISMATCH ); + break; + } + } + } +}; + +TEST(Legacy_BruteForceMatcher, accuracy) { CV_BruteForceMatcherTest test; test.safe_run(); } + diff --git a/modules/legacy/test/test_em.cpp b/modules/legacy/test/test_em.cpp index 26be3fe..823561a 100644 --- a/modules/legacy/test/test_em.cpp +++ b/modules/legacy/test/test_em.cpp @@ -444,5 +444,5 @@ protected: } }; -TEST(ML_CvEM, accuracy) { CV_CvEMTest test; test.safe_run(); } -TEST(ML_CvEM, save_load) { CV_CvEMTest_SaveLoad test; test.safe_run(); } +TEST(Legacy_CvEM, accuracy) { CV_CvEMTest test; test.safe_run(); } +TEST(Legacy_CvEM, save_load) { CV_CvEMTest_SaveLoad test; test.safe_run(); } diff --git a/modules/legacy/test/test_nearestneighbors.cpp b/modules/legacy/test/test_nearestneighbors.cpp index b3e4735..df5fc5f 100644 --- a/modules/legacy/test/test_nearestneighbors.cpp +++ b/modules/legacy/test/test_nearestneighbors.cpp @@ -259,6 +259,6 @@ int CV_KDTreeTest_C::checkFindBoxed() } -TEST(Features2d_LSH, regression) { CV_LSHTest test; test.safe_run(); } -TEST(Features2d_SpillTree, regression) { CV_SpillTreeTest_C test; test.safe_run(); } -TEST(Features2d_KDTree_C, regression) { CV_KDTreeTest_C test; test.safe_run(); } +TEST(Legacy_LSH, regression) { CV_LSHTest test; test.safe_run(); } +TEST(Legacy_SpillTree, regression) { CV_SpillTreeTest_C test; test.safe_run(); } +TEST(Legacy_KDTree_C, regression) { CV_KDTreeTest_C test; test.safe_run(); } diff --git a/modules/legacy/test/test_optflow.cpp b/modules/legacy/test/test_optflow.cpp index e14e855..71aea35 100644 --- a/modules/legacy/test/test_optflow.cpp +++ b/modules/legacy/test/test_optflow.cpp @@ -351,6 +351,6 @@ void CV_OptFlowTest::run( int /* start_from */) } -TEST(Video_OpticalFlow, accuracy) { CV_OptFlowTest test; test.safe_run(); } +TEST(Legacy_OpticalFlow, accuracy) { CV_OptFlowTest test; test.safe_run(); } diff --git a/modules/legacy/test/test_pyrsegmentation.cpp b/modules/legacy/test/test_pyrsegmentation.cpp index 89fe46a..674265a 100644 --- a/modules/legacy/test/test_pyrsegmentation.cpp +++ b/modules/legacy/test/test_pyrsegmentation.cpp @@ -199,6 +199,6 @@ _exit_: ts->set_failed_test_info( code ); } -TEST(Imgproc_PyrSegmentation, regression) { CV_PyrSegmentationTest test; test.safe_run(); } +TEST(Legacy_PyrSegmentation, regression) { CV_PyrSegmentationTest test; test.safe_run(); } /* End of file. */ diff --git a/modules/legacy/test/test_stereomatching.cpp b/modules/legacy/test/test_stereomatching.cpp index 21834b0..c3d37d5 100644 --- a/modules/legacy/test/test_stereomatching.cpp +++ b/modules/legacy/test/test_stereomatching.cpp @@ -719,4 +719,4 @@ protected: }; -TEST(Calib3d_StereoGC, regression) { CV_StereoGCTest test; test.safe_run(); } +TEST(Legacy_StereoGC, regression) { CV_StereoGCTest test; test.safe_run(); } diff --git a/modules/legacy/test/test_subdivisions.cpp b/modules/legacy/test/test_subdivisions.cpp index 65e2112..924cc67 100644 --- a/modules/legacy/test/test_subdivisions.cpp +++ b/modules/legacy/test/test_subdivisions.cpp @@ -335,7 +335,7 @@ _exit_: return code; } -TEST(Imgproc_Subdiv, correctness) { CV_SubdivTest test; test.safe_run(); } +TEST(Legacy_Subdiv, correctness) { CV_SubdivTest test; test.safe_run(); } /* End of file. */ -- 2.7.4