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 
45 #include <string>
46 #include <iostream>
47 #include <fstream>
48 #include <iterator>
49 #include <limits>
50 #include <numeric>
51 
52 using namespace cv;
53 using namespace std;
54 
55 
56 class CV_OperationsTest : public cvtest::BaseTest
57 {
58 public:
59     CV_OperationsTest();
60     ~CV_OperationsTest();
61 protected:
62     void run(int);
63 
64     struct test_excep
65     {
test_excepCV_OperationsTest::test_excep66         test_excep(const string& _s=string("")) : s(_s) { }
67         string s;
68     };
69 
70     bool SomeMatFunctions();
71     bool TestMat();
72     template<typename _Tp> void TestType(Size sz, _Tp value);
73     bool TestTemplateMat();
74     bool TestMatND();
75     bool TestSparseMat();
76     bool TestVec();
77     bool TestMatxMultiplication();
78     bool TestMatxElementwiseDivison();
79     bool TestSubMatAccess();
80     bool TestExp();
81     bool TestSVD();
82     bool operations1();
83 
checkDiff(const Mat & m1,const Mat & m2,const string & s)84     void checkDiff(const Mat& m1, const Mat& m2, const string& s)
85     {
86         if (cvtest::norm(m1, m2, NORM_INF) != 0) throw test_excep(s);
87     }
checkDiffF(const Mat & m1,const Mat & m2,const string & s)88     void checkDiffF(const Mat& m1, const Mat& m2, const string& s)
89     {
90         if (cvtest::norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s);
91     }
92 };
93 
CV_OperationsTest()94 CV_OperationsTest::CV_OperationsTest()
95 {
96 }
97 
~CV_OperationsTest()98 CV_OperationsTest::~CV_OperationsTest() {}
99 
100 #define STR(a) STR2(a)
101 #define STR2(a) #a
102 
103 #define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ")  !=  (" #b ")  at l." STR(__LINE__))
104 #define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ")  !=(eps)  (" #b ")  at l." STR(__LINE__))
105 
106 #if defined _MSC_VER && _MSC_VER < 1400
107 #define MSVC_OLD 1
108 #else
109 #define MSVC_OLD 0
110 #endif
111 
TestType(Size sz,_Tp value)112 template<typename _Tp> void CV_OperationsTest::TestType(Size sz, _Tp value)
113 {
114     cv::Mat_<_Tp> m(sz);
115     CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == DataType<_Tp>::depth &&
116               m.channels() == DataType<_Tp>::channels &&
117               m.elemSize() == sizeof(_Tp) && m.step == m.elemSize()*m.cols);
118     for( int y = 0; y < sz.height; y++ )
119         for( int x = 0; x < sz.width; x++ )
120         {
121             m(y,x) = value;
122         }
123 
124     double s = sum(Mat(m).reshape(1))[0];
125     CV_Assert( s == (double)sz.width*sz.height );
126 }
127 
TestMat()128 bool CV_OperationsTest::TestMat()
129 {
130     try
131     {
132         Mat one_3x1(3, 1, CV_32F, Scalar(1.0));
133         Mat shi_3x1(3, 1, CV_32F, Scalar(1.2));
134         Mat shi_2x1(2, 1, CV_32F, Scalar(-1));
135         Scalar shift = Scalar::all(15);
136 
137         float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
138         Mat rot_2x3(2, 3, CV_32F, data);
139 
140         Mat res = one_3x1 + shi_3x1 + shi_3x1 + shi_3x1;
141         res = Mat(Mat(2 * rot_2x3) * res - shi_2x1) + shift;
142 
143         Mat tmp, res2;
144         add(one_3x1, shi_3x1, tmp);
145         add(tmp, shi_3x1, tmp);
146         add(tmp, shi_3x1, tmp);
147         gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
148         add(res2, Mat(2, 1, CV_32F, shift), res2);
149 
150         CHECK_DIFF(res, res2);
151 
152         Mat mat4x4(4, 4, CV_32F);
153         randu(mat4x4, Scalar(0), Scalar(10));
154 
155         Mat roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
156         Mat roi2 = mat4x4(Range(1, 3), Range(1, 3));
157 
158         CHECK_DIFF(roi1, roi2);
159         CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
160 
161         Mat intMat10(3, 3, CV_32S, Scalar(10));
162         Mat intMat11(3, 3, CV_32S, Scalar(11));
163         Mat resMat(3, 3, CV_8U, Scalar(255));
164 
165         CHECK_DIFF(resMat, intMat10 == intMat10);
166         CHECK_DIFF(resMat, intMat10 <  intMat11);
167         CHECK_DIFF(resMat, intMat11 >  intMat10);
168         CHECK_DIFF(resMat, intMat10 <= intMat11);
169         CHECK_DIFF(resMat, intMat11 >= intMat10);
170         CHECK_DIFF(resMat, intMat11 != intMat10);
171 
172         CHECK_DIFF(resMat, intMat10 == 10.0);
173         CHECK_DIFF(resMat, 10.0 == intMat10);
174         CHECK_DIFF(resMat, intMat10 <  11.0);
175         CHECK_DIFF(resMat, 11.0 > intMat10);
176         CHECK_DIFF(resMat, 10.0 < intMat11);
177         CHECK_DIFF(resMat, 11.0 >= intMat10);
178         CHECK_DIFF(resMat, 10.0 <= intMat11);
179         CHECK_DIFF(resMat, 10.0 != intMat11);
180         CHECK_DIFF(resMat, intMat11 != 10.0);
181 
182         Mat eye =  Mat::eye(3, 3, CV_16S);
183         Mat maskMat4(3, 3, CV_16S, Scalar(4));
184         Mat maskMat1(3, 3, CV_16S, Scalar(1));
185         Mat maskMat5(3, 3, CV_16S, Scalar(5));
186         Mat maskMat0(3, 3, CV_16S, Scalar(0));
187 
188         CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
189         CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
190         CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
191 
192         Mat m;
193         m = maskMat4.clone(); m &= maskMat1; CHECK_DIFF(maskMat0, m);
194         m = maskMat4.clone(); m &= maskMat1 | maskMat1; CHECK_DIFF(maskMat0, m);
195         m = maskMat4.clone(); m &= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat0, m);
196 
197         m = maskMat4.clone(); m &= Scalar(1); CHECK_DIFF(maskMat0, m);
198         m = maskMat4.clone(); m |= maskMat1; CHECK_DIFF(maskMat5, m);
199         m = maskMat5.clone(); m ^= maskMat1; CHECK_DIFF(maskMat4, m);
200         m = maskMat4.clone(); m |= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat5, m);
201         m = maskMat5.clone(); m ^= (2* maskMat1 - maskMat1); CHECK_DIFF(maskMat4, m);
202 
203         m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
204         m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
205 
206 
207 
208         CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
209         CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
210         CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
211         CHECK_DIFF(maskMat0, (maskMat1 | maskMat1) & Scalar(4));
212         CHECK_DIFF(maskMat0, Scalar(4) & (maskMat1 | maskMat1));
213 
214         CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
215         CHECK_DIFF(maskMat0, (maskMat4 | maskMat1) ^ maskMat5);
216         CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ (maskMat4 + maskMat1));
217         CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
218         CHECK_DIFF(maskMat1, Scalar(5) ^ maskMat4);
219         CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 + maskMat1));
220         CHECK_DIFF(maskMat5, Scalar(5) | (maskMat4 + maskMat1));
221         CHECK_DIFF(maskMat0, (maskMat4 + maskMat1) ^ Scalar(5));
222 
223         CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
224         CHECK_DIFF(maskMat5, (maskMat4 ^ maskMat1) | maskMat5);
225         CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
226         CHECK_DIFF(maskMat5, (maskMat4 | maskMat4) | Scalar(1));
227         CHECK_DIFF(maskMat5, Scalar(1) | (maskMat4 | maskMat4));
228         CHECK_DIFF(maskMat5, Scalar(1) | maskMat4);
229         CHECK_DIFF(maskMat5, (maskMat5 | maskMat5) | (maskMat4 ^ maskMat1));
230 
231         CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
232         CHECK_DIFF(maskMat1, min(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
233         CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
234         CHECK_DIFF(maskMat5, max(Mat(maskMat1 | maskMat1), maskMat5 | maskMat5));
235 
236         CHECK_DIFF(maskMat1, min(maskMat1, maskMat5 | maskMat5));
237         CHECK_DIFF(maskMat1, min(maskMat1 | maskMat1, maskMat5));
238         CHECK_DIFF(maskMat5, max(maskMat1 | maskMat1, maskMat5));
239         CHECK_DIFF(maskMat5, max(maskMat1, maskMat5 | maskMat5));
240 
241         CHECK_DIFF(~maskMat1, maskMat1 ^ -1);
242         CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ -1);
243 
244         CHECK_DIFF(maskMat1, maskMat4/4.0);
245 
246         /////////////////////////////
247 
248         CHECK_DIFF(1.0 - (maskMat5 | maskMat5), -maskMat4);
249         CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 1.0, maskMat5);
250         CHECK_DIFF(1.0 + (maskMat4 | maskMat4) * 1.0, maskMat5);
251         CHECK_DIFF((maskMat5 | maskMat5) * 1.0 - 1.0, maskMat4);
252         CHECK_DIFF(5.0 - (maskMat4 | maskMat4) * 1.0, maskMat1);
253         CHECK_DIFF((maskMat4 | maskMat4) * 1.0 + 0.5 + 0.5, maskMat5);
254         CHECK_DIFF(0.5 + ((maskMat4 | maskMat4) * 1.0 + 0.5), maskMat5);
255         CHECK_DIFF(((maskMat4 | maskMat4) * 1.0 + 2.0) - 1.0, maskMat5);
256         CHECK_DIFF(5.0 - ((maskMat1 | maskMat1) * 1.0 + 3.0), maskMat1);
257         CHECK_DIFF( ( (maskMat1 | maskMat1) * 2.0 + 2.0) * 1.25, maskMat5);
258         CHECK_DIFF( 1.25 * ( (maskMat1 | maskMat1) * 2.0 + 2.0), maskMat5);
259         CHECK_DIFF( -( (maskMat1 | maskMat1) * (-2.0) + 1.0), maskMat1);
260         CHECK_DIFF( maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0, maskMat5);
261         CHECK_DIFF( 1.0 + (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
262         CHECK_DIFF( (maskMat1 * 1.0 + maskMat4 * 0.5 + 2.0) - 1.0, maskMat4);
263         CHECK_DIFF(5.0 -  (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat1);
264         CHECK_DIFF((maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0)*1.25, maskMat5);
265         CHECK_DIFF(1.25 * (maskMat1 * 1.0 + maskMat4 * 0.5 + 1.0), maskMat5);
266         CHECK_DIFF(-(maskMat1 * 2.0 + maskMat4 * (-1) + 1.0), maskMat1);
267         CHECK_DIFF((maskMat1 * 1.0 + maskMat4), maskMat5);
268         CHECK_DIFF((maskMat4 + maskMat1 * 1.0), maskMat5);
269         CHECK_DIFF((maskMat1 * 3.0 + 1.0) + maskMat1, maskMat5);
270         CHECK_DIFF(maskMat1 + (maskMat1 * 3.0 + 1.0), maskMat5);
271         CHECK_DIFF(maskMat1*4.0 + (maskMat1 | maskMat1), maskMat5);
272         CHECK_DIFF((maskMat1 | maskMat1) + maskMat1*4.0, maskMat5);
273         CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1 | maskMat1), maskMat5);
274         CHECK_DIFF((maskMat1 | maskMat1) + (maskMat1*3.0 + 1.0), maskMat5);
275         CHECK_DIFF(maskMat1*4.0 + maskMat4*2.0, maskMat1 * 12);
276         CHECK_DIFF((maskMat1*3.0 + 1.0) + maskMat4*2.0, maskMat1 * 12);
277         CHECK_DIFF(maskMat4*2.0 + (maskMat1*3.0 + 1.0), maskMat1 * 12);
278         CHECK_DIFF((maskMat1*3.0 + 1.0) + (maskMat1*2.0 + 2.0), maskMat1 * 8);
279 
280         CHECK_DIFF(maskMat5*1.0 - maskMat4, maskMat1);
281         CHECK_DIFF(maskMat5 - maskMat1 * 4.0, maskMat1);
282         CHECK_DIFF((maskMat4 * 1.0 + 4.0)- maskMat4, maskMat4);
283         CHECK_DIFF(maskMat5 - (maskMat1 * 2.0 + 2.0), maskMat1);
284         CHECK_DIFF(maskMat5*1.0 - (maskMat4 | maskMat4), maskMat1);
285         CHECK_DIFF((maskMat5 | maskMat5) - maskMat1 * 4.0, maskMat1);
286         CHECK_DIFF((maskMat4 * 1.0 + 4.0)- (maskMat4 | maskMat4), maskMat4);
287         CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 * 2.0 + 2.0), maskMat1);
288         CHECK_DIFF(maskMat1*5.0 - maskMat4 * 1.0, maskMat1);
289         CHECK_DIFF((maskMat1*5.0 + 3.0)- maskMat4 * 1.0, maskMat4);
290         CHECK_DIFF(maskMat4 * 2.0 - (maskMat1*4.0 + 3.0), maskMat1);
291         CHECK_DIFF((maskMat1 * 2.0 + 3.0) - (maskMat1*3.0 + 1.0), maskMat1);
292 
293         CHECK_DIFF((maskMat5 - maskMat4)* 4.0, maskMat4);
294         CHECK_DIFF(4.0 * (maskMat5 - maskMat4), maskMat4);
295 
296         CHECK_DIFF(-((maskMat4 | maskMat4) - (maskMat5 | maskMat5)), maskMat1);
297 
298         CHECK_DIFF(4.0 * (maskMat1 | maskMat1), maskMat4);
299         CHECK_DIFF((maskMat4 | maskMat4)/4.0, maskMat1);
300 
301 #if !MSVC_OLD
302         CHECK_DIFF(2.0 * (maskMat1 * 2.0) , maskMat4);
303 #endif
304         CHECK_DIFF((maskMat4 / 2.0) / 2.0 , maskMat1);
305         CHECK_DIFF(-(maskMat4 - maskMat5) , maskMat1);
306         CHECK_DIFF(-((maskMat4 - maskMat5) * 1.0), maskMat1);
307 
308 
309         /////////////////////////////
310         CHECK_DIFF(maskMat4 /  maskMat4, maskMat1);
311 
312         ///// Element-wise multiplication
313 
314         CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
315         CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
316         CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
317         CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
318         CHECK_DIFF(maskMat4.mul(maskMat4) * 0.25, maskMat4);
319         CHECK_DIFF(0.25 * maskMat4.mul(maskMat4), maskMat4);
320 
321         ////// Element-wise division
322 
323         CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
324         CHECK_DIFF((maskMat4 & maskMat4) / (maskMat1 * 4), maskMat1);
325 
326         CHECK_DIFF((maskMat4 & maskMat4) / maskMat4, maskMat1);
327         CHECK_DIFF(maskMat4 / (maskMat4 & maskMat4), maskMat1);
328         CHECK_DIFF((maskMat1 * 4) / maskMat4, maskMat1);
329 
330         CHECK_DIFF(maskMat4 / (maskMat1 * 4), maskMat1);
331         CHECK_DIFF((maskMat4 * 0.5 )/ (maskMat1 * 2), maskMat1);
332 
333         CHECK_DIFF(maskMat4 / maskMat4.mul(maskMat1), maskMat1);
334         CHECK_DIFF((maskMat4 & maskMat4) / maskMat4.mul(maskMat1), maskMat1);
335 
336         CHECK_DIFF(4.0 / maskMat4, maskMat1);
337         CHECK_DIFF(4.0 / (maskMat4 | maskMat4), maskMat1);
338         CHECK_DIFF(4.0 / (maskMat1 * 4.0), maskMat1);
339         CHECK_DIFF(4.0 / (maskMat4 / maskMat1), maskMat1);
340 
341         m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
342         m = maskMat4.clone(); m/=maskMat4; CHECK_DIFF(m, maskMat1);
343         m = maskMat4.clone(); m/=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
344         m = maskMat4.clone(); m/=(maskMat4 / maskMat1); CHECK_DIFF(m, maskMat1);
345 
346         /////////////////////////////
347         float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
348         Mat mt(3, 3, CV_32F, matrix_data);
349         Mat mi = mt.inv();
350         Mat d1 = Mat::eye(3, 3, CV_32F);
351         Mat d2 = d1 * 2;
352         MatExpr mt_tr = mt.t();
353         MatExpr mi_tr = mi.t();
354         Mat mi2 = mi * 2;
355 
356 
357         CHECK_DIFF_FLT( mi2 * mt, d2 );
358         CHECK_DIFF_FLT( mi * mt, d1 );
359         CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
360 
361         m = mi.clone(); m*=mt;  CHECK_DIFF_FLT(m, d1);
362         m = mi.clone(); m*= (2 * mt - mt) ;  CHECK_DIFF_FLT(m, d1);
363 
364         m = maskMat4.clone(); m+=(maskMat1 * 1.0); CHECK_DIFF(m, maskMat5);
365         m = maskMat5.clone(); m-=(maskMat1 * 4.0); CHECK_DIFF(m, maskMat1);
366 
367         m = maskMat1.clone(); m+=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat5);
368         m = maskMat5.clone(); m-=(maskMat1 * 3.0 + 1.0); CHECK_DIFF(m, maskMat1);
369 #if !MSVC_OLD
370         m = mi.clone(); m+=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi + d1 * 4);
371         m = mi.clone(); m-=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi - d1 * 4);
372         m = mi.clone(); m*=(mt * 1.0); CHECK_DIFF_FLT(m, d1);
373         m = mi.clone(); m*=(mt * 1.0 + Mat::eye(m.size(), m.type())); CHECK_DIFF_FLT(m, d1 + mi);
374         m = mi.clone(); m*=mt_tr.t(); CHECK_DIFF_FLT(m, d1);
375 
376         CHECK_DIFF_FLT( (mi * 2) * mt, d2);
377         CHECK_DIFF_FLT( mi * (2 * mt), d2);
378         CHECK_DIFF_FLT( mt.t() * mi_tr, d1 );
379         CHECK_DIFF_FLT( mt_tr * mi.t(), d1 );
380         CHECK_DIFF_FLT( (mi * 0.4) * (mt * 5), d2);
381 
382         CHECK_DIFF_FLT( mt.t() * (mi_tr * 2), d2 );
383         CHECK_DIFF_FLT( (mt_tr * 2) * mi.t(), d2 );
384 
385         CHECK_DIFF_FLT(mt.t() * mi.t(), d1);
386         CHECK_DIFF_FLT( (mi * mt) * 2.0, d2);
387         CHECK_DIFF_FLT( 2.0 * (mi * mt), d2);
388         CHECK_DIFF_FLT( -(mi * mt), -d1);
389 
390         CHECK_DIFF_FLT( (mi * mt) / 2.0, d1 / 2);
391 
392         Mat mt_mul_2_plus_1;
393         gemm(mt, d1, 2, Mat::ones(3, 3, CV_32F), 1, mt_mul_2_plus_1);
394 
395         CHECK_DIFF( (mt * 2.0 + 1.0) * mi, mt_mul_2_plus_1 * mi);        // (A*alpha + beta)*B
396         CHECK_DIFF( mi * (mt * 2.0 + 1.0), mi * mt_mul_2_plus_1);        // A*(B*alpha + beta)
397         CHECK_DIFF( (mt * 2.0 + 1.0) * (mi * 2), mt_mul_2_plus_1 * mi2); // (A*alpha + beta)*(B*gamma)
398         CHECK_DIFF( (mi *2)* (mt * 2.0 + 1.0), mi2 * mt_mul_2_plus_1);   // (A*gamma)*(B*alpha + beta)
399         CHECK_DIFF_FLT( (mt * 2.0 + 1.0) * mi.t(), mt_mul_2_plus_1 * mi_tr); // (A*alpha + beta)*B^t
400         CHECK_DIFF_FLT( mi.t() * (mt * 2.0 + 1.0), mi_tr * mt_mul_2_plus_1); // A^t*(B*alpha + beta)
401 
402         CHECK_DIFF_FLT( (mi * mt + d2)*5, d1 * 3 * 5);
403         CHECK_DIFF_FLT( mi * mt + d2, d1 * 3);
404         CHECK_DIFF_FLT( -(mi * mt) + d2, d1);
405         CHECK_DIFF_FLT( (mi * mt) + d1, d2);
406         CHECK_DIFF_FLT( d1 + (mi * mt), d2);
407         CHECK_DIFF_FLT( (mi * mt) - d2, -d1);
408         CHECK_DIFF_FLT( d2 - (mi * mt), d1);
409 
410         CHECK_DIFF_FLT( (mi * mt) + d2 * 0.5, d2);
411         CHECK_DIFF_FLT( d2 * 0.5 + (mi * mt), d2);
412         CHECK_DIFF_FLT( (mi * mt) - d1 * 2, -d1);
413         CHECK_DIFF_FLT( d1 * 2 - (mi * mt), d1);
414 
415         CHECK_DIFF_FLT( (mi * mt) + mi.t(), mi_tr + d1);
416         CHECK_DIFF_FLT( mi.t() + (mi * mt), mi_tr + d1);
417         CHECK_DIFF_FLT( (mi * mt) - mi.t(), d1 - mi_tr);
418         CHECK_DIFF_FLT( mi.t() - (mi * mt), mi_tr - d1);
419 
420         CHECK_DIFF_FLT( 2.0 *(mi * mt + d2), d1 * 6);
421         CHECK_DIFF_FLT( -(mi * mt + d2), d1 * -3);
422 
423         CHECK_DIFF_FLT(mt.inv() * mt, d1);
424 
425         CHECK_DIFF_FLT(mt.inv() * (2*mt - mt), d1);
426 #endif
427     }
428     catch (const test_excep& e)
429     {
430         ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
431         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
432         return false;
433     }
434     return true;
435 }
436 
SomeMatFunctions()437 bool CV_OperationsTest::SomeMatFunctions()
438 {
439     try
440     {
441         Mat rgba( 10, 10, CV_8UC4, Scalar(1,2,3,4) );
442         Mat bgr( rgba.rows, rgba.cols, CV_8UC3 );
443         Mat alpha( rgba.rows, rgba.cols, CV_8UC1 );
444         Mat out[] = { bgr, alpha };
445         // rgba[0] -> bgr[2], rgba[1] -> bgr[1],
446         // rgba[2] -> bgr[0], rgba[3] -> alpha[0]
447         int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
448         mixChannels( &rgba, 1, out, 2, from_to, 4 );
449 
450         Mat bgr_exp( rgba.size(), CV_8UC3, Scalar(3,2,1));
451         Mat alpha_exp( rgba.size(), CV_8UC1, Scalar(4));
452 
453         CHECK_DIFF(bgr_exp, bgr);
454         CHECK_DIFF(alpha_exp, alpha);
455     }
456     catch (const test_excep& e)
457     {
458         ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
459         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
460         return false;
461     }
462     return true;
463 
464 }
465 
466 
TestSubMatAccess()467 bool CV_OperationsTest::TestSubMatAccess()
468 {
469     try
470     {
471         Mat_<float> T_bs(4,4);
472         Vec3f cdir(1.f, 1.f, 0.f);
473         Vec3f ydir(1.f, 0.f, 1.f);
474         Vec3f fpt(0.1f, 0.7f, 0.2f);
475         T_bs.setTo(0);
476         T_bs(Range(0,3),Range(2,3)) = 1.0*Mat(cdir); // wierd OpenCV stuff, need to do multiply
477         T_bs(Range(0,3),Range(1,2)) = 1.0*Mat(ydir);
478         T_bs(Range(0,3),Range(0,1)) = 1.0*Mat(cdir.cross(ydir));
479         T_bs(Range(0,3),Range(3,4)) = 1.0*Mat(fpt);
480         T_bs(3,3) = 1.0;
481         //std::cout << "[Nav Grok] S frame =" << std::endl << T_bs << std::endl;
482 
483         // set up display coords, really just the S frame
484         std::vector<float>coords;
485 
486         for (int i=0; i<16; i++)
487         {
488             coords.push_back(T_bs(i));
489             //std::cout << T_bs1(i) << std::endl;
490         }
491         CV_Assert( cvtest::norm(coords, T_bs.reshape(1,1), NORM_INF) == 0 );
492     }
493     catch (const test_excep& e)
494     {
495         ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
496         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
497         return false;
498     }
499     return true;
500 }
501 
TestTemplateMat()502 bool CV_OperationsTest::TestTemplateMat()
503 {
504     try
505     {
506         Mat_<float> one_3x1(3, 1, 1.0f);
507         Mat_<float> shi_3x1(3, 1, 1.2f);
508         Mat_<float> shi_2x1(2, 1, -2);
509         Scalar shift = Scalar::all(15);
510 
511         float data[] = { sqrt(2.f)/2, -sqrt(2.f)/2, 1.f, sqrt(2.f)/2, sqrt(2.f)/2, 10.f };
512         Mat_<float> rot_2x3(2, 3, data);
513 
514         Mat_<float> res = Mat(Mat(2 * rot_2x3) * Mat(one_3x1 + shi_3x1 + shi_3x1 + shi_3x1) - shi_2x1) + shift;
515         Mat_<float> resS = rot_2x3 * one_3x1;
516 
517         Mat_<float> tmp, res2, resS2;
518         add(one_3x1, shi_3x1, tmp);
519         add(tmp, shi_3x1, tmp);
520         add(tmp, shi_3x1, tmp);
521         gemm(rot_2x3, tmp, 2, shi_2x1, -1, res2, 0);
522         add(res2, Mat(2, 1, CV_32F, shift), res2);
523 
524         gemm(rot_2x3, one_3x1, 1, shi_2x1, 0, resS2, 0);
525         CHECK_DIFF(res, res2);
526         CHECK_DIFF(resS, resS2);
527 
528 
529         Mat_<float> mat4x4(4, 4);
530         randu(mat4x4, Scalar(0), Scalar(10));
531 
532         Mat_<float> roi1 = mat4x4(Rect(Point(1, 1), Size(2, 2)));
533         Mat_<float> roi2 = mat4x4(Range(1, 3), Range(1, 3));
534 
535         CHECK_DIFF(roi1, roi2);
536         CHECK_DIFF(mat4x4, mat4x4(Rect(Point(0,0), mat4x4.size())));
537 
538         Mat_<int> intMat10(3, 3, 10);
539         Mat_<int> intMat11(3, 3, 11);
540         Mat_<uchar> resMat(3, 3, 255);
541 
542         CHECK_DIFF(resMat, intMat10 == intMat10);
543         CHECK_DIFF(resMat, intMat10 <  intMat11);
544         CHECK_DIFF(resMat, intMat11 >  intMat10);
545         CHECK_DIFF(resMat, intMat10 <= intMat11);
546         CHECK_DIFF(resMat, intMat11 >= intMat10);
547 
548         CHECK_DIFF(resMat, intMat10 == 10.0);
549         CHECK_DIFF(resMat, intMat10 <  11.0);
550         CHECK_DIFF(resMat, intMat11 >  10.0);
551         CHECK_DIFF(resMat, intMat10 <= 11.0);
552         CHECK_DIFF(resMat, intMat11 >= 10.0);
553 
554         Mat_<uchar> maskMat4(3, 3, 4);
555         Mat_<uchar> maskMat1(3, 3, 1);
556         Mat_<uchar> maskMat5(3, 3, 5);
557         Mat_<uchar> maskMat0(3, 3, (uchar)0);
558 
559         CHECK_DIFF(maskMat0, maskMat4 & maskMat1);
560         CHECK_DIFF(maskMat0, Scalar(1) & maskMat4);
561         CHECK_DIFF(maskMat0, maskMat4 & Scalar(1));
562 
563         Mat_<uchar> m;
564         m = maskMat4.clone(); m&=maskMat1; CHECK_DIFF(maskMat0, m);
565         m = maskMat4.clone(); m&=Scalar(1); CHECK_DIFF(maskMat0, m);
566 
567         m = maskMat4.clone(); m|=maskMat1; CHECK_DIFF(maskMat5, m);
568         m = maskMat4.clone(); m^=maskMat1; CHECK_DIFF(maskMat5, m);
569 
570         CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & (maskMat1 | maskMat1));
571         CHECK_DIFF(maskMat0, (maskMat4 | maskMat4) & maskMat1);
572         CHECK_DIFF(maskMat0, maskMat4 & (maskMat1 | maskMat1));
573 
574         CHECK_DIFF(maskMat0, maskMat5 ^ (maskMat4 | maskMat1));
575         CHECK_DIFF(maskMat0, Scalar(5) ^ (maskMat4 | Scalar(1)));
576 
577         CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ maskMat1));
578         CHECK_DIFF(maskMat5, maskMat5 | (maskMat4 ^ Scalar(1)));
579 
580         CHECK_DIFF(~maskMat1, maskMat1 ^ 0xFF);
581         CHECK_DIFF(~(maskMat1 | maskMat1), maskMat1 ^ 0xFF);
582 
583         CHECK_DIFF(maskMat1 + maskMat4, maskMat5);
584         CHECK_DIFF(maskMat1 + Scalar(4), maskMat5);
585         CHECK_DIFF(Scalar(4) + maskMat1, maskMat5);
586         CHECK_DIFF(Scalar(4) + (maskMat1 & maskMat1), maskMat5);
587 
588         CHECK_DIFF(maskMat1 + 4.0, maskMat5);
589         CHECK_DIFF((maskMat1 & 0xFF) + 4.0, maskMat5);
590         CHECK_DIFF(4.0 + maskMat1, maskMat5);
591 
592         m = maskMat4.clone(); m+=Scalar(1); CHECK_DIFF(m, maskMat5);
593         m = maskMat4.clone(); m+=maskMat1; CHECK_DIFF(m, maskMat5);
594         m = maskMat4.clone(); m+=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat5);
595 
596         CHECK_DIFF(maskMat5 - maskMat1, maskMat4);
597         CHECK_DIFF(maskMat5 - Scalar(1), maskMat4);
598         CHECK_DIFF((maskMat5 | maskMat5) - Scalar(1), maskMat4);
599         CHECK_DIFF(maskMat5 - 1, maskMat4);
600         CHECK_DIFF((maskMat5 | maskMat5) - 1, maskMat4);
601         CHECK_DIFF((maskMat5 | maskMat5) - (maskMat1 | maskMat1), maskMat4);
602 
603         CHECK_DIFF(maskMat1, min(maskMat1, maskMat5));
604         CHECK_DIFF(maskMat5, max(maskMat1, maskMat5));
605 
606         m = maskMat5.clone(); m-=Scalar(1); CHECK_DIFF(m, maskMat4);
607         m = maskMat5.clone(); m-=maskMat1; CHECK_DIFF(m, maskMat4);
608         m = maskMat5.clone(); m-=(maskMat1 | maskMat1); CHECK_DIFF(m, maskMat4);
609 
610         m = maskMat4.clone(); m |= Scalar(1); CHECK_DIFF(maskMat5, m);
611         m = maskMat5.clone(); m ^= Scalar(1); CHECK_DIFF(maskMat4, m);
612 
613         CHECK_DIFF(maskMat1, maskMat4/4.0);
614 
615         Mat_<float> negf(3, 3, -3.0);
616         Mat_<float> posf = -negf;
617         Mat_<float> posf2 = posf * 2;
618         Mat_<int> negi(3, 3, -3);
619 
620         CHECK_DIFF(abs(negf), -negf);
621         CHECK_DIFF(abs(posf - posf2), -negf);
622         CHECK_DIFF(abs(negi), -(negi & negi));
623 
624         CHECK_DIFF(5.0 - maskMat4, maskMat1);
625 
626 
627         CHECK_DIFF(maskMat4.mul(maskMat4, 0.25), maskMat4);
628         CHECK_DIFF(maskMat4.mul(maskMat1 * 4, 0.25), maskMat4);
629         CHECK_DIFF(maskMat4.mul(maskMat4 / 4), maskMat4);
630 
631 
632         ////// Element-wise division
633 
634         CHECK_DIFF(maskMat4 / maskMat4, maskMat1);
635         CHECK_DIFF(4.0 / maskMat4, maskMat1);
636         m = maskMat4.clone(); m/=4.0; CHECK_DIFF(m, maskMat1);
637 
638         ////////////////////////////////
639 
640         typedef Mat_<int> TestMat_t;
641 
642         const TestMat_t cnegi = negi.clone();
643 
644         TestMat_t::iterator beg = negi.begin();
645         TestMat_t::iterator end = negi.end();
646 
647         TestMat_t::const_iterator cbeg = cnegi.begin();
648         TestMat_t::const_iterator cend = cnegi.end();
649 
650         int sum = 0;
651         for(; beg!=end; ++beg)
652             sum+=*beg;
653 
654         for(; cbeg!=cend; ++cbeg)
655             sum-=*cbeg;
656 
657         if (sum != 0) throw test_excep();
658 
659         CHECK_DIFF(negi.col(1), negi.col(2));
660         CHECK_DIFF(negi.row(1), negi.row(2));
661         CHECK_DIFF(negi.col(1), negi.diag());
662 
663         if (Mat_<Point2f>(1, 1).elemSize1() != sizeof(float)) throw test_excep();
664         if (Mat_<Point2f>(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
665         if (Mat_<Point2f>(1, 1).depth() != CV_32F) throw test_excep();
666         if (Mat_<float>(1, 1).depth() != CV_32F) throw test_excep();
667         if (Mat_<int>(1, 1).depth() != CV_32S) throw test_excep();
668         if (Mat_<double>(1, 1).depth() != CV_64F) throw test_excep();
669         if (Mat_<Point3d>(1, 1).depth() != CV_64F) throw test_excep();
670         if (Mat_<signed char>(1, 1).depth() != CV_8S) throw test_excep();
671         if (Mat_<unsigned short>(1, 1).depth() != CV_16U) throw test_excep();
672         if (Mat_<unsigned short>(1, 1).channels() != 1) throw test_excep();
673         if (Mat_<Point2f>(1, 1).channels() != 2) throw test_excep();
674         if (Mat_<Point3f>(1, 1).channels() != 3) throw test_excep();
675         if (Mat_<Point3d>(1, 1).channels() != 3) throw test_excep();
676 
677         Mat_<uchar> eye = Mat_<uchar>::zeros(2, 2); CHECK_DIFF(Mat_<uchar>::zeros(Size(2, 2)), eye);
678         eye.at<uchar>(Point(0,0)) = 1; eye.at<uchar>(1, 1) = 1;
679 
680         CHECK_DIFF(Mat_<uchar>::eye(2, 2), eye);
681         CHECK_DIFF(eye, Mat_<uchar>::eye(Size(2,2)));
682 
683         Mat_<uchar> ones(2, 2, (uchar)1);
684         CHECK_DIFF(ones, Mat_<uchar>::ones(Size(2,2)));
685         CHECK_DIFF(Mat_<uchar>::ones(2, 2), ones);
686 
687         Mat_<Point2f> pntMat(2, 2, Point2f(1, 0));
688         if(pntMat.stepT() != 2) throw test_excep();
689 
690         uchar uchar_data[] = {1, 0, 0, 1};
691 
692         Mat_<uchar> matFromData(1, 4, uchar_data);
693         const Mat_<uchar> mat2 = matFromData.clone();
694         CHECK_DIFF(matFromData, eye.reshape(1, 1));
695         if (matFromData(Point(0,0)) != uchar_data[0])throw test_excep();
696         if (mat2(Point(0,0)) != uchar_data[0]) throw test_excep();
697 
698         if (matFromData(0,0) != uchar_data[0])throw test_excep();
699         if (mat2(0,0) != uchar_data[0]) throw test_excep();
700 
701         Mat_<uchar> rect(eye, Rect(0, 0, 1, 1));
702         if (rect.cols != 1 || rect.rows != 1 || rect(0,0) != uchar_data[0]) throw test_excep();
703 
704         //cv::Mat_<_Tp>::adjustROI(int,int,int,int)
705         //cv::Mat_<_Tp>::cross(const Mat_&) const
706         //cv::Mat_<_Tp>::Mat_(const vector<_Tp>&,bool)
707         //cv::Mat_<_Tp>::Mat_(int,int,_Tp*,size_t)
708         //cv::Mat_<_Tp>::Mat_(int,int,const _Tp&)
709         //cv::Mat_<_Tp>::Mat_(Size,const _Tp&)
710         //cv::Mat_<_Tp>::mul(const Mat_<_Tp>&,double) const
711         //cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_DivRS_<Mat> >,Mat_<_Tp> >&,double) const
712         //cv::Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>,double,Mat_<_Tp>,MatOp_Scale_<Mat> >,Mat_<_Tp> >&,double) const
713         //cv::Mat_<_Tp>::operator Mat_<T2>() const
714         //cv::Mat_<_Tp>::operator MatExpr_<Mat_<_Tp>,Mat_<_Tp> >() const
715         //cv::Mat_<_Tp>::operator()(const Range&,const Range&) const
716         //cv::Mat_<_Tp>::operator()(const Rect&) const
717 
718         //cv::Mat_<_Tp>::operator=(const MatExpr_Base&)
719         //cv::Mat_<_Tp>::operator[](int) const
720 
721 
722         ///////////////////////////////
723 
724         float matrix_data[] = { 3, 1, -4, -5, 1, 0, 0, 1.1f, 1.5f};
725         Mat_<float> mt(3, 3, matrix_data);
726         Mat_<float> mi = mt.inv();
727         Mat_<float> d1 = Mat_<float>::eye(3, 3);
728         Mat_<float> d2 = d1 * 2;
729         Mat_<float> mt_tr = mt.t();
730         Mat_<float> mi_tr = mi.t();
731         Mat_<float> mi2 = mi * 2;
732 
733         CHECK_DIFF_FLT( mi2 * mt, d2 );
734         CHECK_DIFF_FLT( mi * mt, d1 );
735         CHECK_DIFF_FLT( mt_tr * mi_tr, d1 );
736 
737         Mat_<float> mf;
738         mf = mi.clone(); mf*=mt;  CHECK_DIFF_FLT(mf, d1);
739 
740         ////// typedefs //////
741 
742         if (Mat1b(1, 1).elemSize() != sizeof(uchar)) throw test_excep();
743         if (Mat2b(1, 1).elemSize() != 2 * sizeof(uchar)) throw test_excep();
744         if (Mat3b(1, 1).elemSize() != 3 * sizeof(uchar)) throw test_excep();
745         if (Mat1f(1, 1).elemSize() != sizeof(float)) throw test_excep();
746         if (Mat2f(1, 1).elemSize() != 2 * sizeof(float)) throw test_excep();
747         if (Mat3f(1, 1).elemSize() != 3 * sizeof(float)) throw test_excep();
748         if (Mat1f(1, 1).depth() != CV_32F) throw test_excep();
749         if (Mat3f(1, 1).depth() != CV_32F) throw test_excep();
750         if (Mat3f(1, 1).type() != CV_32FC3) throw test_excep();
751         if (Mat1i(1, 1).depth() != CV_32S) throw test_excep();
752         if (Mat1d(1, 1).depth() != CV_64F) throw test_excep();
753         if (Mat1b(1, 1).depth() != CV_8U) throw test_excep();
754         if (Mat3b(1, 1).type() != CV_8UC3) throw test_excep();
755         if (Mat1w(1, 1).depth() != CV_16U) throw test_excep();
756         if (Mat1s(1, 1).depth() != CV_16S) throw test_excep();
757         if (Mat1f(1, 1).channels() != 1) throw test_excep();
758         if (Mat1b(1, 1).channels() != 1) throw test_excep();
759         if (Mat1i(1, 1).channels() != 1) throw test_excep();
760         if (Mat1w(1, 1).channels() != 1) throw test_excep();
761         if (Mat1s(1, 1).channels() != 1) throw test_excep();
762         if (Mat2f(1, 1).channels() != 2) throw test_excep();
763         if (Mat2b(1, 1).channels() != 2) throw test_excep();
764         if (Mat2i(1, 1).channels() != 2) throw test_excep();
765         if (Mat2w(1, 1).channels() != 2) throw test_excep();
766         if (Mat2s(1, 1).channels() != 2) throw test_excep();
767         if (Mat3f(1, 1).channels() != 3) throw test_excep();
768         if (Mat3b(1, 1).channels() != 3) throw test_excep();
769         if (Mat3i(1, 1).channels() != 3) throw test_excep();
770         if (Mat3w(1, 1).channels() != 3) throw test_excep();
771         if (Mat3s(1, 1).channels() != 3) throw test_excep();
772 
773         vector<Mat_<float> > mvf, mvf2;
774         Mat_<Vec2f> mf2;
775         mvf.push_back(Mat_<float>::ones(4, 3));
776         mvf.push_back(Mat_<float>::zeros(4, 3));
777         merge(mvf, mf2);
778         split(mf2, mvf2);
779         CV_Assert( cvtest::norm(mvf2[0], mvf[0], CV_C) == 0 &&
780                   cvtest::norm(mvf2[1], mvf[1], CV_C) == 0 );
781 
782         {
783         Mat a(2,2,CV_32F,1.f);
784         Mat b(1,2,CV_32F,1.f);
785         Mat c = (a*b.t()).t();
786         CV_Assert( cvtest::norm(c, CV_L1) == 4. );
787         }
788 
789         bool badarg_catched = false;
790         try
791         {
792             Mat m1 = Mat::zeros(1, 10, CV_8UC1);
793             Mat m2 = Mat::zeros(10, 10, CV_8UC3);
794             m1.copyTo(m2.row(1));
795         }
796         catch(const Exception&)
797         {
798             badarg_catched = true;
799         }
800         CV_Assert( badarg_catched );
801 
802         Size size(2, 5);
803         TestType<float>(size, 1.f);
804         cv::Vec3f val1 = 1.f;
805         TestType<cv::Vec3f>(size, val1);
806         cv::Matx31f val2 = 1.f;
807         TestType<cv::Matx31f>(size, val2);
808         cv::Matx41f val3 = 1.f;
809         TestType<cv::Matx41f>(size, val3);
810         cv::Matx32f val4 = 1.f;
811         TestType<cv::Matx32f>(size, val4);
812     }
813     catch (const test_excep& e)
814     {
815         ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
816         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
817         return false;
818     }
819     return true;
820 }
821 
TestMatND()822 bool CV_OperationsTest::TestMatND()
823 {
824     int sizes[] = { 3, 3, 3};
825     cv::MatND nd(3, sizes, CV_32F);
826 
827     return true;
828 }
829 
TestSparseMat()830 bool CV_OperationsTest::TestSparseMat()
831 {
832     try
833     {
834         int sizes[] = { 10, 10, 10};
835         int dims = sizeof(sizes)/sizeof(sizes[0]);
836         SparseMat mat(dims, sizes, CV_32FC2);
837 
838         if (mat.dims() != dims) throw test_excep();
839         if (mat.channels() != 2) throw test_excep();
840         if (mat.depth() != CV_32F) throw test_excep();
841 
842         SparseMat mat2 = mat.clone();
843     }
844     catch (const test_excep&)
845     {
846         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
847         return false;
848     }
849     return true;
850 }
851 
852 
TestMatxMultiplication()853 bool CV_OperationsTest::TestMatxMultiplication()
854 {
855     try
856     {
857         Matx33f mat(1, 1, 1, 0, 1, 1, 0, 0, 1); // Identity matrix
858         Point2f pt(3, 4);
859         Point3f res = mat * pt; // Correctly assumes homogeneous coordinates
860 
861         Vec3f res2 = mat*Vec3f(res.x, res.y, res.z);
862 
863         if(res.x != 8.0) throw test_excep();
864         if(res.y != 5.0) throw test_excep();
865         if(res.z != 1.0) throw test_excep();
866 
867         if(res2[0] != 14.0) throw test_excep();
868         if(res2[1] != 6.0) throw test_excep();
869         if(res2[2] != 1.0) throw test_excep();
870 
871         Matx44f mat44f(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
872         Matx44d mat44d(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
873         Scalar s(4, 3, 2, 1);
874         Scalar sf = mat44f*s;
875         Scalar sd = mat44d*s;
876 
877         if(sf[0] != 10.0) throw test_excep();
878         if(sf[1] != 6.0) throw test_excep();
879         if(sf[2] != 3.0) throw test_excep();
880         if(sf[3] != 1.0) throw test_excep();
881 
882         if(sd[0] != 10.0) throw test_excep();
883         if(sd[1] != 6.0) throw test_excep();
884         if(sd[2] != 3.0) throw test_excep();
885         if(sd[3] != 1.0) throw test_excep();
886     }
887     catch(const test_excep&)
888     {
889         ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
890         return false;
891     }
892     return true;
893 }
894 
TestMatxElementwiseDivison()895 bool CV_OperationsTest::TestMatxElementwiseDivison()
896 {
897     try
898     {
899         Matx22f mat(2, 4, 6, 8);
900         Matx22f mat2(2, 2, 2, 2);
901 
902         Matx22f res = mat.div(mat2);
903 
904         if(res(0, 0) != 1.0) throw test_excep();
905         if(res(0, 1) != 2.0) throw test_excep();
906         if(res(1, 0) != 3.0) throw test_excep();
907         if(res(1, 1) != 4.0) throw test_excep();
908     }
909     catch(const test_excep&)
910     {
911         ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
912         return false;
913     }
914     return true;
915 }
916 
917 
TestVec()918 bool CV_OperationsTest::TestVec()
919 {
920     try
921     {
922         cv::Mat hsvImage_f(5, 5, CV_32FC3), hsvImage_b(5, 5, CV_8UC3);
923         int i = 0,j = 0;
924         cv::Vec3f a;
925 
926         //these compile
927         cv::Vec3b b = a;
928         hsvImage_f.at<cv::Vec3f>(i,j) = cv::Vec3f((float)i,0,1);
929         hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3b(cv::Vec3f((float)i,0,1));
930 
931         //these don't
932         b = cv::Vec3f(1,0,0);
933         cv::Vec3b c;
934         c = cv::Vec3f(0,0,1);
935         hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3f((float)i,0,1);
936         hsvImage_b.at<cv::Vec3b>(i,j) = a;
937         hsvImage_b.at<cv::Vec3b>(i,j) = cv::Vec3f(1,2,3);
938     }
939     catch(const test_excep&)
940     {
941         ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
942         return false;
943     }
944     return true;
945 }
946 
operations1()947 bool CV_OperationsTest::operations1()
948 {
949     try
950     {
951         Point3d p1(1, 1, 1), p2(2, 2, 2), p4(4, 4, 4);
952         p1*=2;
953         if (!(p1     == p2)) throw test_excep();
954         if (!(p2 * 2 == p4)) throw test_excep();
955         if (!(p2 * 2.f == p4)) throw test_excep();
956         if (!(p2 * 2.f == p4)) throw test_excep();
957 
958         Point2d pi1(1, 1), pi2(2, 2), pi4(4, 4);
959         pi1*=2;
960         if (!(pi1     == pi2)) throw test_excep();
961         if (!(pi2 * 2 == pi4)) throw test_excep();
962         if (!(pi2 * 2.f == pi4)) throw test_excep();
963         if (!(pi2 * 2.f == pi4)) throw test_excep();
964 
965         Vec2d v12(1, 1), v22(2, 2);
966         v12*=2.0;
967         if (!(v12 == v22)) throw test_excep();
968 
969         Vec3d v13(1, 1, 1), v23(2, 2, 2);
970         v13*=2.0;
971         if (!(v13 == v23)) throw test_excep();
972 
973         Vec4d v14(1, 1, 1, 1), v24(2, 2, 2, 2);
974         v14*=2.0;
975         if (!(v14 == v24)) throw test_excep();
976 
977         Size sz(10, 20);
978         if (sz.area() != 200) throw test_excep();
979         if (sz.width != 10 || sz.height != 20) throw test_excep();
980         if (((CvSize)sz).width != 10 || ((CvSize)sz).height != 20) throw test_excep();
981 
982         Vec<double, 5> v5d(1, 1, 1, 1, 1);
983         Vec<double, 6> v6d(1, 1, 1, 1, 1, 1);
984         Vec<double, 7> v7d(1, 1, 1, 1, 1, 1, 1);
985         Vec<double, 8> v8d(1, 1, 1, 1, 1, 1, 1, 1);
986         Vec<double, 9> v9d(1, 1, 1, 1, 1, 1, 1, 1, 1);
987         Vec<double,10> v10d(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
988 
989         Vec<double,10> v10dzero;
990         for (int ii = 0; ii < 10; ++ii) {
991             if (v10dzero[ii] != 0.0)
992                 throw test_excep();
993         }
994 
995         Mat A(1, 32, CV_32F), B;
996         for( int i = 0; i < A.cols; i++ )
997             A.at<float>(i) = (float)(i <= 12 ? i : 24 - i);
998         transpose(A, B);
999 
1000         int minidx[2] = {0, 0}, maxidx[2] = {0, 0};
1001         double minval = 0, maxval = 0;
1002         minMaxIdx(A, &minval, &maxval, minidx, maxidx);
1003 
1004         if( !(minidx[0] == 0 && minidx[1] == 31 && maxidx[0] == 0 && maxidx[1] == 12 &&
1005                   minval == -7 && maxval == 12))
1006             throw test_excep();
1007 
1008         minMaxIdx(B, &minval, &maxval, minidx, maxidx);
1009 
1010         if( !(minidx[0] == 31 && minidx[1] == 0 && maxidx[0] == 12 && maxidx[1] == 0 &&
1011               minval == -7 && maxval == 12))
1012             throw test_excep();
1013 
1014         Matx33f b(1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f);
1015         Mat c;
1016         add(Mat::zeros(3, 3, CV_32F), b, c);
1017         CV_Assert( cvtest::norm(b, c, CV_C) == 0 );
1018 
1019         add(Mat::zeros(3, 3, CV_64F), b, c, noArray(), c.type());
1020         CV_Assert( cvtest::norm(b, c, CV_C) == 0 );
1021 
1022         add(Mat::zeros(6, 1, CV_64F), 1, c, noArray(), c.type());
1023         CV_Assert( cvtest::norm(Matx61f(1.f, 1.f, 1.f, 1.f, 1.f, 1.f), c, CV_C) == 0 );
1024 
1025         vector<Point2f> pt2d(3);
1026         vector<Point3d> pt3d(2);
1027 
1028         CV_Assert( Mat(pt2d).checkVector(2) == 3 && Mat(pt2d).checkVector(3) < 0 &&
1029                    Mat(pt3d).checkVector(2) < 0 && Mat(pt3d).checkVector(3) == 2 );
1030 
1031         Matx44f m44(0.8147f, 0.6324f, 0.9575f, 0.9572f,
1032                 0.9058f, 0.0975f, 0.9649f, 0.4854f,
1033                 0.1270f, 0.2785f, 0.1576f, 0.8003f,
1034                 0.9134f, 0.5469f, 0.9706f, 0.1419f);
1035         double d = determinant(m44);
1036         CV_Assert( fabs(d - (-0.0262)) <= 0.001 );
1037 
1038         Cv32suf z;
1039         z.i = 0x80000000;
1040         CV_Assert( cvFloor(z.f) == 0 && cvCeil(z.f) == 0 && cvRound(z.f) == 0 );
1041     }
1042     catch(const test_excep&)
1043     {
1044         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1045         return false;
1046     }
1047     return true;
1048 }
1049 
1050 
TestExp()1051 bool CV_OperationsTest::TestExp()
1052 {
1053     Mat1f tt = Mat1f::ones(4,2);
1054     Mat1f outs;
1055     exp(-tt, outs);
1056     Mat1f tt2 = Mat1f::ones(4,1), outs2;
1057     exp(-tt2, outs2);
1058     return true;
1059 }
1060 
1061 
TestSVD()1062 bool CV_OperationsTest::TestSVD()
1063 {
1064     try
1065     {
1066         Mat A = (Mat_<double>(3,4) << 1, 2, -1, 4, 2, 4, 3, 5, -1, -2, 6, 7);
1067         Mat x;
1068         SVD::solveZ(A,x);
1069         if( cvtest::norm(A*x, CV_C) > FLT_EPSILON )
1070             throw test_excep();
1071 
1072         SVD svd(A, SVD::FULL_UV);
1073         if( cvtest::norm(A*svd.vt.row(3).t(), CV_C) > FLT_EPSILON )
1074             throw test_excep();
1075 
1076         Mat Dp(3,3,CV_32FC1);
1077         Mat Dc(3,3,CV_32FC1);
1078         Mat Q(3,3,CV_32FC1);
1079         Mat U,Vt,R,T,W;
1080 
1081         Dp.at<float>(0,0)=0.86483884f; Dp.at<float>(0,1)= -0.3077251f; Dp.at<float>(0,2)=-0.55711365f;
1082         Dp.at<float>(1,0)=0.49294353f; Dp.at<float>(1,1)=-0.24209651f; Dp.at<float>(1,2)=-0.25084701f;
1083         Dp.at<float>(2,0)=0;           Dp.at<float>(2,1)=0;            Dp.at<float>(2,2)=0;
1084 
1085         Dc.at<float>(0,0)=0.75632739f; Dc.at<float>(0,1)= -0.38859656f; Dc.at<float>(0,2)=-0.36773083f;
1086         Dc.at<float>(1,0)=0.9699229f;  Dc.at<float>(1,1)=-0.49858192f;  Dc.at<float>(1,2)=-0.47134098f;
1087         Dc.at<float>(2,0)=0.10566688f; Dc.at<float>(2,1)=-0.060333252f; Dc.at<float>(2,2)=-0.045333147f;
1088 
1089         Q=Dp*Dc.t();
1090         SVD decomp;
1091         decomp=SVD(Q);
1092         U=decomp.u;
1093         Vt=decomp.vt;
1094         W=decomp.w;
1095         Mat I = Mat::eye(3, 3, CV_32F);
1096 
1097         if( cvtest::norm(U*U.t(), I, CV_C) > FLT_EPSILON ||
1098             cvtest::norm(Vt*Vt.t(), I, CV_C) > FLT_EPSILON ||
1099             W.at<float>(2) < 0 || W.at<float>(1) < W.at<float>(2) ||
1100             W.at<float>(0) < W.at<float>(1) ||
1101             cvtest::norm(U*Mat::diag(W)*Vt, Q, CV_C) > FLT_EPSILON )
1102             throw test_excep();
1103     }
1104     catch(const test_excep&)
1105     {
1106         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1107         return false;
1108     }
1109     return true;
1110 }
1111 
run(int)1112 void CV_OperationsTest::run( int /* start_from */)
1113 {
1114     if (!TestMat())
1115         return;
1116 
1117     if (!SomeMatFunctions())
1118         return;
1119 
1120     if (!TestTemplateMat())
1121         return;
1122 
1123  /*   if (!TestMatND())
1124         return;*/
1125 
1126     if (!TestSparseMat())
1127         return;
1128 
1129     if (!TestVec())
1130         return;
1131 
1132     if (!TestMatxMultiplication())
1133         return;
1134 
1135     if (!TestMatxElementwiseDivison())
1136         return;
1137 
1138     if (!TestSubMatAccess())
1139         return;
1140 
1141     if (!TestExp())
1142         return;
1143 
1144     if (!TestSVD())
1145         return;
1146 
1147     if (!operations1())
1148         return;
1149 
1150     ts->set_failed_test_info(cvtest::TS::OK);
1151 }
1152 
TEST(Core_Array,expressions)1153 TEST(Core_Array, expressions) { CV_OperationsTest test; test.safe_run(); }
1154 
1155 class CV_SparseMatTest : public cvtest::BaseTest
1156 {
1157 public:
CV_SparseMatTest()1158     CV_SparseMatTest() {}
~CV_SparseMatTest()1159     ~CV_SparseMatTest() {}
1160 protected:
run(int)1161     void run(int)
1162     {
1163         try
1164         {
1165             RNG& rng = theRNG();
1166             const int MAX_DIM=3;
1167             int sizes[MAX_DIM], idx[MAX_DIM];
1168             for( int iter = 0; iter < 100; iter++ )
1169             {
1170                 ts->printf(cvtest::TS::LOG, ".");
1171                 ts->update_context(this, iter, true);
1172                 int k, dims = rng.uniform(1, MAX_DIM+1), p = 1;
1173                 for( k = 0; k < dims; k++ )
1174                 {
1175                     sizes[k] = rng.uniform(1, 30);
1176                     p *= sizes[k];
1177                 }
1178                 int j, nz = rng.uniform(0, (p+2)/2), nz0 = 0;
1179                 SparseMat_<int> v(dims,sizes);
1180 
1181                 CV_Assert( (int)v.nzcount() == 0 );
1182 
1183                 SparseMatIterator_<int> it = v.begin();
1184                 SparseMatIterator_<int> it_end = v.end();
1185 
1186                 for( k = 0; it != it_end; ++it, ++k )
1187                     ;
1188                 CV_Assert( k == 0 );
1189 
1190                 int sum0 = 0, sum = 0;
1191                 for( j = 0; j < nz; j++ )
1192                 {
1193                     int val = rng.uniform(1, 100);
1194                     for( k = 0; k < dims; k++ )
1195                         idx[k] = rng.uniform(0, sizes[k]);
1196                     if( dims == 1 )
1197                     {
1198                         CV_Assert( v.ref(idx[0]) == v(idx[0]) );
1199                     }
1200                     else if( dims == 2 )
1201                     {
1202                         CV_Assert( v.ref(idx[0], idx[1]) == v(idx[0], idx[1]) );
1203                     }
1204                     else if( dims == 3 )
1205                     {
1206                         CV_Assert( v.ref(idx[0], idx[1], idx[2]) == v(idx[0], idx[1], idx[2]) );
1207                     }
1208                     CV_Assert( v.ref(idx) == v(idx) );
1209                     v.ref(idx) += val;
1210                     if( v(idx) == val )
1211                         nz0++;
1212                     sum0 += val;
1213                 }
1214 
1215                 CV_Assert( (int)v.nzcount() == nz0 );
1216 
1217                 it = v.begin();
1218                 it_end = v.end();
1219 
1220                 for( k = 0; it != it_end; ++it, ++k )
1221                     sum += *it;
1222                 CV_Assert( k == nz0 && sum == sum0 );
1223 
1224                 v.clear();
1225                 CV_Assert( (int)v.nzcount() == 0 );
1226 
1227                 it = v.begin();
1228                 it_end = v.end();
1229 
1230                 for( k = 0; it != it_end; ++it, ++k )
1231                     ;
1232                 CV_Assert( k == 0 );
1233             }
1234         }
1235         catch(...)
1236         {
1237             ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
1238         }
1239     }
1240 };
1241 
TEST(Core_SparseMat,iterations)1242 TEST(Core_SparseMat, iterations) { CV_SparseMatTest test; test.safe_run(); }
1243