mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.1 KiB
167 lines
5.1 KiB
#include "perf_precomp.hpp" |
|
|
|
namespace opencv_test |
|
{ |
|
using namespace perf; |
|
|
|
CV_ENUM(NormType, NORM_L1, NORM_L2, NORM_L2SQR, NORM_HAMMING, NORM_HAMMING2) |
|
|
|
typedef tuple<NormType, MatType, bool> Norm_Destination_CrossCheck_t; |
|
typedef perf::TestBaseWithParam<Norm_Destination_CrossCheck_t> Norm_Destination_CrossCheck; |
|
|
|
typedef tuple<NormType, bool> Norm_CrossCheck_t; |
|
typedef perf::TestBaseWithParam<Norm_CrossCheck_t> Norm_CrossCheck; |
|
|
|
typedef tuple<MatType, bool> Source_CrossCheck_t; |
|
typedef perf::TestBaseWithParam<Source_CrossCheck_t> Source_CrossCheck; |
|
|
|
void generateData( Mat& query, Mat& train, const int sourceType ); |
|
|
|
PERF_TEST_P(Norm_Destination_CrossCheck, batchDistance_8U, |
|
testing::Combine(testing::Values((int)NORM_L1, (int)NORM_L2SQR), |
|
testing::Values(CV_32S, CV_32F), |
|
testing::Bool() |
|
) |
|
) |
|
{ |
|
NormType normType = get<0>(GetParam()); |
|
int destinationType = get<1>(GetParam()); |
|
bool isCrossCheck = get<2>(GetParam()); |
|
int knn = isCrossCheck ? 1 : 0; |
|
|
|
Mat queryDescriptors; |
|
Mat trainDescriptors; |
|
Mat dist; |
|
Mat ndix; |
|
|
|
generateData(queryDescriptors, trainDescriptors, CV_8U); |
|
|
|
TEST_CYCLE() |
|
{ |
|
batchDistance(queryDescriptors, trainDescriptors, dist, destinationType, (isCrossCheck) ? ndix : noArray(), |
|
normType, knn, Mat(), 0, isCrossCheck); |
|
} |
|
|
|
SANITY_CHECK(dist); |
|
if (isCrossCheck) SANITY_CHECK(ndix); |
|
} |
|
|
|
PERF_TEST_P(Norm_CrossCheck, batchDistance_Dest_32S, |
|
testing::Combine(testing::Values((int)NORM_HAMMING, (int)NORM_HAMMING2), |
|
testing::Bool() |
|
) |
|
) |
|
{ |
|
NormType normType = get<0>(GetParam()); |
|
bool isCrossCheck = get<1>(GetParam()); |
|
int knn = isCrossCheck ? 1 : 0; |
|
|
|
Mat queryDescriptors; |
|
Mat trainDescriptors; |
|
Mat dist; |
|
Mat ndix; |
|
|
|
generateData(queryDescriptors, trainDescriptors, CV_8U); |
|
|
|
TEST_CYCLE() |
|
{ |
|
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32S, (isCrossCheck) ? ndix : noArray(), |
|
normType, knn, Mat(), 0, isCrossCheck); |
|
} |
|
|
|
SANITY_CHECK(dist); |
|
if (isCrossCheck) SANITY_CHECK(ndix); |
|
} |
|
|
|
PERF_TEST_P(Source_CrossCheck, batchDistance_L2, |
|
testing::Combine(testing::Values(CV_8U, CV_32F), |
|
testing::Bool() |
|
) |
|
) |
|
{ |
|
int sourceType = get<0>(GetParam()); |
|
bool isCrossCheck = get<1>(GetParam()); |
|
int knn = isCrossCheck ? 1 : 0; |
|
|
|
Mat queryDescriptors; |
|
Mat trainDescriptors; |
|
Mat dist; |
|
Mat ndix; |
|
|
|
generateData(queryDescriptors, trainDescriptors, sourceType); |
|
|
|
declare.time(50); |
|
TEST_CYCLE() |
|
{ |
|
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(), |
|
NORM_L2, knn, Mat(), 0, isCrossCheck); |
|
} |
|
|
|
SANITY_CHECK(dist); |
|
if (isCrossCheck) SANITY_CHECK(ndix); |
|
} |
|
|
|
PERF_TEST_P(Norm_CrossCheck, batchDistance_32F, |
|
testing::Combine(testing::Values((int)NORM_L1, (int)NORM_L2SQR), |
|
testing::Bool() |
|
) |
|
) |
|
{ |
|
NormType normType = get<0>(GetParam()); |
|
bool isCrossCheck = get<1>(GetParam()); |
|
int knn = isCrossCheck ? 1 : 0; |
|
|
|
Mat queryDescriptors; |
|
Mat trainDescriptors; |
|
Mat dist; |
|
Mat ndix; |
|
|
|
generateData(queryDescriptors, trainDescriptors, CV_32F); |
|
declare.time(100); |
|
|
|
TEST_CYCLE() |
|
{ |
|
batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(), |
|
normType, knn, Mat(), 0, isCrossCheck); |
|
} |
|
|
|
SANITY_CHECK(dist, 1e-4); |
|
if (isCrossCheck) SANITY_CHECK(ndix); |
|
} |
|
|
|
void generateData( Mat& query, Mat& train, const int sourceType ) |
|
{ |
|
const int dim = 500; |
|
const int queryDescCount = 300; // must be even number because we split train data in some cases in two |
|
const int countFactor = 4; // do not change it |
|
RNG& rng = theRNG(); |
|
|
|
// Generate query descriptors randomly. |
|
// Descriptor vector elements are integer values. |
|
Mat buf( queryDescCount, dim, CV_32SC1 ); |
|
rng.fill( buf, RNG::UNIFORM, Scalar::all(0), Scalar(3) ); |
|
buf.convertTo( query, sourceType ); |
|
|
|
// Generate train descriptors as follows: |
|
// copy each query descriptor to train set countFactor times |
|
// and perturb some one element of the copied descriptors in |
|
// in ascending order. General boundaries of the perturbation |
|
// are (0.f, 1.f). |
|
train.create( query.rows*countFactor, query.cols, sourceType ); |
|
float step = (sourceType == CV_8U ? 256.f : 1.f) / countFactor; |
|
for( int qIdx = 0; qIdx < query.rows; qIdx++ ) |
|
{ |
|
Mat queryDescriptor = query.row(qIdx); |
|
for( int c = 0; c < countFactor; c++ ) |
|
{ |
|
int tIdx = qIdx * countFactor + c; |
|
Mat trainDescriptor = train.row(tIdx); |
|
queryDescriptor.copyTo( trainDescriptor ); |
|
int elem = rng(dim); |
|
float diff = rng.uniform( step*c, step*(c+1) ); |
|
trainDescriptor.col(elem) += diff; |
|
} |
|
} |
|
} |
|
|
|
} // namespace
|
|
|