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