Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/features2d/perf/perf_batchDistance.cpp
16354 views
1
#include "perf_precomp.hpp"
2
3
namespace opencv_test
4
{
5
using namespace perf;
6
7
CV_ENUM(NormType, NORM_L1, NORM_L2, NORM_L2SQR, NORM_HAMMING, NORM_HAMMING2)
8
9
typedef tuple<NormType, MatType, bool> Norm_Destination_CrossCheck_t;
10
typedef perf::TestBaseWithParam<Norm_Destination_CrossCheck_t> Norm_Destination_CrossCheck;
11
12
typedef tuple<NormType, bool> Norm_CrossCheck_t;
13
typedef perf::TestBaseWithParam<Norm_CrossCheck_t> Norm_CrossCheck;
14
15
typedef tuple<MatType, bool> Source_CrossCheck_t;
16
typedef perf::TestBaseWithParam<Source_CrossCheck_t> Source_CrossCheck;
17
18
void generateData( Mat& query, Mat& train, const int sourceType );
19
20
PERF_TEST_P(Norm_Destination_CrossCheck, batchDistance_8U,
21
testing::Combine(testing::Values((int)NORM_L1, (int)NORM_L2SQR),
22
testing::Values(CV_32S, CV_32F),
23
testing::Bool()
24
)
25
)
26
{
27
NormType normType = get<0>(GetParam());
28
int destinationType = get<1>(GetParam());
29
bool isCrossCheck = get<2>(GetParam());
30
int knn = isCrossCheck ? 1 : 0;
31
32
Mat queryDescriptors;
33
Mat trainDescriptors;
34
Mat dist;
35
Mat ndix;
36
37
generateData(queryDescriptors, trainDescriptors, CV_8U);
38
39
TEST_CYCLE()
40
{
41
batchDistance(queryDescriptors, trainDescriptors, dist, destinationType, (isCrossCheck) ? ndix : noArray(),
42
normType, knn, Mat(), 0, isCrossCheck);
43
}
44
45
SANITY_CHECK(dist);
46
if (isCrossCheck) SANITY_CHECK(ndix);
47
}
48
49
PERF_TEST_P(Norm_CrossCheck, batchDistance_Dest_32S,
50
testing::Combine(testing::Values((int)NORM_HAMMING, (int)NORM_HAMMING2),
51
testing::Bool()
52
)
53
)
54
{
55
NormType normType = get<0>(GetParam());
56
bool isCrossCheck = get<1>(GetParam());
57
int knn = isCrossCheck ? 1 : 0;
58
59
Mat queryDescriptors;
60
Mat trainDescriptors;
61
Mat dist;
62
Mat ndix;
63
64
generateData(queryDescriptors, trainDescriptors, CV_8U);
65
66
TEST_CYCLE()
67
{
68
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32S, (isCrossCheck) ? ndix : noArray(),
69
normType, knn, Mat(), 0, isCrossCheck);
70
}
71
72
SANITY_CHECK(dist);
73
if (isCrossCheck) SANITY_CHECK(ndix);
74
}
75
76
PERF_TEST_P(Source_CrossCheck, batchDistance_L2,
77
testing::Combine(testing::Values(CV_8U, CV_32F),
78
testing::Bool()
79
)
80
)
81
{
82
int sourceType = get<0>(GetParam());
83
bool isCrossCheck = get<1>(GetParam());
84
int knn = isCrossCheck ? 1 : 0;
85
86
Mat queryDescriptors;
87
Mat trainDescriptors;
88
Mat dist;
89
Mat ndix;
90
91
generateData(queryDescriptors, trainDescriptors, sourceType);
92
93
declare.time(50);
94
TEST_CYCLE()
95
{
96
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(),
97
NORM_L2, knn, Mat(), 0, isCrossCheck);
98
}
99
100
SANITY_CHECK(dist);
101
if (isCrossCheck) SANITY_CHECK(ndix);
102
}
103
104
PERF_TEST_P(Norm_CrossCheck, batchDistance_32F,
105
testing::Combine(testing::Values((int)NORM_L1, (int)NORM_L2SQR),
106
testing::Bool()
107
)
108
)
109
{
110
NormType normType = get<0>(GetParam());
111
bool isCrossCheck = get<1>(GetParam());
112
int knn = isCrossCheck ? 1 : 0;
113
114
Mat queryDescriptors;
115
Mat trainDescriptors;
116
Mat dist;
117
Mat ndix;
118
119
generateData(queryDescriptors, trainDescriptors, CV_32F);
120
declare.time(100);
121
122
TEST_CYCLE()
123
{
124
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(),
125
normType, knn, Mat(), 0, isCrossCheck);
126
}
127
128
SANITY_CHECK(dist, 1e-4);
129
if (isCrossCheck) SANITY_CHECK(ndix);
130
}
131
132
void generateData( Mat& query, Mat& train, const int sourceType )
133
{
134
const int dim = 500;
135
const int queryDescCount = 300; // must be even number because we split train data in some cases in two
136
const int countFactor = 4; // do not change it
137
RNG& rng = theRNG();
138
139
// Generate query descriptors randomly.
140
// Descriptor vector elements are integer values.
141
Mat buf( queryDescCount, dim, CV_32SC1 );
142
rng.fill( buf, RNG::UNIFORM, Scalar::all(0), Scalar(3) );
143
buf.convertTo( query, sourceType );
144
145
// Generate train descriptors as follows:
146
// copy each query descriptor to train set countFactor times
147
// and perturb some one element of the copied descriptors in
148
// in ascending order. General boundaries of the perturbation
149
// are (0.f, 1.f).
150
train.create( query.rows*countFactor, query.cols, sourceType );
151
float step = (sourceType == CV_8U ? 256.f : 1.f) / countFactor;
152
for( int qIdx = 0; qIdx < query.rows; qIdx++ )
153
{
154
Mat queryDescriptor = query.row(qIdx);
155
for( int c = 0; c < countFactor; c++ )
156
{
157
int tIdx = qIdx * countFactor + c;
158
Mat trainDescriptor = train.row(tIdx);
159
queryDescriptor.copyTo( trainDescriptor );
160
int elem = rng(dim);
161
float diff = rng.uniform( step*c, step*(c+1) );
162
trainDescriptor.col(elem) += diff;
163
}
164
}
165
}
166
167
} // namespace
168
169