1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
14 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15 // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
16 // Third party copyrights are property of their respective owners.
17 //
18 // @Authors
19 // Niko Li, newlife20080214@gmail.com
20 // Jia Haipeng, jiahaipeng95@gmail.com
21 // Zero Lin, Zero.Lin@amd.com
22 // Zhang Ying, zhangying913@gmail.com
23 // Yao Wang, bitwangyaoyao@gmail.com
24 //
25 // Redistribution and use in source and binary forms, with or without modification,
26 // are permitted provided that the following conditions are met:
27 //
28 // * Redistribution's of source code must retain the above copyright notice,
29 // this list of conditions and the following disclaimer.
30 //
31 // * Redistribution's in binary form must reproduce the above copyright notice,
32 // this list of conditions and the following disclaimer in the documentation
33 // and/or other materials provided with the distribution.
34 //
35 // * The name of the copyright holders may not be used to endorse or promote products
36 // derived from this software without specific prior written permission.
37 //
38 // This software is provided by the copyright holders and contributors "as is" and
39 // any express or implied warranties, including, but not limited to, the implied
40 // warranties of merchantability and fitness for a particular purpose are disclaimed.
41 // In no event shall the Intel Corporation or contributors be liable for any direct,
42 // indirect, incidental, special, exemplary, or consequential damages
43 // (including, but not limited to, procurement of substitute goods or services;
44 // loss of use, data, or profits; or business interruption) however caused
45 // and on any theory of liability, whether in contract, strict liability,
46 // or tort (including negligence or otherwise) arising in any way out of
47 // the use of this software, even if advised of the possibility of such damage.
48 //
49 //M*/
50
51 #include "../test_precomp.hpp"
52 #include "cvconfig.h"
53 #include "opencv2/ts/ocl_test.hpp"
54
55 #ifdef HAVE_OPENCL
56
57 namespace cvtest {
58 namespace ocl {
PARAM_TEST_CASE(BruteForceMatcher,int,int)59 PARAM_TEST_CASE(BruteForceMatcher, int, int)
60 {
61 int distType;
62 int dim;
63
64 int queryDescCount;
65 int countFactor;
66
67 Mat query, train;
68 UMat uquery, utrain;
69
70 virtual void SetUp()
71 {
72 distType = GET_PARAM(0);
73 dim = GET_PARAM(1);
74
75 queryDescCount = 300; // must be even number because we split train data in some cases in two
76 countFactor = 4; // do not change it
77
78 cv::Mat queryBuf, trainBuf;
79
80 // Generate query descriptors randomly.
81 // Descriptor vector elements are integer values.
82 queryBuf.create(queryDescCount, dim, CV_32SC1);
83 rng.fill(queryBuf, cv::RNG::UNIFORM, cv::Scalar::all(0), cv::Scalar::all(3));
84 queryBuf.convertTo(queryBuf, CV_32FC1);
85
86 // Generate train decriptors as follows:
87 // copy each query descriptor to train set countFactor times
88 // and perturb some one element of the copied descriptors in
89 // in ascending order. General boundaries of the perturbation
90 // are (0.f, 1.f).
91 trainBuf.create(queryDescCount * countFactor, dim, CV_32FC1);
92 float step = 1.f / countFactor;
93 for (int qIdx = 0; qIdx < queryDescCount; qIdx++)
94 {
95 cv::Mat queryDescriptor = queryBuf.row(qIdx);
96 for (int c = 0; c < countFactor; c++)
97 {
98 int tIdx = qIdx * countFactor + c;
99 cv::Mat trainDescriptor = trainBuf.row(tIdx);
100 queryDescriptor.copyTo(trainDescriptor);
101 int elem = rng(dim);
102 float diff = rng.uniform(step * c, step * (c + 1));
103 trainDescriptor.at<float>(0, elem) += diff;
104 }
105 }
106
107 queryBuf.convertTo(query, CV_32F);
108 trainBuf.convertTo(train, CV_32F);
109 query.copyTo(uquery);
110 train.copyTo(utrain);
111 }
112 };
113
114 #ifdef ANDROID
OCL_TEST_P(BruteForceMatcher,DISABLED_Match_Single)115 OCL_TEST_P(BruteForceMatcher, DISABLED_Match_Single)
116 #else
117 OCL_TEST_P(BruteForceMatcher, Match_Single)
118 #endif
119 {
120 BFMatcher matcher(distType);
121
122 std::vector<cv::DMatch> matches;
123 matcher.match(uquery, utrain, matches);
124
125 ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
126
127 int badCount = 0;
128 for (size_t i = 0; i < matches.size(); i++)
129 {
130 cv::DMatch match = matches[i];
131 if ((match.queryIdx != (int)i) || (match.trainIdx != (int)i * countFactor) || (match.imgIdx != 0))
132 badCount++;
133 }
134
135 ASSERT_EQ(0, badCount);
136 }
137
138 #ifdef ANDROID
OCL_TEST_P(BruteForceMatcher,DISABLED_KnnMatch_2_Single)139 OCL_TEST_P(BruteForceMatcher, DISABLED_KnnMatch_2_Single)
140 #else
141 OCL_TEST_P(BruteForceMatcher, KnnMatch_2_Single)
142 #endif
143 {
144 const int knn = 2;
145
146 BFMatcher matcher(distType);
147
148 std::vector< std::vector<cv::DMatch> > matches;
149 matcher.knnMatch(uquery, utrain, matches, knn);
150
151 ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
152
153 int badCount = 0;
154 for (size_t i = 0; i < matches.size(); i++)
155 {
156 if ((int)matches[i].size() != knn)
157 badCount++;
158 else
159 {
160 int localBadCount = 0;
161 for (int k = 0; k < knn; k++)
162 {
163 cv::DMatch match = matches[i][k];
164 if ((match.queryIdx != (int)i) || (match.trainIdx != (int)i * countFactor + k) || (match.imgIdx != 0))
165 localBadCount++;
166 }
167 badCount += localBadCount > 0 ? 1 : 0;
168 }
169 }
170
171 ASSERT_EQ(0, badCount);
172 }
173
174 #ifdef ANDROID
OCL_TEST_P(BruteForceMatcher,DISABLED_RadiusMatch_Single)175 OCL_TEST_P(BruteForceMatcher, DISABLED_RadiusMatch_Single)
176 #else
177 OCL_TEST_P(BruteForceMatcher, RadiusMatch_Single)
178 #endif
179 {
180 float radius = 1.f / countFactor;
181
182 BFMatcher matcher(distType);
183
184 std::vector< std::vector<cv::DMatch> > matches;
185 matcher.radiusMatch(uquery, utrain, matches, radius);
186
187 ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
188
189 int badCount = 0;
190 for (size_t i = 0; i < matches.size(); i++)
191 {
192 if ((int)matches[i].size() != 1)
193 {
194 badCount++;
195 }
196 else
197 {
198 cv::DMatch match = matches[i][0];
199 if ((match.queryIdx != (int)i) || (match.trainIdx != (int)i * countFactor) || (match.imgIdx != 0))
200 badCount++;
201 }
202 }
203
204 ASSERT_EQ(0, badCount);
205 }
206
207 OCL_INSTANTIATE_TEST_CASE_P(Matcher, BruteForceMatcher, Combine( Values((int)NORM_L1, (int)NORM_L2),
208 Values(57, 64, 83, 128, 179, 256, 304) ) );
209
210 }//ocl
211 }//cvtest
212
213 #endif //HAVE_OPENCL
214