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) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
22 //
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
26 //
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "test_precomp.hpp"
44 #include "opencv2/ts/ocl_test.hpp" // T-API like tests
45
46 namespace opencv_test {
47 namespace {
48
49 class CV_OperationsTest : public cvtest::BaseTest
50 {
51 public:
52 CV_OperationsTest();
53 ~CV_OperationsTest();
54 protected:
55 void run(int);
56
57 struct test_excep
58 {
test_excepopencv_test::__anon1e3f11a60111::CV_OperationsTest::test_excep59 test_excep(const string& _s=string("")) : s(_s) { }
60 string s;
61 };
62
63 bool SomeMatFunctions();
64 bool TestMat();
65 template<typename _Tp> void TestType(Size sz, _Tp value);
66 bool TestTemplateMat();
67 bool TestMatND();
68 bool TestSparseMat();
69 bool TestVec();
70 bool TestMatxMultiplication();
71 bool TestMatxElementwiseDivison();
72 bool TestDivisionByValue();
73 bool TestInplaceDivisionByValue();
74 bool TestMatMatxCastSum();
75 bool TestSubMatAccess();
76 bool TestExp();
77 bool TestSVD();
78 bool operations1();
79
checkDiff(const Mat & m1,const Mat & m2,const string & s)80 void checkDiff(const Mat& m1, const Mat& m2, const string& s)
81 {
82 if (cvtest::norm(m1, m2, NORM_INF) != 0) throw test_excep(s);
83 }
checkDiffF(const Mat & m1,const Mat & m2,const string & s)84 void checkDiffF(const Mat& m1, const Mat& m2, const string& s)
85 {
86 if (cvtest::norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s);
87 }
88 };
89
CV_OperationsTest()90 CV_OperationsTest::CV_OperationsTest()
91 {
92 }
93
~CV_OperationsTest()94 CV_OperationsTest::~CV_OperationsTest() {}
95
96 #define STR(a) STR2(a)
97 #define STR2(a) #a
98
99 #define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ") != (" #b ") at l." STR(__LINE__))
100 #define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ") !=(eps) (" #b ") at l." STR(__LINE__))
101
102 #if defined _MSC_VER && _MSC_VER < 1400
103 #define MSVC_OLD 1
104 #else
105 #define MSVC_OLD 0
106 #endif
107
TestType(Size sz,_Tp value)108 template<typename _Tp> void CV_OperationsTest::TestType(Size sz, _Tp value)
109 {
110 cv::Mat_<_Tp> m(sz);
111 CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == cv::traits::Depth<_Tp>::value &&
112 m.channels() == DataType<_Tp>::channels &&
113 m.elemSize() == sizeof(_Tp) && m.step == m.elemSize()*m.cols);
114 for( int y = 0; y < sz.height; y++ )
115 for( int x = 0; x < sz.width; x++ )
116 {
117 m(y,x) = value;
118 }
119
120 double s = sum(Mat(m).reshape(1))[0];
121 CV_Assert( s == (double)sz.width*sz.height );
122 }
123
TestMat()124 bool CV_OperationsTest::TestMat()
125 {
126 try
127 {
128 Mat one_3x1(3, 1, CV_32F, Scalar(1.0));
129 Mat shi_3x1(3, 1, CV_32F, Scalar(1.2));
130 Mat shi_2x1(2, 1, CV_32F, Scalar(-1));
131 Scalar shift = Scalar::all(15);
132
133 float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
134 Mat rot_2x3(2, 3, CV_32F, data);
135
136 Mat res = one_3x1 + shi_3x1 + shi_3x1 + shi_3x1;
137 res = Mat(Mat(2 * rot_2x3) * res - shi_2x1) + shift;
138
139 Mat tmp, res2;
140 cv::add(one_3x1, shi_3x1, tmp);
141 cv::add(tmp, shi_3x1, tmp);
142 cv::add(tmp, shi_3x1, tmp);
143 cv::gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
144 cv::add(res2, Mat(2, 1, CV_32F, shift), res2);
145
146 CHECK_DIFF(res, res2);
147
148 Mat mat4x4(4, 4, CV_32F);
149 cv::randu(mat4x4, Scalar(0), Scalar(10));
150
151 Mat roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
152 Mat roi2 = mat4x4(Range(1, 3), Range(1, 3));
153
154 CHECK_DIFF(roi1, roi2);
155 CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
156
157 Mat intMat10(3, 3, CV_32S, Scalar(10));
158 Mat intMat11(3, 3, CV_32S, Scalar(11));
159 Mat resMat(3, 3, CV_8U, Scalar(255));
160
161 CHECK_DIFF(resMat, intMat10 == intMat10);
162 CHECK_DIFF(resMat, intMat10 < intMat11);
163 CHECK_DIFF(resMat, intMat11 > intMat10);
164 CHECK_DIFF(resMat, intMat10 <= intMat11);
165 CHECK_DIFF(resMat, intMat11 >= intMat10);
166 CHECK_DIFF(resMat, intMat11 != intMat10);
167
168 CHECK_DIFF(resMat, intMat10 == 10.0);
169 CHECK_DIFF(resMat, 10.0 == intMat10);
170 CHECK_DIFF(resMat, intMat10 < 11.0);
171 CHECK_DIFF(resMat, 11.0 > intMat10);
172 CHECK_DIFF(resMat, 10.0 < intMat11);
173 CHECK_DIFF(resMat, 11.0 >= intMat10);
174 CHECK_DIFF(resMat, 10.0 <= intMat11);
175 CHECK_DIFF(resMat, 10.0 != intMat11);
176 CHECK_DIFF(resMat, intMat11 != 10.0);
177
178 Mat eye = Mat::eye(3, 3, CV_16S);
179 Mat maskMat4(3, 3, CV_16S, Scalar(4));
180 Mat maskMat1(3, 3, CV_16S, Scalar(1));
181 Mat maskMat5(3, 3, CV_16S, Scalar(5));
182 Mat maskMat0(3, 3, CV_16S, Scalar(0));
183
184 CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
185 CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
186 CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
187
188 Mat m;
189 m = maskMat4.clone(); m &= maskMat1; CHECK_DIFF(maskMat0, m);
190 m = maskMat4.clone(); m &= maskMat1 | maskMat1; CHECK_DIFF(maskMat0, m);
191 m = maskMat4.clone(); m &= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat0, m);
192
193 m = maskMat4.clone(); m &= Scalar(1); CHECK_DIFF(maskMat0, m);
194 m = maskMat4.clone(); m |= maskMat1; CHECK_DIFF(maskMat5, m);
195 m = maskMat5.clone(); m ^= maskMat1; CHECK_DIFF(maskMat4, m);
196 m = maskMat4.clone(); m |= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat5, m);
197 m = maskMat5.clone(); m ^= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat4, m);
198
199 m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
200 m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
201
202
203
204 CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
205 CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
206 CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
207 CHECK_DIFF(maskMat0, (maskMat1 | maskMat1) & Scalar(4));
208 CHECK_DIFF(maskMat0, Scalar(4) & (maskMat1 | maskMat1));
209
210 CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
211 CHECK_DIFF(maskMat0, (maskMat4 | maskMat1) ^ maskMat5);
212 CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ (maskMat4 + maskMat1));
213 CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
214 CHECK_DIFF(maskMat1, Scalar(5) ^ maskMat4);
215 CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 + maskMat1));
216 CHECK_DIFF(maskMat5, Scalar(5) | (maskMat4 + maskMat1));
217 CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ Scalar(5));
218
219 CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
220 CHECK_DIFF(maskMat5, (maskMat4 ^ maskMat1) | maskMat5);
221 CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
222 CHECK_DIFF(maskMat5, (maskMat4 | maskMat4) | Scalar(1));
223 CHECK_DIFF(maskMat5, Scalar(1) | (maskMat4 | maskMat4));
224 CHECK_DIFF(maskMat5, Scalar(1) | maskMat4);
225 CHECK_DIFF(maskMat5, (maskMat5 | maskMat5) | (maskMat4 ^ maskMat1));
226
227 CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
228 CHECK_DIFF(maskMat1, min(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
229 CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
230 CHECK_DIFF(maskMat5, max(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
231
232 CHECK_DIFF(maskMat1, min(maskMat1, maskMat5 | maskMat5));
233 CHECK_DIFF(maskMat1, min(maskMat1 | maskMat1, maskMat5));
234 CHECK_DIFF(maskMat5, max(maskMat1 | maskMat1, maskMat5));
235 CHECK_DIFF(maskMat5, max(maskMat1, maskMat5 | maskMat5));
236
237 CHECK_DIFF(~maskMat1, maskMat1 ^ -1);
238 CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ -1);
239
240 CHECK_DIFF(maskMat1, maskMat4/4.0);
241
242 /////////////////////////////
243
244 CHECK_DIFF(1.0 - (maskMat5 | maskMat5), -maskMat4);
245 CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 1.0, maskMat5);
246 CHECK_DIFF(1.0 + (maskMat4 | maskMat4) * 1.0, maskMat5);
247 CHECK_DIFF((maskMat5 | maskMat5) * 1.0 - 1.0, maskMat4);
248 CHECK_DIFF(5.0 - (maskMat4 | maskMat4) * 1.0, maskMat1);
249 CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 0.5 + 0.5, maskMat5);
250 CHECK_DIFF(0.5 + ((maskMat4 | maskMat4) * 1.0 + 0.5), maskMat5);
251 CHECK_DIFF(((maskMat4 | maskMat4) * 1.0 + 2.0) - 1.0, maskMat5);
252 CHECK_DIFF(5.0 - ((maskMat1 | maskMat1) * 1.0 + 3.0), maskMat1);
253 CHECK_DIFF( ( (maskMat1 | maskMat1) * 2.0 + 2.0) * 1.25, maskMat5);
254 CHECK_DIFF( 1.25 * ( (maskMat1 | maskMat1) * 2.0 + 2.0), maskMat5);
255 CHECK_DIFF( -( (maskMat1 | maskMat1) * (-2.0) + 1.0), maskMat1);
256 CHECK_DIFF( maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0, maskMat5);
257 CHECK_DIFF( 1.0 + (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
258 CHECK_DIFF( (maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0) - 1.0, maskMat4);
259 CHECK_DIFF(5.0 - (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat1);
260 CHECK_DIFF((maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0)*1.25, maskMat5);
261 CHECK_DIFF(1.25 * (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
262 CHECK_DIFF(-(maskMat1 * 2.0 + maskMat4 * (-1) + 1.0), maskMat1);
263 CHECK_DIFF((maskMat1 * 1.0 + maskMat4), maskMat5);
264 CHECK_DIFF((maskMat4 + maskMat1 * 1.0), maskMat5);
265 CHECK_DIFF((maskMat1 * 3.0 + 1.0) + maskMat1, maskMat5);
266 CHECK_DIFF(maskMat1 + (maskMat1 * 3.0 + 1.0), maskMat5);
267 CHECK_DIFF(maskMat1*4.0 + (maskMat1 | maskMat1), maskMat5);
268 CHECK_DIFF((maskMat1 | maskMat1) + maskMat1*4.0, maskMat5);
269 CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1 | maskMat1), maskMat5);
270 CHECK_DIFF((maskMat1 | maskMat1) + (maskMat1*3.0 + 1.0), maskMat5);
271 CHECK_DIFF(maskMat1*4.0 + maskMat4*2.0, maskMat1 * 12);
272 CHECK_DIFF((maskMat1*3.0 + 1.0) + maskMat4*2.0, maskMat1 * 12);
273 CHECK_DIFF(maskMat4*2.0 + (maskMat1*3.0 + 1.0), maskMat1 * 12);
274 CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1*2.0 + 2.0), maskMat1 * 8);
275
276 CHECK_DIFF(maskMat5*1.0 - maskMat4, maskMat1);
277 CHECK_DIFF(maskMat5 - maskMat1 * 4.0, maskMat1);
278 CHECK_DIFF((maskMat4 * 1.0 + 4.0)- maskMat4, maskMat4);
279 CHECK_DIFF(maskMat5 - (maskMat1 * 2.0 + 2.0), maskMat1);
280 CHECK_DIFF(maskMat5*1.0 - (maskMat4 | maskMat4), maskMat1);
281 CHECK_DIFF((maskMat5 | maskMat5) - maskMat1 * 4.0, maskMat1);
282 CHECK_DIFF((maskMat4 * 1.0 + 4.0)- (maskMat4 | maskMat4), maskMat4);
283 CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 * 2.0 + 2.0), maskMat1);
284 CHECK_DIFF(maskMat1*5.0 - maskMat4 * 1.0, maskMat1);
285 CHECK_DIFF((maskMat1*5.0 + 3.0)- maskMat4 * 1.0, maskMat4);
286 CHECK_DIFF(maskMat4 * 2.0 - (maskMat1*4.0 + 3.0), maskMat1);
287 CHECK_DIFF((maskMat1 * 2.0 + 3.0) - (maskMat1*3.0 + 1.0), maskMat1);
288
289 CHECK_DIFF((maskMat5 - maskMat4)* 4.0, maskMat4);
290 CHECK_DIFF(4.0 * (maskMat5 - maskMat4), maskMat4);
291
292 CHECK_DIFF(-((maskMat4 | maskMat4) - (maskMat5 | maskMat5)), maskMat1);
293
294 CHECK_DIFF(4.0 * (maskMat1 | maskMat1), maskMat4);
295 CHECK_DIFF((maskMat4 | maskMat4)/4.0, maskMat1);
296
297 #if !MSVC_OLD
298 CHECK_DIFF(2.0 * (maskMat1 * 2.0) , maskMat4);
299 #endif
300 CHECK_DIFF((maskMat4 / 2.0) / 2.0 , maskMat1);
301 CHECK_DIFF(-(maskMat4 - maskMat5) , maskMat1);
302 CHECK_DIFF(-((maskMat4 - maskMat5) * 1.0), maskMat1);
303
304
305 /////////////////////////////
306 CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
307
308 ///// Element-wise multiplication
309
310 CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
311 CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
312 CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
313 CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
314 CHECK_DIFF(maskMat4.mul(maskMat4) * 0.25, maskMat4);
315 CHECK_DIFF(0.25 * maskMat4.mul(maskMat4), maskMat4);
316
317 ////// Element-wise division
318
319 CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
320 CHECK_DIFF((maskMat4 & maskMat4) / (maskMat1 * 4), maskMat1);
321
322 CHECK_DIFF((maskMat4 & maskMat4) / maskMat4, maskMat1);
323 CHECK_DIFF(maskMat4 / (maskMat4 & maskMat4), maskMat1);
324 CHECK_DIFF((maskMat1 * 4) / maskMat4, maskMat1);
325
326 CHECK_DIFF(maskMat4 / (maskMat1 * 4), maskMat1);
327 CHECK_DIFF((maskMat4 * 0.5 )/ (maskMat1 * 2), maskMat1);
328
329 CHECK_DIFF(maskMat4 / maskMat4.mul(maskMat1), maskMat1);
330 CHECK_DIFF((maskMat4 & maskMat4) / maskMat4.mul(maskMat1), maskMat1);
331
332 CHECK_DIFF(4.0 / maskMat4, maskMat1);
333 CHECK_DIFF(4.0 / (maskMat4 | maskMat4), maskMat1);
334 CHECK_DIFF(4.0 / (maskMat1 * 4.0), maskMat1);
335 CHECK_DIFF(4.0 / (maskMat4 / maskMat1), maskMat1);
336
337 m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
338 m = maskMat4.clone(); m/=maskMat4; CHECK_DIFF(m, maskMat1);
339 m = maskMat4.clone(); m/=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
340 m = maskMat4.clone(); m/=(maskMat4 / maskMat1); CHECK_DIFF(m, maskMat1);
341
342 /////////////////////////////
343 float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
344 Mat mt(3, 3, CV_32F, matrix_data);
345 Mat mi = mt.inv();
346 Mat d1 = Mat::eye(3, 3, CV_32F);
347 Mat d2 = d1 * 2;
348 MatExpr mt_tr = mt.t();
349 MatExpr mi_tr = mi.t();
350 Mat mi2 = mi * 2;
351
352
353 CHECK_DIFF_FLT( mi2 * mt, d2 );
354 CHECK_DIFF_FLT( mi * mt, d1 );
355 CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
356
357 m = mi.clone(); m*=mt; CHECK_DIFF_FLT(m, d1);
358 m = mi.clone(); m*= (2 * mt - mt) ; CHECK_DIFF_FLT(m, d1);
359
360 m = maskMat4.clone(); m+=(maskMat1 * 1.0); CHECK_DIFF(m, maskMat5);
361 m = maskMat5.clone(); m-=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
362
363 m = maskMat1.clone(); m+=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat5);
364 m = maskMat5.clone(); m-=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat1);
365 #if !MSVC_OLD
366 m = mi.clone(); m+=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi + d1 * 4);
367 m = mi.clone(); m-=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi - d1 * 4);
368 m = mi.clone(); m*=(mt * 1.0); CHECK_DIFF_FLT(m, d1);
369 m = mi.clone(); m*=(mt * 1.0 + Mat::eye(m.size(), m.type())); CHECK_DIFF_FLT(m, d1 + mi);
370 m = mi.clone(); m*=mt_tr.t(); CHECK_DIFF_FLT(m, d1);
371
372 CHECK_DIFF_FLT( (mi * 2) * mt, d2);
373 CHECK_DIFF_FLT( mi * (2 * mt), d2);
374 CHECK_DIFF_FLT( mt.t() * mi_tr, d1 );
375 CHECK_DIFF_FLT( mt_tr * mi.t(), d1 );
376 CHECK_DIFF_FLT( (mi * 0.4) * (mt * 5), d2);
377
378 CHECK_DIFF_FLT( mt.t() * (mi_tr * 2), d2 );
379 CHECK_DIFF_FLT( (mt_tr * 2) * mi.t(), d2 );
380
381 CHECK_DIFF_FLT(mt.t() * mi.t(), d1);
382 CHECK_DIFF_FLT( (mi * mt) * 2.0, d2);
383 CHECK_DIFF_FLT( 2.0 * (mi * mt), d2);
384 CHECK_DIFF_FLT( -(mi * mt), -d1);
385
386 CHECK_DIFF_FLT( (mi * mt) / 2.0, d1 / 2);
387
388 Mat mt_mul_2_plus_1;
389 gemm(mt, d1, 2, Mat::ones(3, 3, CV_32F), 1, mt_mul_2_plus_1);
390
391 CHECK_DIFF( (mt * 2.0 + 1.0) * mi, mt_mul_2_plus_1 * mi); // (A*alpha + beta)*B
392 CHECK_DIFF( mi * (mt * 2.0 + 1.0), mi * mt_mul_2_plus_1); // A*(B*alpha + beta)
393 CHECK_DIFF( (mt * 2.0 + 1.0) * (mi * 2), mt_mul_2_plus_1 * mi2); // (A*alpha + beta)*(B*gamma)
394 CHECK_DIFF( (mi *2)* (mt * 2.0 + 1.0), mi2 * mt_mul_2_plus_1); // (A*gamma)*(B*alpha + beta)
395 CHECK_DIFF_FLT( (mt * 2.0 + 1.0) * mi.t(), mt_mul_2_plus_1 * mi_tr); // (A*alpha + beta)*B^t
396 CHECK_DIFF_FLT( mi.t() * (mt * 2.0 + 1.0), mi_tr * mt_mul_2_plus_1); // A^t*(B*alpha + beta)
397
398 CHECK_DIFF_FLT( (mi * mt + d2)*5, d1 * 3 * 5);
399 CHECK_DIFF_FLT( mi * mt + d2, d1 * 3);
400 CHECK_DIFF_FLT( -(mi * mt) + d2, d1);
401 CHECK_DIFF_FLT( (mi * mt) + d1, d2);
402 CHECK_DIFF_FLT( d1 + (mi * mt), d2);
403 CHECK_DIFF_FLT( (mi * mt) - d2, -d1);
404 CHECK_DIFF_FLT( d2 - (mi * mt), d1);
405
406 CHECK_DIFF_FLT( (mi * mt) + d2 * 0.5, d2);
407 CHECK_DIFF_FLT( d2 * 0.5 + (mi * mt), d2);
408 CHECK_DIFF_FLT( (mi * mt) - d1 * 2, -d1);
409 CHECK_DIFF_FLT( d1 * 2 - (mi * mt), d1);
410
411 CHECK_DIFF_FLT( (mi * mt) + mi.t(), mi_tr + d1);
412 CHECK_DIFF_FLT( mi.t() + (mi * mt), mi_tr + d1);
413 CHECK_DIFF_FLT( (mi * mt) - mi.t(), d1 - mi_tr);
414 CHECK_DIFF_FLT( mi.t() - (mi * mt), mi_tr - d1);
415
416 CHECK_DIFF_FLT( 2.0 *(mi * mt + d2), d1 * 6);
417 CHECK_DIFF_FLT( -(mi * mt + d2), d1 * -3);
418
419 CHECK_DIFF_FLT(mt.inv() * mt, d1);
420
421 CHECK_DIFF_FLT(mt.inv() * (2*mt - mt), d1);
422 #endif
423 }
424 catch (const test_excep& e)
425 {
426 ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
427 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
428 return false;
429 }
430 return true;
431 }
432
SomeMatFunctions()433 bool CV_OperationsTest::SomeMatFunctions()
434 {
435 try
436 {
437 Mat rgba( 10, 10, CV_8UC4, Scalar(1,2,3,4) );
438 Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
439 Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
440 Mat out[] = { bgr, alpha };
441 // rgba[0] -> bgr[2], rgba[1] -> bgr[1],
442 // rgba[2] -> bgr[0], rgba[3] -> alpha[0]
443 int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
444 mixChannels( &rgba, 1, out, 2, from_to, 4 );
445
446 Mat bgr_exp( rgba.size(), CV_8UC3, Scalar(3,2,1));
447 Mat alpha_exp( rgba.size(), CV_8UC1, Scalar(4));
448
449 CHECK_DIFF(bgr_exp, bgr);
450 CHECK_DIFF(alpha_exp, alpha);
451 }
452 catch (const test_excep& e)
453 {
454 ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
455 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
456 return false;
457 }
458 return true;
459
460 }
461
462
TestSubMatAccess()463 bool CV_OperationsTest::TestSubMatAccess()
464 {
465 try
466 {
467 Mat_<float> T_bs(4,4);
468 Vec3f cdir(1.f, 1.f, 0.f);
469 Vec3f ydir(1.f, 0.f, 1.f);
470 Vec3f fpt(0.1f, 0.7f, 0.2f);
471 T_bs.setTo(0);
472 T_bs(Range(0,3),Range(2,3)) = 1.0*Mat(cdir); // weird OpenCV stuff, need to do multiply
473 T_bs(Range(0,3),Range(1,2)) = 1.0*Mat(ydir);
474 T_bs(Range(0,3),Range(0,1)) = 1.0*Mat(cdir.cross(ydir));
475 T_bs(Range(0,3),Range(3,4)) = 1.0*Mat(fpt);
476 T_bs(3,3) = 1.0;
477 //std::cout << "[Nav Grok] S frame =" << std::endl << T_bs << std::endl;
478
479 // set up display coords, really just the S frame
480 std::vector<float>coords;
481
482 for (int i=0; i<16; i++)
483 {
484 coords.push_back(T_bs(i));
485 //std::cout << T_bs1(i) << std::endl;
486 }
487 CV_Assert( cvtest::norm(coords, T_bs.reshape(1,1), NORM_INF) == 0 );
488 }
489 catch (const test_excep& e)
490 {
491 ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
492 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
493 return false;
494 }
495 return true;
496 }
497
TestTemplateMat()498 bool CV_OperationsTest::TestTemplateMat()
499 {
500 try
501 {
502 Mat_<float> one_3x1(3, 1, 1.0f);
503 Mat_<float> shi_3x1(3, 1, 1.2f);
504 Mat_<float> shi_2x1(2, 1, -2);
505 Scalar shift = Scalar::all(15);
506
507 float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
508 Mat_<float> rot_2x3(2, 3, data);
509
510 Mat_<float> res = Mat(Mat(2 * rot_2x3) * Mat(one_3x1 + shi_3x1 + shi_3x1 + shi_3x1) - shi_2x1) + shift;
511 Mat_<float> resS = rot_2x3 * one_3x1;
512
513 Mat_<float> tmp, res2, resS2;
514 cv::add(one_3x1, shi_3x1, tmp);
515 cv::add(tmp, shi_3x1, tmp);
516 cv::add(tmp, shi_3x1, tmp);
517 cv::gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
518 cv::add(res2, Mat(2, 1, CV_32F, shift), res2);
519
520 cv::gemm(rot_2x3, one_3x1, 1, shi_2x1, 0, resS2, 0);
521 CHECK_DIFF(res, res2);
522 CHECK_DIFF(resS, resS2);
523
524
525 Mat_<float> mat4x4(4, 4);
526 cv::randu(mat4x4, Scalar(0), Scalar(10));
527
528 Mat_<float> roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
529 Mat_<float> roi2 = mat4x4(Range(1, 3), Range(1, 3));
530
531 CHECK_DIFF(roi1, roi2);
532 CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
533
534 Mat_<int> intMat10(3, 3, 10);
535 Mat_<int> intMat11(3, 3, 11);
536 Mat_<uchar> resMat(3, 3, 255);
537
538 CHECK_DIFF(resMat, intMat10 == intMat10);
539 CHECK_DIFF(resMat, intMat10 < intMat11);
540 CHECK_DIFF(resMat, intMat11 > intMat10);
541 CHECK_DIFF(resMat, intMat10 <= intMat11);
542 CHECK_DIFF(resMat, intMat11 >= intMat10);
543
544 CHECK_DIFF(resMat, intMat10 == 10.0);
545 CHECK_DIFF(resMat, intMat10 < 11.0);
546 CHECK_DIFF(resMat, intMat11 > 10.0);
547 CHECK_DIFF(resMat, intMat10 <= 11.0);
548 CHECK_DIFF(resMat, intMat11 >= 10.0);
549
550 Mat_<uchar> maskMat4(3, 3, 4);
551 Mat_<uchar> maskMat1(3, 3, 1);
552 Mat_<uchar> maskMat5(3, 3, 5);
553 Mat_<uchar> maskMat0(3, 3, (uchar)0);
554
555 CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
556 CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
557 CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
558
559 Mat_<uchar> m;
560 m = maskMat4.clone(); m&=maskMat1; CHECK_DIFF(maskMat0, m);
561 m = maskMat4.clone(); m&=Scalar(1); CHECK_DIFF(maskMat0, m);
562
563 m = maskMat4.clone(); m|=maskMat1; CHECK_DIFF(maskMat5, m);
564 m = maskMat4.clone(); m^=maskMat1; CHECK_DIFF(maskMat5, m);
565
566 CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
567 CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
568 CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
569
570 CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
571 CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
572
573 CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
574 CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
575
576 CHECK_DIFF(~maskMat1, maskMat1 ^ 0xFF);
577 CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ 0xFF);
578
579 CHECK_DIFF(maskMat1 + maskMat4, maskMat5);
580 CHECK_DIFF(maskMat1 + Scalar(4), maskMat5);
581 CHECK_DIFF(Scalar(4) + maskMat1, maskMat5);
582 CHECK_DIFF(Scalar(4) + (maskMat1 & maskMat1), maskMat5);
583
584 CHECK_DIFF(maskMat1 + 4.0, maskMat5);
585 CHECK_DIFF((maskMat1 & 0xFF) + 4.0, maskMat5);
586 CHECK_DIFF(4.0 + maskMat1, maskMat5);
587
588 m = maskMat4.clone(); m+=Scalar(1); CHECK_DIFF(m, maskMat5);
589 m = maskMat4.clone(); m+=maskMat1; CHECK_DIFF(m, maskMat5);
590 m = maskMat4.clone(); m+=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat5);
591
592 CHECK_DIFF(maskMat5 - maskMat1, maskMat4);
593 CHECK_DIFF(maskMat5 - Scalar(1), maskMat4);
594 CHECK_DIFF((maskMat5 | maskMat5) - Scalar(1), maskMat4);
595 CHECK_DIFF(maskMat5 - 1, maskMat4);
596 CHECK_DIFF((maskMat5 | maskMat5) - 1, maskMat4);
597 CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 | maskMat1), maskMat4);
598
599 CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
600 CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
601
602 m = maskMat5.clone(); m-=Scalar(1); CHECK_DIFF(m, maskMat4);
603 m = maskMat5.clone(); m-=maskMat1; CHECK_DIFF(m, maskMat4);
604 m = maskMat5.clone(); m-=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat4);
605
606 m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
607 m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
608
609 CHECK_DIFF(maskMat1, maskMat4/4.0);
610
611 Mat_<float> negf(3, 3, -3.0);
612 Mat_<float> posf = -negf;
613 Mat_<float> posf2 = posf * 2;
614 Mat_<int> negi(3, 3, -3);
615
616 CHECK_DIFF(abs(negf), -negf);
617 CHECK_DIFF(abs(posf - posf2), -negf);
618 CHECK_DIFF(abs(negi), -(negi & negi));
619
620 CHECK_DIFF(5.0 - maskMat4, maskMat1);
621
622
623 CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
624 CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
625 CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
626
627
628 ////// Element-wise division
629
630 CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
631 CHECK_DIFF(4.0 / maskMat4, maskMat1);
632 m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
633
634 ////////////////////////////////
635
636 typedef Mat_<int> TestMat_t;
637
638 const TestMat_t cnegi = negi.clone();
639
640 TestMat_t::iterator beg = negi.begin();
641 TestMat_t::iterator end = negi.end();
642
643 TestMat_t::const_iterator cbeg = cnegi.begin();
644 TestMat_t::const_iterator cend = cnegi.end();
645
646 int sum = 0;
647 for(; beg!=end; ++beg)
648 sum+=*beg;
649
650 for(; cbeg!=cend; ++cbeg)
651 sum-=*cbeg;
652
653 if (sum != 0) throw test_excep();
654
655 CHECK_DIFF(negi.col(1), negi.col(2));
656 CHECK_DIFF(negi.row(1), negi.row(2));
657 CHECK_DIFF(negi.col(1), negi.diag());
658
659 if (Mat_<Point2f>(1, 1).elemSize1() != sizeof(float)) throw test_excep();
660 if (Mat_<Point2f>(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
661 if (Mat_<Point2f>(1, 1).depth() != CV_32F) throw test_excep();
662 if (Mat_<float>(1, 1).depth() != CV_32F) throw test_excep();
663 if (Mat_<int>(1, 1).depth() != CV_32S) throw test_excep();
664 if (Mat_<double>(1, 1).depth() != CV_64F) throw test_excep();
665 if (Mat_<Point3d>(1, 1).depth() != CV_64F) throw test_excep();
666 if (Mat_<signed char>(1, 1).depth() != CV_8S) throw test_excep();
667 if (Mat_<unsigned short>(1, 1).depth() != CV_16U) throw test_excep();
668 if (Mat_<unsigned short>(1, 1).channels() != 1) throw test_excep();
669 if (Mat_<Point2f>(1, 1).channels() != 2) throw test_excep();
670 if (Mat_<Point3f>(1, 1).channels() != 3) throw test_excep();
671 if (Mat_<Point3d>(1, 1).channels() != 3) throw test_excep();
672
673 Mat_<uchar> eye = Mat_<uchar>::zeros(2, 2); CHECK_DIFF(Mat_<uchar>::zeros(Size(2, 2)), eye);
674 eye.at<uchar>(Point(0,0)) = 1; eye.at<uchar>(1, 1) = 1;
675
676 CHECK_DIFF(Mat_<uchar>::eye(2, 2), eye);
677 CHECK_DIFF(eye, Mat_<uchar>::eye(Size(2,2)));
678
679 Mat_<uchar> ones(2, 2, (uchar)1);
680 CHECK_DIFF(ones, Mat_<uchar>::ones(Size(2,2)));
681 CHECK_DIFF(Mat_<uchar>::ones(2, 2), ones);
682
683 Mat_<Point2f> pntMat(2, 2, Point2f(1, 0));
684 if(pntMat.stepT() != 2) throw test_excep();
685
686 uchar uchar_data[] = {1, 0, 0, 1};
687
688 Mat_<uchar> matFromData(1, 4, uchar_data);
689 const Mat_<uchar> mat2 = matFromData.clone();
690 CHECK_DIFF(matFromData, eye.reshape(1, 1));
691 if (matFromData(Point(0,0)) != uchar_data[0])throw test_excep();
692 if (mat2(Point(0,0)) != uchar_data[0]) throw test_excep();
693
694 if (matFromData(0,0) != uchar_data[0])throw test_excep();
695 if (mat2(0,0) != uchar_data[0]) throw test_excep();
696
697 Mat_<uchar> rect(eye, Rect(0, 0, 1, 1));
698 if (rect.cols != 1 || rect.rows != 1 || rect(0,0) != uchar_data[0]) throw test_excep();
699
700 //cv::Mat_<_Tp>::adjustROI(int,int,int,int)
701 //cv::Mat_<_Tp>::cross(const Mat_&) const
702 //cv::Mat_<_Tp>::Mat_(const vector<_Tp>&,bool)
703 //cv::Mat_<_Tp>::Mat_(int,int,_Tp*,size_t)
704 //cv::Mat_<_Tp>::Mat_(int,int,const _Tp&)
705 //cv::Mat_<_Tp>::Mat_(Size,const _Tp&)
706 //cv::Mat_<_Tp>::mul(const Mat_<_Tp>&,double) const
707 //cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_DivRS_<Mat> >,Mat_<_Tp> >&,double) const
708 //cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_Scale_<Mat> >,Mat_<_Tp> >&,double) const
709 //cv::Mat_<_Tp>::operator Mat_<T2>() const
710 //cv::Mat_<_Tp>::operator MatExpr_<Mat_<_Tp>,Mat_<_Tp> >() const
711 //cv::Mat_<_Tp>::operator()(const Range&,const Range&) const
712 //cv::Mat_<_Tp>::operator()(const Rect&) const
713
714 //cv::Mat_<_Tp>::operator=(const MatExpr_Base&)
715 //cv::Mat_<_Tp>::operator[](int) const
716
717
718 ///////////////////////////////
719
720 float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
721 Mat_<float> mt(3, 3, matrix_data);
722 Mat_<float> mi = mt.inv();
723 Mat_<float> d1 = Mat_<float>::eye(3, 3);
724 Mat_<float> d2 = d1 * 2;
725 Mat_<float> mt_tr = mt.t();
726 Mat_<float> mi_tr = mi.t();
727 Mat_<float> mi2 = mi * 2;
728
729 CHECK_DIFF_FLT( mi2 * mt, d2 );
730 CHECK_DIFF_FLT( mi * mt, d1 );
731 CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
732
733 Mat_<float> mf;
734 mf = mi.clone(); mf*=mt; CHECK_DIFF_FLT(mf, d1);
735
736 ////// typedefs //////
737
738 if (Mat1b(1, 1).elemSize() != sizeof(uchar)) throw test_excep();
739 if (Mat2b(1, 1).elemSize() != 2 * sizeof(uchar)) throw test_excep();
740 if (Mat3b(1, 1).elemSize() != 3 * sizeof(uchar)) throw test_excep();
741 if (Mat1f(1, 1).elemSize() != sizeof(float)) throw test_excep();
742 if (Mat2f(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
743 if (Mat3f(1, 1).elemSize() != 3 * sizeof(float)) throw test_excep();
744 if (Mat1f(1, 1).depth() != CV_32F) throw test_excep();
745 if (Mat3f(1, 1).depth() != CV_32F) throw test_excep();
746 if (Mat3f(1, 1).type() != CV_32FC3) throw test_excep();
747 if (Mat1i(1, 1).depth() != CV_32S) throw test_excep();
748 if (Mat1d(1, 1).depth() != CV_64F) throw test_excep();
749 if (Mat1b(1, 1).depth() != CV_8U) throw test_excep();
750 if (Mat3b(1, 1).type() != CV_8UC3) throw test_excep();
751 if (Mat1w(1, 1).depth() != CV_16U) throw test_excep();
752 if (Mat1s(1, 1).depth() != CV_16S) throw test_excep();
753 if (Mat1f(1, 1).channels() != 1) throw test_excep();
754 if (Mat1b(1, 1).channels() != 1) throw test_excep();
755 if (Mat1i(1, 1).channels() != 1) throw test_excep();
756 if (Mat1w(1, 1).channels() != 1) throw test_excep();
757 if (Mat1s(1, 1).channels() != 1) throw test_excep();
758 if (Mat2f(1, 1).channels() != 2) throw test_excep();
759 if (Mat2b(1, 1).channels() != 2) throw test_excep();
760 if (Mat2i(1, 1).channels() != 2) throw test_excep();
761 if (Mat2w(1, 1).channels() != 2) throw test_excep();
762 if (Mat2s(1, 1).channels() != 2) throw test_excep();
763 if (Mat3f(1, 1).channels() != 3) throw test_excep();
764 if (Mat3b(1, 1).channels() != 3) throw test_excep();
765 if (Mat3i(1, 1).channels() != 3) throw test_excep();
766 if (Mat3w(1, 1).channels() != 3) throw test_excep();
767 if (Mat3s(1, 1).channels() != 3) throw test_excep();
768
769 vector<Mat_<float> > mvf, mvf2;
770 Mat_<Vec2f> mf2;
771 mvf.push_back(Mat_<float>::ones(4, 3));
772 mvf.push_back(Mat_<float>::zeros(4, 3));
773 merge(mvf, mf2);
774 split(mf2, mvf2);
775 CV_Assert( cvtest::norm(mvf2[0], mvf[0], CV_C) == 0 &&
776 cvtest::norm(mvf2[1], mvf[1], CV_C) == 0 );
777
778 {
779 Mat a(2,2,CV_32F,1.f);
780 Mat b(1,2,CV_32F,1.f);
781 Mat c = (a*b.t()).t();
782 CV_Assert( cvtest::norm(c, CV_L1) == 4. );
783 }
784
785 bool badarg_catched = false;
786 try
787 {
788 Mat m1 = Mat::zeros(1, 10, CV_8UC1);
789 Mat m2 = Mat::zeros(10, 10, CV_8UC3);
790 m1.copyTo(m2.row(1));
791 }
792 catch(const Exception&)
793 {
794 badarg_catched = true;
795 }
796 CV_Assert( badarg_catched );
797
798 Size size(2, 5);
799 TestType<float>(size, 1.f);
800 cv::Vec3f val1(1.f);
801 TestType<cv::Vec3f>(size, val1);
802 cv::Matx31f val2(1.f);
803 TestType<cv::Matx31f>(size, val2);
804 cv::Matx41f val3(1.f);
805 TestType<cv::Matx41f>(size, val3);
806 cv::Matx32f val4(1.f);
807 TestType<cv::Matx32f>(size, val4);
808 }
809 catch (const test_excep& e)
810 {
811 ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
812 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
813 return false;
814 }
815 return true;
816 }
817
TestMatND()818 bool CV_OperationsTest::TestMatND()
819 {
820 int sizes[] = { 3, 3, 3};
821 cv::MatND nd(3, sizes, CV_32F);
822
823 return true;
824 }
825
TestSparseMat()826 bool CV_OperationsTest::TestSparseMat()
827 {
828 try
829 {
830 int sizes[] = { 10, 10, 10};
831 int dims = sizeof(sizes)/sizeof(sizes[0]);
832 SparseMat mat(dims, sizes, CV_32FC2);
833
834 if (mat.dims() != dims) throw test_excep();
835 if (mat.channels() != 2) throw test_excep();
836 if (mat.depth() != CV_32F) throw test_excep();
837
838 SparseMat mat2 = mat.clone();
839 }
840 catch (const test_excep&)
841 {
842 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
843 return false;
844 }
845 return true;
846 }
847
848
TestMatxMultiplication()849 bool CV_OperationsTest::TestMatxMultiplication()
850 {
851 try
852 {
853 Matx33f mat(1, 1, 1, 0, 1, 1, 0, 0, 1); // Identity matrix
854 Point2f pt(3, 4);
855 Point3f res = mat * pt; // Correctly assumes homogeneous coordinates
856
857 Vec3f res2 = mat*Vec3f(res.x, res.y, res.z);
858
859 if(res.x != 8.0) throw test_excep();
860 if(res.y != 5.0) throw test_excep();
861 if(res.z != 1.0) throw test_excep();
862
863 if(res2[0] != 14.0) throw test_excep();
864 if(res2[1] != 6.0) throw test_excep();
865 if(res2[2] != 1.0) throw test_excep();
866
867 Matx44f mat44f(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
868 Matx44d mat44d(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
869 Scalar s(4, 3, 2, 1);
870 Scalar sf = mat44f*s;
871 Scalar sd = mat44d*s;
872
873 if(sf[0] != 10.0) throw test_excep();
874 if(sf[1] != 6.0) throw test_excep();
875 if(sf[2] != 3.0) throw test_excep();
876 if(sf[3] != 1.0) throw test_excep();
877
878 if(sd[0] != 10.0) throw test_excep();
879 if(sd[1] != 6.0) throw test_excep();
880 if(sd[2] != 3.0) throw test_excep();
881 if(sd[3] != 1.0) throw test_excep();
882 }
883 catch(const test_excep&)
884 {
885 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
886 return false;
887 }
888 return true;
889 }
890
TestMatMatxCastSum()891 bool CV_OperationsTest::TestMatMatxCastSum()
892 {
893 try
894 {
895 Mat ref1 = (Mat_<double>(3, 1) << 1, 2, 3);
896 Mat ref2 = (Mat_<double>(3, 1) << 3, 4, 5);
897 Mat ref3 = Mat::ones(3, 1, CV_64FC1);
898
899 Mat mat = Mat::zeros(3, 1, CV_64FC1);
900
901 Mat tst1 = ref1.clone();
902 Mat_<double> tst2 = ref2.clone();
903 Matx<double, 3, 1> tst3(1, 2, 3);
904 Vec3d tst4(3, 4, 5);
905 Scalar tst5(1, 2, 3);
906 Mat res;
907
908 res = mat + tst1;
909 CHECK_DIFF_FLT(res, ref1);
910 res = mat + tst2;
911 CHECK_DIFF_FLT(res, ref2);
912 res = mat + tst3;
913 CHECK_DIFF_FLT(res, ref1);
914 res = mat + tst4;
915 CHECK_DIFF_FLT(res, ref2);
916
917 res = mat + tst5;
918 CHECK_DIFF_FLT(res, ref3);
919 res = mat + 1;
920 CHECK_DIFF_FLT(res, ref3);
921
922 cv::add(mat, tst1, res);
923 CHECK_DIFF_FLT(res, ref1);
924 cv::add(mat, tst2, res);
925 CHECK_DIFF_FLT(res, ref2);
926 cv::add(mat, tst3, res);
927 CHECK_DIFF_FLT(res, ref1);
928 cv::add(mat, tst4, res);
929 CHECK_DIFF_FLT(res, ref2);
930
931 cv::add(mat, tst5, res);
932 CHECK_DIFF_FLT(res, ref3);
933 cv::add(mat, 1, res);
934 CHECK_DIFF_FLT(res, ref3);
935
936 res = mat.clone(); res += tst1;
937 CHECK_DIFF_FLT(res, ref1);
938 res = mat.clone(); res += tst2;
939 CHECK_DIFF_FLT(res, ref2);
940 res = mat.clone(); res += tst3;
941 CHECK_DIFF_FLT(res, ref1);
942 res = mat.clone(); res += tst4;
943 CHECK_DIFF_FLT(res, ref2);
944
945 res = mat.clone(); res += tst5;
946 CHECK_DIFF_FLT(res, ref3);
947 res = mat.clone(); res += 1;
948 CHECK_DIFF_FLT(res, ref3);
949 }
950 catch (const test_excep& e)
951 {
952 ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
953 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
954 return false;
955 }
956 return true;
957 }
958
TestMatxElementwiseDivison()959 bool CV_OperationsTest::TestMatxElementwiseDivison()
960 {
961 try
962 {
963 Matx22f mat(2, 4, 6, 8);
964 Matx22f mat2(2, 2, 2, 2);
965
966 Matx22f res = mat.div(mat2);
967
968 if(res(0, 0) != 1.0) throw test_excep();
969 if(res(0, 1) != 2.0) throw test_excep();
970 if(res(1, 0) != 3.0) throw test_excep();
971 if(res(1, 1) != 4.0) throw test_excep();
972 }
973 catch(const test_excep&)
974 {
975 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
976 return false;
977 }
978 return true;
979 }
980
TestDivisionByValue()981 bool CV_OperationsTest::TestDivisionByValue()
982 {
983 try
984 {
985 Matx22f mat(2, 4, 6, 8);
986 float alpha = 2.f;
987
988 Matx22f res = mat / alpha;
989
990 if(res(0, 0) != 1.0) throw test_excep();
991 if(res(0, 1) != 2.0) throw test_excep();
992 if(res(1, 0) != 3.0) throw test_excep();
993 if(res(1, 1) != 4.0) throw test_excep();
994 }
995 catch(const test_excep&)
996 {
997 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
998 return false;
999 }
1000 return true;
1001 }
1002
1003
TestInplaceDivisionByValue()1004 bool CV_OperationsTest::TestInplaceDivisionByValue()
1005 {
1006 try
1007 {
1008 Matx22f mat(2, 4, 6, 8);
1009 float alpha = 2.f;
1010
1011 mat /= alpha;
1012
1013 if(mat(0, 0) != 1.0) throw test_excep();
1014 if(mat(0, 1) != 2.0) throw test_excep();
1015 if(mat(1, 0) != 3.0) throw test_excep();
1016 if(mat(1, 1) != 4.0) throw test_excep();
1017 }
1018 catch(const test_excep&)
1019 {
1020 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
1021 return false;
1022 }
1023 return true;
1024 }
1025
TestVec()1026 bool CV_OperationsTest::TestVec()
1027 {
1028 try
1029 {
1030 cv::Mat hsvImage_f(5, 5, CV_32FC3), hsvImage_b(5, 5, CV_8UC3);
1031 int i = 0,j = 0;
1032 cv::Vec3f a;
1033
1034 //these compile
1035 cv::Vec3b b = a;
1036 hsvImage_f.at<cv::Vec3f>(i,j) = cv::Vec3f((float)i,0,1);
1037 hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3b(cv::Vec3f((float)i,0,1));
1038
1039 //these don't
1040 b = cv::Vec3f(1,0,0);
1041 cv::Vec3b c;
1042 c = cv::Vec3f(0,0,1);
1043 hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3f((float)i,0,1);
1044 hsvImage_b.at<cv::Vec3b>(i,j) = a;
1045 hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3f(1,2,3);
1046 }
1047 catch(const test_excep&)
1048 {
1049 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
1050 return false;
1051 }
1052 return true;
1053 }
1054
operations1()1055 bool CV_OperationsTest::operations1()
1056 {
1057 try
1058 {
1059 Point3d p1(1, 1, 1), p2(2, 2, 2), p4(4, 4, 4);
1060 p1*=2;
1061 if (!(p1 == p2)) throw test_excep();
1062 if (!(p2 * 2 == p4)) throw test_excep();
1063 if (!(p2 * 2.f == p4)) throw test_excep();
1064 if (!(p2 * 2.f == p4)) throw test_excep();
1065
1066 Point2d pi1(1, 1), pi2(2, 2), pi4(4, 4);
1067 pi1*=2;
1068 if (!(pi1 == pi2)) throw test_excep();
1069 if (!(pi2 * 2 == pi4)) throw test_excep();
1070 if (!(pi2 * 2.f == pi4)) throw test_excep();
1071 if (!(pi2 * 2.f == pi4)) throw test_excep();
1072
1073 Vec2d v12(1, 1), v22(2, 2);
1074 v12*=2.0;
1075 if (!(v12 == v22)) throw test_excep();
1076
1077 Vec3d v13(1, 1, 1), v23(2, 2, 2);
1078 v13*=2.0;
1079 if (!(v13 == v23)) throw test_excep();
1080
1081 Vec4d v14(1, 1, 1, 1), v24(2, 2, 2, 2);
1082 v14*=2.0;
1083 if (!(v14 == v24)) throw test_excep();
1084
1085 Size sz(10, 20);
1086 if (sz.area() != 200) throw test_excep();
1087 if (sz.width != 10 || sz.height != 20) throw test_excep();
1088 if (cvSize(sz).width != 10 || cvSize(sz).height != 20) throw test_excep();
1089
1090 Rect r1(0, 0, 10, 20);
1091 Size sz1(5, 10);
1092 r1 -= sz1;
1093 if (r1.size().width != 5 || r1.size().height != 10) throw test_excep();
1094 Rect r2 = r1 - sz1;
1095 if (r2.size().width != 0 || r2.size().height != 0) throw test_excep();
1096
1097 Vec<double, 5> v5d(1, 1, 1, 1, 1);
1098 Vec<double, 6> v6d(1, 1, 1, 1, 1, 1);
1099 Vec<double, 7> v7d(1, 1, 1, 1, 1, 1, 1);
1100 Vec<double, 8> v8d(1, 1, 1, 1, 1, 1, 1, 1);
1101 Vec<double, 9> v9d(1, 1, 1, 1, 1, 1, 1, 1, 1);
1102 Vec<double,10> v10d(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
1103
1104 Vec<double,10> v10dzero;
1105 for (int ii = 0; ii < 10; ++ii) {
1106 if (v10dzero[ii] != 0.0)
1107 throw test_excep();
1108 }
1109
1110 Mat A(1, 32, CV_32F), B;
1111 for( int i = 0; i < A.cols; i++ )
1112 A.at<float>(i) = (float)(i <= 12 ? i : 24 - i);
1113 cv::transpose(A, B);
1114
1115 int minidx[2] = {0, 0}, maxidx[2] = {0, 0};
1116 double minval = 0, maxval = 0;
1117 cv::minMaxIdx(A, &minval, &maxval, minidx, maxidx);
1118
1119 if( !(minidx[0] == 0 && minidx[1] == 31 && maxidx[0] == 0 && maxidx[1] == 12 &&
1120 minval == -7 && maxval == 12))
1121 throw test_excep();
1122
1123 cv::minMaxIdx(B, &minval, &maxval, minidx, maxidx);
1124
1125 if( !(minidx[0] == 31 && minidx[1] == 0 && maxidx[0] == 12 && maxidx[1] == 0 &&
1126 minval == -7 && maxval == 12))
1127 throw test_excep();
1128
1129 Matx33f b(1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f);
1130 Mat c;
1131 cv::add(Mat::zeros(3, 3, CV_32F), b, c);
1132 CV_Assert( cvtest::norm(b, c, CV_C) == 0 );
1133
1134 cv::add(Mat::zeros(3, 3, CV_64F), b, c, noArray(), c.type());
1135 CV_Assert( cvtest::norm(b, c, CV_C) == 0 );
1136
1137 cv::add(Mat::zeros(6, 1, CV_64F), 1, c, noArray(), c.type());
1138 CV_Assert( cvtest::norm(Matx61f(1.f, 1.f, 1.f, 1.f, 1.f, 1.f), c, CV_C) == 0 );
1139
1140 vector<Point2f> pt2d(3);
1141 vector<Point3d> pt3d(2);
1142
1143 CV_Assert( Mat(pt2d).checkVector(2) == 3 && Mat(pt2d).checkVector(3) < 0 &&
1144 Mat(pt3d).checkVector(2) < 0 && Mat(pt3d).checkVector(3) == 2 );
1145
1146 Matx44f m44(0.8147f, 0.6324f, 0.9575f, 0.9572f,
1147 0.9058f, 0.0975f, 0.9649f, 0.4854f,
1148 0.1270f, 0.2785f, 0.1576f, 0.8003f,
1149 0.9134f, 0.5469f, 0.9706f, 0.1419f);
1150 double d = cv::determinant(m44);
1151 CV_Assert( fabs(d - (-0.0262)) <= 0.001 );
1152
1153 Cv32suf z;
1154 z.i = 0x80000000;
1155 CV_Assert( cvFloor(z.f) == 0 && cvCeil(z.f) == 0 && cvRound(z.f) == 0 );
1156 }
1157 catch(const test_excep&)
1158 {
1159 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1160 return false;
1161 }
1162 return true;
1163 }
1164
1165
TestExp()1166 bool CV_OperationsTest::TestExp()
1167 {
1168 Mat1f tt = Mat1f::ones(4,2);
1169 Mat1f outs;
1170 exp(-tt, outs);
1171 Mat1f tt2 = Mat1f::ones(4,1), outs2;
1172 exp(-tt2, outs2);
1173 return true;
1174 }
1175
1176
TestSVD()1177 bool CV_OperationsTest::TestSVD()
1178 {
1179 try
1180 {
1181 Mat A = (Mat_<double>(3,4) << 1, 2, -1, 4, 2, 4, 3, 5, -1, -2, 6, 7);
1182 Mat x;
1183 SVD::solveZ(A,x);
1184 if( cvtest::norm(A*x, CV_C) > FLT_EPSILON )
1185 throw test_excep();
1186
1187 SVD svd(A, SVD::FULL_UV);
1188 if( cvtest::norm(A*svd.vt.row(3).t(), CV_C) > FLT_EPSILON )
1189 throw test_excep();
1190
1191 Mat Dp(3,3,CV_32FC1);
1192 Mat Dc(3,3,CV_32FC1);
1193 Mat Q(3,3,CV_32FC1);
1194 Mat U,Vt,R,T,W;
1195
1196 Dp.at<float>(0,0)=0.86483884f; Dp.at<float>(0,1)= -0.3077251f; Dp.at<float>(0,2)=-0.55711365f;
1197 Dp.at<float>(1,0)=0.49294353f; Dp.at<float>(1,1)=-0.24209651f; Dp.at<float>(1,2)=-0.25084701f;
1198 Dp.at<float>(2,0)=0; Dp.at<float>(2,1)=0; Dp.at<float>(2,2)=0;
1199
1200 Dc.at<float>(0,0)=0.75632739f; Dc.at<float>(0,1)= -0.38859656f; Dc.at<float>(0,2)=-0.36773083f;
1201 Dc.at<float>(1,0)=0.9699229f; Dc.at<float>(1,1)=-0.49858192f; Dc.at<float>(1,2)=-0.47134098f;
1202 Dc.at<float>(2,0)=0.10566688f; Dc.at<float>(2,1)=-0.060333252f; Dc.at<float>(2,2)=-0.045333147f;
1203
1204 Q=Dp*Dc.t();
1205 SVD decomp;
1206 decomp=SVD(Q);
1207 U=decomp.u;
1208 Vt=decomp.vt;
1209 W=decomp.w;
1210 Mat I = Mat::eye(3, 3, CV_32F);
1211
1212 if( cvtest::norm(U*U.t(), I, CV_C) > FLT_EPSILON ||
1213 cvtest::norm(Vt*Vt.t(), I, CV_C) > FLT_EPSILON ||
1214 W.at<float>(2) < 0 || W.at<float>(1) < W.at<float>(2) ||
1215 W.at<float>(0) < W.at<float>(1) ||
1216 cvtest::norm(U*Mat::diag(W)*Vt, Q, CV_C) > FLT_EPSILON )
1217 throw test_excep();
1218 }
1219 catch(const test_excep&)
1220 {
1221 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1222 return false;
1223 }
1224 return true;
1225 }
1226
run(int)1227 void CV_OperationsTest::run( int /* start_from */)
1228 {
1229 if (!TestMat())
1230 return;
1231
1232 if (!SomeMatFunctions())
1233 return;
1234
1235 if (!TestTemplateMat())
1236 return;
1237
1238 if (!TestMatND())
1239 return;
1240
1241 if (!TestSparseMat())
1242 return;
1243
1244 if (!TestVec())
1245 return;
1246
1247 if (!TestMatxMultiplication())
1248 return;
1249
1250 if (!TestMatxElementwiseDivison())
1251 return;
1252
1253 if (!TestDivisionByValue())
1254 return;
1255
1256 if (!TestInplaceDivisionByValue())
1257 return;
1258
1259 if (!TestMatMatxCastSum())
1260 return;
1261
1262 if (!TestSubMatAccess())
1263 return;
1264
1265 if (!TestExp())
1266 return;
1267
1268 if (!TestSVD())
1269 return;
1270
1271 if (!operations1())
1272 return;
1273
1274 ts->set_failed_test_info(cvtest::TS::OK);
1275 }
1276
TEST(Core_Array,expressions)1277 TEST(Core_Array, expressions) { CV_OperationsTest test; test.safe_run(); }
1278
1279 class CV_SparseMatTest : public cvtest::BaseTest
1280 {
1281 public:
CV_SparseMatTest()1282 CV_SparseMatTest() {}
~CV_SparseMatTest()1283 ~CV_SparseMatTest() {}
1284 protected:
run(int)1285 void run(int)
1286 {
1287 try
1288 {
1289 RNG& rng = theRNG();
1290 const int MAX_DIM=3;
1291 int sizes[MAX_DIM], idx[MAX_DIM];
1292 for( int iter = 0; iter < 100; iter++ )
1293 {
1294 ts->printf(cvtest::TS::LOG, ".");
1295 ts->update_context(this, iter, true);
1296 int k, dims = rng.uniform(1, MAX_DIM+1), p = 1;
1297 for( k = 0; k < dims; k++ )
1298 {
1299 sizes[k] = rng.uniform(1, 30);
1300 p *= sizes[k];
1301 }
1302 int j, nz = rng.uniform(0, (p+2)/2), nz0 = 0;
1303 SparseMat_<int> v(dims,sizes);
1304
1305 CV_Assert( (int)v.nzcount() == 0 );
1306
1307 SparseMatIterator_<int> it = v.begin();
1308 SparseMatIterator_<int> it_end = v.end();
1309
1310 for( k = 0; it != it_end; ++it, ++k )
1311 ;
1312 CV_Assert( k == 0 );
1313
1314 int sum0 = 0, sum = 0;
1315 for( j = 0; j < nz; j++ )
1316 {
1317 int val = rng.uniform(1, 100);
1318 for( k = 0; k < dims; k++ )
1319 idx[k] = rng.uniform(0, sizes[k]);
1320 if( dims == 1 )
1321 {
1322 CV_Assert( v.ref(idx[0]) == v(idx[0]) );
1323 }
1324 else if( dims == 2 )
1325 {
1326 CV_Assert( v.ref(idx[0], idx[1]) == v(idx[0], idx[1]) );
1327 }
1328 else if( dims == 3 )
1329 {
1330 CV_Assert( v.ref(idx[0], idx[1], idx[2]) == v(idx[0], idx[1], idx[2]) );
1331 }
1332 CV_Assert( v.ref(idx) == v(idx) );
1333 v.ref(idx) += val;
1334 if( v(idx) == val )
1335 nz0++;
1336 sum0 += val;
1337 }
1338
1339 CV_Assert( (int)v.nzcount() == nz0 );
1340
1341 it = v.begin();
1342 it_end = v.end();
1343
1344 for( k = 0; it != it_end; ++it, ++k )
1345 sum += *it;
1346 CV_Assert( k == nz0 && sum == sum0 );
1347
1348 v.clear();
1349 CV_Assert( (int)v.nzcount() == 0 );
1350
1351 it = v.begin();
1352 it_end = v.end();
1353
1354 for( k = 0; it != it_end; ++it, ++k )
1355 ;
1356 CV_Assert( k == 0 );
1357 }
1358 }
1359 catch(...)
1360 {
1361 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1362 }
1363 }
1364 };
1365
TEST(Core_SparseMat,iterations)1366 TEST(Core_SparseMat, iterations) { CV_SparseMatTest test; test.safe_run(); }
1367
TEST(MatTestRoi,adjustRoiOverflow)1368 TEST(MatTestRoi, adjustRoiOverflow)
1369 {
1370 Mat m(15, 10, CV_32S);
1371 Mat roi(m, cv::Range(2, 10), cv::Range(3,6));
1372 int rowsInROI = roi.rows;
1373 roi.adjustROI(1, 0, 0, 0);
1374
1375 ASSERT_EQ(roi.rows, rowsInROI + 1);
1376
1377 roi.adjustROI(-m.rows, -m.rows, 0, 0);
1378
1379 ASSERT_EQ(roi.rows, m.rows);
1380 }
1381
1382
CV_ENUM(SortRowCol,SORT_EVERY_COLUMN,SORT_EVERY_ROW)1383 CV_ENUM(SortRowCol, SORT_EVERY_COLUMN, SORT_EVERY_ROW)
1384 CV_ENUM(SortOrder, SORT_ASCENDING, SORT_DESCENDING)
1385
1386 PARAM_TEST_CASE(sortIdx, MatDepth, SortRowCol, SortOrder, Size, bool)
1387 {
1388 int type;
1389 Size size;
1390 int flags;
1391 bool use_roi;
1392
1393 Mat src, src_roi;
1394 Mat dst, dst_roi;
1395
1396 virtual void SetUp()
1397 {
1398 int depth = GET_PARAM(0);
1399 int rowFlags = GET_PARAM(1);
1400 int orderFlags = GET_PARAM(2);
1401 size = GET_PARAM(3);
1402 use_roi = GET_PARAM(4);
1403
1404 type = CV_MAKE_TYPE(depth, 1);
1405
1406 flags = rowFlags | orderFlags;
1407 }
1408
1409 void generateTestData()
1410 {
1411 Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
1412 randomSubMat(src, src_roi, size, srcBorder, type, -100, 100);
1413
1414 Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
1415 randomSubMat(dst, dst_roi, size, dstBorder, CV_32S, 5, 16);
1416 }
1417
1418 template<typename T>
1419 void check_(const cv::Mat& values_, const cv::Mat_<int>& idx_)
1420 {
1421 cv::Mat_<T>& values = (cv::Mat_<T>&)values_;
1422 cv::Mat_<int>& idx = (cv::Mat_<int>&)idx_;
1423 size_t N = values.total();
1424 std::vector<bool> processed(N, false);
1425 int prevIdx = idx(0);
1426 T prevValue = values(prevIdx);
1427 processed[prevIdx] = true;
1428 for (size_t i = 1; i < N; i++)
1429 {
1430 int nextIdx = idx((int)i);
1431 T value = values(nextIdx);
1432 ASSERT_EQ(false, processed[nextIdx]) << "Indexes must be unique. i=" << i << " idx=" << nextIdx << std::endl << idx;
1433 processed[nextIdx] = true;
1434 if ((flags & SORT_DESCENDING) == SORT_DESCENDING)
1435 ASSERT_GE(prevValue, value) << "i=" << i << " prevIdx=" << prevIdx << " idx=" << nextIdx;
1436 else
1437 ASSERT_LE(prevValue, value) << "i=" << i << " prevIdx=" << prevIdx << " idx=" << nextIdx;
1438 prevValue = value;
1439 prevIdx = nextIdx;
1440 }
1441 }
1442
1443 void validate()
1444 {
1445 ASSERT_EQ(CV_32SC1, dst_roi.type());
1446 ASSERT_EQ(size, dst_roi.size());
1447 bool isColumn = (flags & SORT_EVERY_COLUMN) == SORT_EVERY_COLUMN;
1448 size_t N = isColumn ? src_roi.cols : src_roi.rows;
1449 Mat values_row((int)N, 1, type), idx_row((int)N, 1, CV_32S);
1450 for (size_t i = 0; i < N; i++)
1451 {
1452 SCOPED_TRACE(cv::format("row/col=%d", (int)i));
1453 if (isColumn)
1454 {
1455 src_roi.col((int)i).copyTo(values_row);
1456 dst_roi.col((int)i).copyTo(idx_row);
1457 }
1458 else
1459 {
1460 src_roi.row((int)i).copyTo(values_row);
1461 dst_roi.row((int)i).copyTo(idx_row);
1462 }
1463 switch(type)
1464 {
1465 case CV_8U: check_<uchar>(values_row, idx_row); break;
1466 case CV_8S: check_<char>(values_row, idx_row); break;
1467 case CV_16S: check_<short>(values_row, idx_row); break;
1468 case CV_32S: check_<int>(values_row, idx_row); break;
1469 case CV_32F: check_<float>(values_row, idx_row); break;
1470 case CV_64F: check_<double>(values_row, idx_row); break;
1471 default: ASSERT_FALSE(true) << "Unsupported type: " << type;
1472 }
1473 }
1474 }
1475 };
1476
TEST_P(sortIdx,simple)1477 TEST_P(sortIdx, simple)
1478 {
1479 for (int j = 0; j < 5; j++)
1480 {
1481 generateTestData();
1482
1483 cv::sortIdx(src_roi, dst_roi, flags);
1484 validate();
1485 }
1486 }
1487
1488 INSTANTIATE_TEST_CASE_P(Core, sortIdx, Combine(
1489 Values(CV_8U, CV_8S, CV_16S, CV_32S, CV_32F, CV_64F), // depth
1490 Values(SORT_EVERY_COLUMN, SORT_EVERY_ROW),
1491 Values(SORT_ASCENDING, SORT_DESCENDING),
1492 Values(Size(3, 3), Size(16, 8)),
1493 ::testing::Bool()
1494 ));
1495
1496
TEST(Core_sortIdx,regression_8941)1497 TEST(Core_sortIdx, regression_8941)
1498 {
1499 cv::Mat src = (cv::Mat_<int>(3, 3) <<
1500 1, 2, 3,
1501 0, 9, 5,
1502 8, 1, 6
1503 );
1504 cv::Mat expected = (cv::Mat_<int>(3, 1) <<
1505 1,
1506 0,
1507 2
1508 );
1509
1510 cv::Mat result;
1511 cv::sortIdx(src.col(0), result, CV_SORT_EVERY_COLUMN | CV_SORT_ASCENDING);
1512 #if 0
1513 std::cout << src.col(0) << std::endl;
1514 std::cout << result << std::endl;
1515 #endif
1516 ASSERT_EQ(expected.size(), result.size());
1517 EXPECT_EQ(0, cvtest::norm(expected, result, NORM_INF)) <<
1518 "result=" << std::endl << result << std::endl <<
1519 "expected=" << std::endl << expected;
1520 }
1521
TEST(Core_Mat,augmentation_operations_9688)1522 TEST(Core_Mat, augmentation_operations_9688)
1523 {
1524 {
1525 Mat x(1, 1, CV_64FC1, 1.0f);
1526 Mat p(1, 4, CV_64FC1, 5.0f);
1527 EXPECT_ANY_THROW(
1528 x += p;
1529 ) << x;
1530 }
1531 {
1532 Mat x(1, 1, CV_64FC1, 1.0f);
1533 Mat p(1, 4, CV_64FC1, 5.0f);
1534 EXPECT_ANY_THROW(
1535 x -= p;
1536 ) << x;
1537 }
1538 }
1539
1540 //These tests guard regressions against running MatExpr
1541 //operations on empty operands and giving bogus
1542 //results.
TEST(Core_MatExpr,empty_check_15760)1543 TEST(Core_MatExpr, empty_check_15760)
1544 {
1545 EXPECT_THROW(Mat c = min(Mat(), Mat()), cv::Exception);
1546 EXPECT_THROW(Mat c = abs(Mat()), cv::Exception);
1547 EXPECT_THROW(Mat c = min(Mat(), Mat()), cv::Exception);
1548 EXPECT_THROW(Mat c = Mat() | Mat(), cv::Exception);
1549 EXPECT_THROW(Mat c = Mat() + Mat(), cv::Exception);
1550 EXPECT_THROW(Mat c = Mat().t(), cv::Exception);
1551 EXPECT_THROW(Mat c = Mat().cross(Mat()), cv::Exception);
1552 }
1553
TEST(Core_Arithm,scalar_handling_19599)1554 TEST(Core_Arithm, scalar_handling_19599) // https://github.com/opencv/opencv/issues/19599 (OpenCV 4.x+ only)
1555 {
1556 Mat a(1, 1, CV_32F, Scalar::all(1));
1557 Mat b(4, 1, CV_64F, Scalar::all(1)); // MatExpr may convert Scalar to Mat
1558 Mat c;
1559 EXPECT_NO_THROW(cv::multiply(a, b, c));
1560 EXPECT_EQ(1, c.cols);
1561 EXPECT_EQ(1, c.rows);
1562 }
1563
1564 }} // namespace
1565