Skip to content

Commit 411d36f

Browse files
committed
features2d(test): update descriptor regression test
1 parent 63ae5f0 commit 411d36f

File tree

1 file changed

+74
-43
lines changed

1 file changed

+74
-43
lines changed

modules/features2d/test/test_descriptors_regression.cpp

Lines changed: 74 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename )
5656
FILE* f = fopen( filename.c_str(), "wb");
5757
if( f )
5858
{
59+
CV_Assert(4 == sizeof(int));
5960
int type = mat.type();
6061
fwrite( (void*)&mat.rows, sizeof(int), 1, f );
6162
fwrite( (void*)&mat.cols, sizeof(int), 1, f );
@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename )
7273
FILE* f = fopen( filename.c_str(), "rb" );
7374
if( f )
7475
{
76+
CV_Assert(4 == sizeof(int));
7577
int rows, cols, type, dataSize;
7678
size_t elements_read1 = fread( (void*)&rows, sizeof(int), 1, f );
7779
size_t elements_read2 = fread( (void*)&cols, sizeof(int), 1, f );
@@ -123,24 +125,37 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
123125
CV_Assert( DataType<ValueType>::type == validDescriptors.type() );
124126

125127
int dimension = validDescriptors.cols;
126-
DistanceType curMaxDist = std::numeric_limits<DistanceType>::min();
128+
DistanceType curMaxDist = 0;
129+
size_t exact_count = 0, failed_count = 0;
127130
for( int y = 0; y < validDescriptors.rows; y++ )
128131
{
129132
DistanceType dist = distance( validDescriptors.ptr<ValueType>(y), calcDescriptors.ptr<ValueType>(y), dimension );
133+
if (dist == 0)
134+
exact_count++;
130135
if( dist > curMaxDist )
136+
{
137+
if (dist > maxDist)
138+
failed_count++;
131139
curMaxDist = dist;
140+
}
141+
#if 0
142+
if (dist > 0)
143+
{
144+
std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl;
145+
std::cout << "valid: " << validDescriptors.row(y) << std::endl;
146+
std::cout << " calc: " << calcDescriptors.row(y) << std::endl;
147+
}
148+
#endif
132149
}
133150

151+
float exact_percents = (100 * (float)exact_count / validDescriptors.rows);
152+
float failed_percents = (100 * (float)failed_count / validDescriptors.rows);
134153
stringstream ss;
135-
ss << "Max distance between valid and computed descriptors " << curMaxDist;
136-
if( curMaxDist <= maxDist )
137-
ss << "." << endl;
138-
else
139-
{
140-
ss << ">" << maxDist << " - bad accuracy!"<< endl;
141-
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
142-
}
143-
ts->printf(cvtest::TS::LOG, ss.str().c_str() );
154+
ss << "Exact count (dist == 0): " << exact_count << " (" << (int)exact_percents << "%)" << std::endl
155+
<< "Failed count (dist > " << maxDist << "): " << failed_count << " (" << (int)failed_percents << "%)" << std::endl
156+
<< "Max distance between valid and computed descriptors (" << validDescriptors.size() << "): " << curMaxDist;
157+
EXPECT_LE(failed_percents, 20.0f);
158+
std::cout << ss.str() << std::endl;
144159
}
145160

146161
void emptyDataTest()
@@ -202,22 +217,57 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
202217
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
203218
return;
204219
}
220+
const std::string keypoints_filename = string(ts->get_data_path()) +
221+
(detector.empty()
222+
? (FEATURES2D_DIR + "/" + std::string("keypoints.xml.gz"))
223+
: (DESCRIPTOR_DIR + "/" + name + "_keypoints.xml.gz"));
224+
FileStorage fs(keypoints_filename, FileStorage::READ);
225+
205226
vector<KeyPoint> keypoints;
206-
FileStorage fs( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::READ );
207-
if(!detector.empty()) {
208-
detector->detect(img, keypoints);
209-
} else {
210-
read( fs.getFirstTopLevelNode(), keypoints );
227+
EXPECT_TRUE(fs.isOpened()) << "Keypoint testdata is missing. Re-computing and re-writing keypoints testdata...";
228+
if (!fs.isOpened())
229+
{
230+
fs.open(keypoints_filename, FileStorage::WRITE);
231+
ASSERT_TRUE(fs.isOpened()) << "File for writting keypoints can not be opened.";
232+
if (detector.empty())
233+
{
234+
Ptr<ORB> fd = ORB::create();
235+
fd->detect(img, keypoints);
236+
}
237+
else
238+
{
239+
detector->detect(img, keypoints);
240+
}
241+
write(fs, "keypoints", keypoints);
242+
fs.release();
211243
}
212-
if(!keypoints.empty())
244+
else
245+
{
246+
read(fs.getFirstTopLevelNode(), keypoints);
247+
fs.release();
248+
}
249+
250+
if(!detector.empty())
251+
{
252+
vector<KeyPoint> calcKeypoints;
253+
detector->detect(img, calcKeypoints);
254+
// TODO validate received keypoints
255+
int diff = abs((int)calcKeypoints.size() - (int)keypoints.size());
256+
if (diff > 0)
257+
{
258+
std::cout << "Keypoints difference: " << diff << std::endl;
259+
EXPECT_LE(diff, (int)(keypoints.size() * 0.03f));
260+
}
261+
}
262+
ASSERT_FALSE(keypoints.empty());
213263
{
214264
Mat calcDescriptors;
215265
double t = (double)getTickCount();
216-
dextractor->compute( img, keypoints, calcDescriptors );
266+
dextractor->compute(img, keypoints, calcDescriptors);
217267
t = getTickCount() - t;
218268
ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)getTickFrequency()*1000.)/calcDescriptors.rows);
219269

220-
if( calcDescriptors.rows != (int)keypoints.size() )
270+
if (calcDescriptors.rows != (int)keypoints.size())
221271
{
222272
ts->printf( cvtest::TS::LOG, "Count of computed descriptors and keypoints count must be equal.\n" );
223273
ts->printf( cvtest::TS::LOG, "Count of keypoints is %d.\n", (int)keypoints.size() );
@@ -226,7 +276,7 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
226276
return;
227277
}
228278

229-
if( calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType() )
279+
if (calcDescriptors.cols != dextractor->descriptorSize() || calcDescriptors.type() != dextractor->descriptorType())
230280
{
231281
ts->printf( cvtest::TS::LOG, "Incorrect descriptor size or descriptor type.\n" );
232282
ts->printf( cvtest::TS::LOG, "Expected size is %d.\n", dextractor->descriptorSize() );
@@ -239,33 +289,14 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
239289

240290
// TODO read and write descriptor extractor parameters and check them
241291
Mat validDescriptors = readDescriptors();
242-
if( !validDescriptors.empty() )
243-
compareDescriptors( validDescriptors, calcDescriptors );
244-
else
292+
EXPECT_FALSE(validDescriptors.empty()) << "Descriptors testdata is missing. Re-writing descriptors testdata...";
293+
if (!validDescriptors.empty())
245294
{
246-
if( !writeDescriptors( calcDescriptors ) )
247-
{
248-
ts->printf( cvtest::TS::LOG, "Descriptors can not be written.\n" );
249-
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
250-
return;
251-
}
252-
}
253-
}
254-
if(!fs.isOpened())
255-
{
256-
ts->printf( cvtest::TS::LOG, "Compute and write keypoints.\n" );
257-
fs.open( string(ts->get_data_path()) + FEATURES2D_DIR + "/keypoints.xml.gz", FileStorage::WRITE );
258-
if( fs.isOpened() )
259-
{
260-
Ptr<ORB> fd = ORB::create();
261-
fd->detect(img, keypoints);
262-
write( fs, "keypoints", keypoints );
295+
compareDescriptors(validDescriptors, calcDescriptors);
263296
}
264297
else
265298
{
266-
ts->printf(cvtest::TS::LOG, "File for writting keypoints can not be opened.\n");
267-
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
268-
return;
299+
ASSERT_TRUE(writeDescriptors(calcDescriptors)) << "Descriptors can not be written.";
269300
}
270301
}
271302
}
@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression )
344375
TEST( Features2d_DescriptorExtractor_AKAZE, regression )
345376
{
346377
CV_DescriptorExtractorTest<Hamming> test( "descriptor-akaze",
347-
(CV_DescriptorExtractorTest<Hamming>::DistanceType)12.f,
378+
(CV_DescriptorExtractorTest<Hamming>::DistanceType)(486*0.05f),
348379
AKAZE::create(),
349380
Hamming(), AKAZE::create());
350381
test.safe_run();

0 commit comments

Comments
 (0)