Commit 411d36ff authored by Alexander Alekhin's avatar Alexander Alekhin

features2d(test): update descriptor regression test

parent 63ae5f00
...@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename ) ...@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename )
FILE* f = fopen( filename.c_str(), "wb"); FILE* f = fopen( filename.c_str(), "wb");
if( f ) if( f )
{ {
CV_Assert(4 == sizeof(int));
int type = mat.type(); int type = mat.type();
fwrite( (void*)&mat.rows, sizeof(int), 1, f ); fwrite( (void*)&mat.rows, sizeof(int), 1, f );
fwrite( (void*)&mat.cols, sizeof(int), 1, f ); fwrite( (void*)&mat.cols, sizeof(int), 1, f );
...@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename ) ...@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename )
FILE* f = fopen( filename.c_str(), "rb" ); FILE* f = fopen( filename.c_str(), "rb" );
if( f ) if( f )
{ {
CV_Assert(4 == sizeof(int));
int rows, cols, type, dataSize; int rows, cols, type, dataSize;
size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f ); size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f );
size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f ); size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f );
...@@ -123,24 +125,37 @@ protected: ...@@ -123,24 +125,37 @@ protected:
CV_Assert( DataType<ValueType>::type == validDescriptors.type() ); CV_Assert( DataType<ValueType>::type == validDescriptors.type() );
int dimension = validDescriptors.cols; int dimension = validDescriptors.cols;
DistanceType curMaxDist = std::numeric_limits<DistanceType>::min(); DistanceType curMaxDist = 0;
size_t exact_count = 0, failed_count = 0;
for( int y = 0; y < validDescriptors.rows; y++ ) for( int y = 0; y < validDescriptors.rows; y++ )
{ {
DistanceType dist = distance( validDescriptors.ptr<ValueType>(y), calcDescriptors.ptr<ValueType>(y), dimension ); DistanceType dist = distance( validDescriptors.ptr<ValueType>(y), calcDescriptors.ptr<ValueType>(y), dimension );
if (dist == 0)
exact_count++;
if( dist > curMaxDist ) if( dist > curMaxDist )
{
if (dist > maxDist)
failed_count++;
curMaxDist = dist; curMaxDist = dist;
} }
#if 0
stringstream ss; if (dist > 0)
ss << "Max distance between valid and computed descriptors " << curMaxDist;
if( curMaxDist <= maxDist )
ss << "." << endl;
else
{ {
ss << ">" << maxDist << " - bad accuracy!"<< endl; std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl;
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); std::cout << "valid: " << validDescriptors.row(y) << std::endl;
std::cout << " calc: " << calcDescriptors.row(y) << std::endl;
}
#endif
} }
ts->printf(cvtest::TS::LOG, ss.str().c_str() );
float exact_percents = (100 * (float)exact_count / validDescriptors.rows);
float failed_percents = (100 * (float)failed_count / validDescriptors.rows);
stringstream ss;
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() void emptyDataTest()
...@@ -202,22 +217,57 @@ protected: ...@@ -202,22 +217,57 @@ protected:
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return; 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<KeyPoint> keypoints; vector<KeyPoint> keypoints;
FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ ); EXPECT_TRUE(fs.isOpened()) << "Keypoint testdata is missing. Re-computing and re-writing keypoints testdata...";
if(!detector.empty()) { 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<ORB> fd = ORB::create();
fd->detect(img, keypoints);
}
else
{
detector->detect(img, keypoints); detector->detect(img, keypoints);
} else {
read( fs.getFirstTopLevelNode(), keypoints );
} }
if(!keypoints.empty()) write(fs, "keypoints", keypoints);
fs.release();
}
else
{
read(fs.getFirstTopLevelNode(), keypoints);
fs.release();
}
if(!detector.empty())
{
vector<KeyPoint> 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; Mat calcDescriptors;
double t = (double)getTickCount(); double t = (double)getTickCount();
dextractor->compute( img, keypoints, calcDescriptors ); dextractor->compute(img, keypoints, calcDescriptors);
t = getTickCount() - t; t = getTickCount() - t;
ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)getTickFrequency()*1000.)/calcDescriptors.rows); 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 computed descriptors and keypoints count must be equal.\n" );
ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() ); ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() );
...@@ -226,7 +276,7 @@ protected: ...@@ -226,7 +276,7 @@ protected:
return; 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, "Incorrect descriptor size or descriptor type.\n" );
ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() ); ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() );
...@@ -239,33 +289,14 @@ protected: ...@@ -239,33 +289,14 @@ protected:
// TODO read and write descriptor extractor parameters and check them // TODO read and write descriptor extractor parameters and check them
Mat validDescriptors = readDescriptors(); Mat validDescriptors = readDescriptors();
if( !validDescriptors.empty() ) EXPECT_FALSE(validDescriptors.empty()) << "Descriptors testdata is missing. Re-writing descriptors testdata...";
compareDescriptors( validDescriptors, calcDescriptors ); if (!validDescriptors.empty())
else
{
if( !writeDescriptors( calcDescriptors ) )
{ {
ts->printf( cvtest::TS::LOG, "Descriptors can not be written.\n" ); compareDescriptors(validDescriptors, calcDescriptors);
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<ORB> fd = ORB::create();
fd->detect(img, keypoints);
write( fs, "keypoints", keypoints );
} }
else else
{ {
ts->printf(cvtest::TS::LOG, "File for writting keypoints can not be opened.\n"); ASSERT_TRUE(writeDescriptors(calcDescriptors)) << "Descriptors can not be written.";
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
} }
} }
} }
...@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression ) ...@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression )
TEST( Features2d_DescriptorExtractor_AKAZE, regression ) TEST( Features2d_DescriptorExtractor_AKAZE, regression )
{ {
CV_DescriptorExtractorTest<Hamming> test( "descriptor-akaze", CV_DescriptorExtractorTest<Hamming> test( "descriptor-akaze",
(CV_DescriptorExtractorTest<Hamming>::DistanceType)12.f, (CV_DescriptorExtractorTest<Hamming>::DistanceType)(486*0.05f),
AKAZE::create(), AKAZE::create(),
Hamming(), AKAZE::create()); Hamming(), AKAZE::create());
test.safe_run(); test.safe_run();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment