|
|
|
@ -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(); |
|
|
|
|
} |
|
|
|
|