From 411d36ff130c2e9ee0da718875a77b048328e888 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 3 Aug 2017 13:19:51 +0300 Subject: [PATCH] features2d(test): update descriptor regression test --- .../test/test_descriptors_regression.cpp | 117 +++++++++++------- 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/modules/features2d/test/test_descriptors_regression.cpp b/modules/features2d/test/test_descriptors_regression.cpp index d6fd30d951..0862649bd9 100644 --- a/modules/features2d/test/test_descriptors_regression.cpp +++ b/modules/features2d/test/test_descriptors_regression.cpp @@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename ) FILE* f = fopen( filename.c_str(), "wb"); if( f ) { + CV_Assert(4 == sizeof(int)); int type = mat.type(); fwrite( (void*)&mat.rows, sizeof(int), 1, f ); fwrite( (void*)&mat.cols, sizeof(int), 1, f ); @@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename ) FILE* f = fopen( filename.c_str(), "rb" ); if( f ) { + CV_Assert(4 == sizeof(int)); int rows, cols, type, dataSize; size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f ); size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f ); @@ -123,24 +125,37 @@ protected: CV_Assert( DataType::type == validDescriptors.type() ); int dimension = validDescriptors.cols; - DistanceType curMaxDist = std::numeric_limits::min(); + DistanceType curMaxDist = 0; + size_t exact_count = 0, failed_count = 0; for( int y = 0; y < validDescriptors.rows; y++ ) { DistanceType dist = distance( validDescriptors.ptr(y), calcDescriptors.ptr(y), dimension ); + if (dist == 0) + exact_count++; if( dist > curMaxDist ) + { + if (dist > maxDist) + failed_count++; curMaxDist = dist; + } +#if 0 + if (dist > 0) + { + std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl; + std::cout << "valid: " << validDescriptors.row(y) << std::endl; + std::cout << " calc: " << calcDescriptors.row(y) << std::endl; + } +#endif } + float exact_percents = (100 * (float)exact_count / validDescriptors.rows); + float failed_percents = (100 * (float)failed_count / validDescriptors.rows); stringstream ss; - ss << "Max distance between valid and computed descriptors " << curMaxDist; - if( curMaxDist <= maxDist ) - ss << "." << endl; - else - { - ss << ">" << maxDist << " - bad accuracy!"<< endl; - ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); - } - ts->printf(cvtest::TS::LOG, ss.str().c_str() ); + ss << "Exact count (dist == 0): " << exact_count << " (" << (int)exact_percents << "%)" << std::endl + << "Failed count (dist > " << maxDist << "): " << failed_count << " (" << (int)failed_percents << "%)" << std::endl + << "Max distance between valid and computed descriptors (" << validDescriptors.size() << "): " << curMaxDist; + EXPECT_LE(failed_percents, 20.0f); + std::cout << ss.str() << std::endl; } void emptyDataTest() @@ -202,22 +217,57 @@ protected: ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); return; } + const std::string keypoints_filename = string(ts->get_data_path()) + + (detector.empty() + ? (FEATURES2D_DIR + "/" + std::string("keypoints.xml.gz")) + : (DESCRIPTOR_DIR + "/" + name + "_keypoints.xml.gz")); + FileStorage fs(keypoints_filename, FileStorage::READ); + vector keypoints; - FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ ); - if(!detector.empty()) { - detector->detect(img, keypoints); - } else { - read( fs.getFirstTopLevelNode(), keypoints ); + EXPECT_TRUE(fs.isOpened()) << "Keypoint testdata is missing. Re-computing and re-writing keypoints testdata..."; + if (!fs.isOpened()) + { + fs.open(keypoints_filename, FileStorage::WRITE); + ASSERT_TRUE(fs.isOpened()) << "File for writting keypoints can not be opened."; + if (detector.empty()) + { + Ptr fd = ORB::create(); + fd->detect(img, keypoints); + } + else + { + detector->detect(img, keypoints); + } + write(fs, "keypoints", keypoints); + fs.release(); } - if(!keypoints.empty()) + else + { + read(fs.getFirstTopLevelNode(), keypoints); + fs.release(); + } + + if(!detector.empty()) + { + vector calcKeypoints; + detector->detect(img, calcKeypoints); + // TODO validate received keypoints + int diff = abs((int)calcKeypoints.size() - (int)keypoints.size()); + if (diff > 0) + { + std::cout << "Keypoints difference: " << diff << std::endl; + EXPECT_LE(diff, (int)(keypoints.size() * 0.03f)); + } + } + ASSERT_FALSE(keypoints.empty()); { Mat calcDescriptors; double t = (double)getTickCount(); - dextractor->compute( img, keypoints, calcDescriptors ); + dextractor->compute(img, keypoints, calcDescriptors); t = getTickCount() - t; ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)getTickFrequency()*1000.)/calcDescriptors.rows); - if( calcDescriptors.rows != (int)keypoints.size() ) + if (calcDescriptors.rows != (int)keypoints.size()) { ts->printf( cvtest::TS::LOG, "Count of computed descriptors and keypoints count must be equal.\n" ); ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() ); @@ -226,7 +276,7 @@ protected: return; } - if( calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType() ) + if (calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType()) { ts->printf( cvtest::TS::LOG, "Incorrect descriptor size or descriptor type.\n" ); ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() ); @@ -239,33 +289,14 @@ protected: // TODO read and write descriptor extractor parameters and check them Mat validDescriptors = readDescriptors(); - if( !validDescriptors.empty() ) - compareDescriptors( validDescriptors, calcDescriptors ); - else + EXPECT_FALSE(validDescriptors.empty()) << "Descriptors testdata is missing. Re-writing descriptors testdata..."; + if (!validDescriptors.empty()) { - if( !writeDescriptors( calcDescriptors ) ) - { - ts->printf( cvtest::TS::LOG, "Descriptors can not be written.\n" ); - ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); - return; - } - } - } - if(!fs.isOpened()) - { - ts->printf( cvtest::TS::LOG, "Compute and write keypoints.\n" ); - fs.open( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::WRITE ); - if( fs.isOpened() ) - { - Ptr fd = ORB::create(); - fd->detect(img, keypoints); - write( fs, "keypoints", keypoints ); + compareDescriptors(validDescriptors, calcDescriptors); } else { - ts->printf(cvtest::TS::LOG, "File for writting keypoints can not be opened.\n"); - ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); - return; + ASSERT_TRUE(writeDescriptors(calcDescriptors)) << "Descriptors can not be written."; } } } @@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression ) TEST( Features2d_DescriptorExtractor_AKAZE, regression ) { CV_DescriptorExtractorTest test( "descriptor-akaze", - (CV_DescriptorExtractorTest::DistanceType)12.f, + (CV_DescriptorExtractorTest::DistanceType)(486*0.05f), AKAZE::create(), Hamming(), AKAZE::create()); test.safe_run();