@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename )
56
56
FILE* f = fopen ( filename.c_str (), " wb" );
57
57
if ( f )
58
58
{
59
+ CV_Assert (4 == sizeof (int ));
59
60
int type = mat.type ();
60
61
fwrite ( (void *)&mat.rows , sizeof (int ), 1 , f );
61
62
fwrite ( (void *)&mat.cols , sizeof (int ), 1 , f );
@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename )
72
73
FILE* f = fopen ( filename.c_str (), " rb" );
73
74
if ( f )
74
75
{
76
+ CV_Assert (4 == sizeof (int ));
75
77
int rows, cols, type, dataSize;
76
78
size_t elements_read1 = fread ( (void *)&rows, sizeof (int ), 1 , f );
77
79
size_t elements_read2 = fread ( (void *)&cols, sizeof (int ), 1 , f );
@@ -123,24 +125,37 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
123
125
CV_Assert ( DataType<ValueType>::type == validDescriptors.type () );
124
126
125
127
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 ;
127
130
for ( int y = 0 ; y < validDescriptors.rows ; y++ )
128
131
{
129
132
DistanceType dist = distance ( validDescriptors.ptr <ValueType>(y), calcDescriptors.ptr <ValueType>(y), dimension );
133
+ if (dist == 0 )
134
+ exact_count++;
130
135
if ( dist > curMaxDist )
136
+ {
137
+ if (dist > maxDist)
138
+ failed_count++;
131
139
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
132
149
}
133
150
151
+ float exact_percents = (100 * (float )exact_count / validDescriptors.rows );
152
+ float failed_percents = (100 * (float )failed_count / validDescriptors.rows );
134
153
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;
144
159
}
145
160
146
161
void emptyDataTest ()
@@ -202,22 +217,57 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
202
217
ts->set_failed_test_info ( cvtest::TS::FAIL_INVALID_TEST_DATA );
203
218
return ;
204
219
}
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
+
205
226
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 ();
211
243
}
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 ());
213
263
{
214
264
Mat calcDescriptors;
215
265
double t = (double )getTickCount ();
216
- dextractor->compute ( img, keypoints, calcDescriptors );
266
+ dextractor->compute (img, keypoints, calcDescriptors);
217
267
t = getTickCount () - t;
218
268
ts->printf (cvtest::TS::LOG, " \n Average time of computing one descriptor = %g ms.\n " , t/((double )getTickFrequency ()*1000 .)/calcDescriptors.rows );
219
269
220
- if ( calcDescriptors.rows != (int )keypoints.size () )
270
+ if ( calcDescriptors.rows != (int )keypoints.size ())
221
271
{
222
272
ts->printf ( cvtest::TS::LOG, " Count of computed descriptors and keypoints count must be equal.\n " );
223
273
ts->printf ( cvtest::TS::LOG, " Count of keypoints is %d.\n " , (int )keypoints.size () );
@@ -226,7 +276,7 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
226
276
return ;
227
277
}
228
278
229
- if ( calcDescriptors.cols != dextractor->descriptorSize () || calcDescriptors.type () != dextractor->descriptorType () )
279
+ if ( calcDescriptors.cols != dextractor->descriptorSize () || calcDescriptors.type () != dextractor->descriptorType ())
230
280
{
231
281
ts->printf ( cvtest::TS::LOG, " Incorrect descriptor size or descriptor type.\n " );
232
282
ts->printf ( cvtest::TS::LOG, " Expected size is %d.\n " , dextractor->descriptorSize () );
@@ -239,33 +289,14 @@ class CV_DescriptorExtractorTest : public cvtest::BaseTest
239
289
240
290
// TODO read and write descriptor extractor parameters and check them
241
291
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 ())
245
294
{
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);
263
296
}
264
297
else
265
298
{
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." ;
269
300
}
270
301
}
271
302
}
@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression )
344
375
TEST ( Features2d_DescriptorExtractor_AKAZE, regression )
345
376
{
346
377
CV_DescriptorExtractorTest<Hamming> test ( " descriptor-akaze" ,
347
- (CV_DescriptorExtractorTest<Hamming>::DistanceType)12 . f ,
378
+ (CV_DescriptorExtractorTest<Hamming>::DistanceType)( 486 * 0 . 05f ) ,
348
379
AKAZE::create (),
349
380
Hamming (), AKAZE::create ());
350
381
test.safe_run ();
0 commit comments