opencv 2.2.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
operations.hpp
Go to the documentation of this file.
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 #ifndef __OPENCV_CORE_OPERATIONS_HPP__
44 #define __OPENCV_CORE_OPERATIONS_HPP__
45
46 #ifndef SKIP_INCLUDES
47 #include <string.h>
48 #include <limits.h>
49 #endif // SKIP_INCLUDES
50
51 #ifdef __cplusplus
52
54 #ifdef __GNUC__
55
56 #if __GNUC__*10 + __GNUC_MINOR__ >= 42
57
58 #if !defined WIN32 && (defined __i486__ || defined __i586__ || \
59 defined __i686__ || defined __MMX__ || defined __SSE__ || defined __ppc__)
60 #define CV_XADD __sync_fetch_and_add
61 #else
62 #include <ext/atomicity.h>
63 #define CV_XADD __gnu_cxx::__exchange_and_add
64 #endif
65
66 #else
67 #include <bits/atomicity.h>
68 #if __GNUC__*10 + __GNUC_MINOR__ >= 34
69 #define CV_XADD __gnu_cxx::__exchange_and_add
70 #else
71 #define CV_XADD __exchange_and_add
72 #endif
73 #endif
74
75 #elif defined WIN32 || defined _WIN32
76
77 #if defined _MSC_VER && defined _M_IX86
78 static inline int CV_XADD( int* addr, int delta )
79 {
80 int tmp;
81 __asm
82 {
83 mov edx, addr
84 mov eax, delta
85 lock xadd [edx], eax
86 mov tmp, eax
87 }
88 return tmp;
89 }
90 #else
91 #include "windows.h"
92 #undef min
93 #undef max
94 #define CV_XADD(addr,delta) InterlockedExchangeAdd((LONG volatile*)(addr), (delta))
95 #endif
96
97 #else
98
99 template<typename _Tp> static inline _Tp CV_XADD(_Tp* addr, _Tp delta)
100 { int tmp = *addr; *addr += delta; return tmp; }
101
102 #endif
103
104 #include <limits>
105
106 namespace cv
107 {
108
109 using std::cos;
110 using std::sin;
111 using std::max;
112 using std::min;
113 using std::exp;
114 using std::log;
115 using std::pow;
116 using std::sqrt;
117
118
120
121 template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
122 template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
123 template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
124 template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
125 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
126 template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
127 template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
128 template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
129
130 template<> inline uchar saturate_cast<uchar>(schar v)
131 { return (uchar)std::max((int)v, 0); }
132 template<> inline uchar saturate_cast<uchar>(ushort v)
133 { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
134 template<> inline uchar saturate_cast<uchar>(int v)
135 { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
136 template<> inline uchar saturate_cast<uchar>(short v)
137 { return saturate_cast<uchar>((int)v); }
138 template<> inline uchar saturate_cast<uchar>(unsigned v)
139 { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
140 template<> inline uchar saturate_cast<uchar>(float v)
141 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
142 template<> inline uchar saturate_cast<uchar>(double v)
143 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
144
145 template<> inline schar saturate_cast<schar>(uchar v)
146 { return (schar)std::min((int)v, SCHAR_MAX); }
147 template<> inline schar saturate_cast<schar>(ushort v)
148 { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
149 template<> inline schar saturate_cast<schar>(int v)
150 {
151 return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ?
152 v : v > 0 ? SCHAR_MAX : SCHAR_MIN);
153 }
154 template<> inline schar saturate_cast<schar>(short v)
155 { return saturate_cast<schar>((int)v); }
156 template<> inline schar saturate_cast<schar>(unsigned v)
157 { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
158
159 template<> inline schar saturate_cast<schar>(float v)
160 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
161 template<> inline schar saturate_cast<schar>(double v)
162 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
163
164 template<> inline ushort saturate_cast<ushort>(schar v)
165 { return (ushort)std::max((int)v, 0); }
166 template<> inline ushort saturate_cast<ushort>(short v)
167 { return (ushort)std::max((int)v, 0); }
168 template<> inline ushort saturate_cast<ushort>(int v)
169 { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
170 template<> inline ushort saturate_cast<ushort>(unsigned v)
171 { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
172 template<> inline ushort saturate_cast<ushort>(float v)
173 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
174 template<> inline ushort saturate_cast<ushort>(double v)
175 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
176
177 template<> inline short saturate_cast<short>(ushort v)
178 { return (short)std::min((int)v, SHRT_MAX); }
179 template<> inline short saturate_cast<short>(int v)
180 {
181 return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ?
182 v : v > 0 ? SHRT_MAX : SHRT_MIN);
183 }
184 template<> inline short saturate_cast<short>(unsigned v)
185 { return (short)std::min(v, (unsigned)SHRT_MAX); }
186 template<> inline short saturate_cast<short>(float v)
187 { int iv = cvRound(v); return saturate_cast<short>(iv); }
188 template<> inline short saturate_cast<short>(double v)
189 { int iv = cvRound(v); return saturate_cast<short>(iv); }
190
191 template<> inline int saturate_cast<int>(float v) { return cvRound(v); }
192 template<> inline int saturate_cast<int>(double v) { return cvRound(v); }
193
194 // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
195 template<> inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); }
196 template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
197
198
200
201
202 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx()
203 {
204 for(int i = 0; i < channels; i++) val[i] = _Tp(0);
205 }
206
207 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0)
208 {
209 val[0] = v0;
210 for(int i = 1; i < channels; i++) val[i] = _Tp(0);
211 }
212
213 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
214 {
215 assert(channels >= 2);
216 val[0] = v0; val[1] = v1;
217 for(int i = 2; i < channels; i++) val[i] = _Tp(0);
218 }
219
220 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
221 {
222 assert(channels >= 3);
223 val[0] = v0; val[1] = v1; val[2] = v2;
224 for(int i = 3; i < channels; i++) val[i] = _Tp(0);
225 }
226
227 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
228 {
229 assert(channels >= 4);
230 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
231 for(int i = 4; i < channels; i++) val[i] = _Tp(0);
232 }
233
234 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
235 {
236 assert(channels >= 5);
237 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
238 for(int i = 5; i < channels; i++) val[i] = _Tp(0);
239 }
240
241 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
242 _Tp v4, _Tp v5)
243 {
244 assert(channels >= 6);
245 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
246 val[4] = v4; val[5] = v5;
247 for(int i = 6; i < channels; i++) val[i] = _Tp(0);
248 }
249
250 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
251 _Tp v4, _Tp v5, _Tp v6)
252 {
253 assert(channels >= 7);
254 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
255 val[4] = v4; val[5] = v5; val[6] = v6;
256 for(int i = 7; i < channels; i++) val[i] = _Tp(0);
257 }
258
259 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
260 _Tp v4, _Tp v5, _Tp v6, _Tp v7)
261 {
262 assert(channels >= 8);
263 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
264 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
265 for(int i = 8; i < channels; i++) val[i] = _Tp(0);
266 }
267
268 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
269 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
270 _Tp v8)
271 {
272 assert(channels >= 9);
273 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
274 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
275 val[8] = v8;
276 for(int i = 9; i < channels; i++) val[i] = _Tp(0);
277 }
278
279 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
280 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
281 _Tp v8, _Tp v9)
282 {
283 assert(channels >= 10);
284 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
285 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
286 val[8] = v8; val[9] = v9;
287 for(int i = 10; i < channels; i++) val[i] = _Tp(0);
288 }
289
290
291 template<typename _Tp, int m, int n>
292 inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
293 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
294 _Tp v8, _Tp v9, _Tp v10, _Tp v11)
295 {
296 assert(channels == 12);
297 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
298 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
299 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
300 }
301
302 template<typename _Tp, int m, int n>
303 inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
304 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
305 _Tp v8, _Tp v9, _Tp v10, _Tp v11,
306 _Tp v12, _Tp v13, _Tp v14, _Tp v15)
307 {
308 assert(channels == 16);
309 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
310 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
311 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
312 val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
313 }
314
315 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(const _Tp* values)
316 {
317 for( int i = 0; i < channels; i++ ) val[i] = values[i];
318 }
319
320 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
321 {
322 Matx<_Tp, m, n> M;
323 for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
324 return M;
325 }
326
327 template<typename _Tp, int m, int n> inline
328 Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
329 {
330 return all(0);
331 }
332
333 template<typename _Tp, int m, int n> inline
334 Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
335 {
336 return all(1);
337 }
338
339 template<typename _Tp, int m, int n> inline
340 Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
341 {
342 Matx<_Tp,m,n> M;
343 for(int i = 0; i < MIN(m,n); i++)
344 M(i,i) = 1;
345 return M;
346 }
347
348 template<typename _Tp, int m, int n> inline _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
349 {
350 _Tp s = 0;
351 for( int i = 0; i < m*n; i++ ) s += val[i]*M.val[i];
352 return s;
353 }
354
355
356 template<typename _Tp, int m, int n> inline double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
357 {
358 double s = 0;
359 for( int i = 0; i < m*n; i++ ) s += (double)val[i]*M.val[i];
360 return s;
361 }
362
363
364
365 template<typename _Tp, int m, int n> inline
366 Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Matx<_Tp,MIN(m,n),1>& d)
367 {
368 Matx<_Tp,m,n> M;
369 for(int i = 0; i < MIN(m,n); i++)
370 M(i,i) = d[i];
371 return M;
372 }
373
374 template<typename _Tp, int m, int n> inline
375 Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
376 {
377 Matx<_Tp,m,n> M;
378 Mat matM(M, false);
379 cv::randu(matM, Scalar(a), Scalar(b));
380 return M;
381 }
382
383 template<typename _Tp, int m, int n> inline
384 Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
385 {
386 Matx<_Tp,m,n> M;
387 Mat matM(M, false);
388 cv::randn(matM, Scalar(a), Scalar(b));
389 return M;
390 }
391
392 template<typename _Tp, int m, int n> template<typename T2>
393 inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
394 {
395 Matx<T2, m, n> M;
396 for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
397 return M;
398 }
399
400
401 template<typename _Tp, int m, int n> template<int m1, int n1> inline
402 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
403 {
404 CV_DbgAssert(m1*n1 == m*n);
405 return (const Matx<_Tp, m1, n1>&)*this;
406 }
407
408
409 template<typename _Tp, int m, int n>
410 template<int m1, int n1> inline
411 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
412 {
413 CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
414 Matx<_Tp, m1, n1> s;
415 for( int di = 0; di < m1; di++ )
416 for( int dj = 0; dj < n1; dj++ )
417 s(di, dj) = (*this)(i+di, j+dj);
418 return s;
419 }
420
421
422 template<typename _Tp, int m, int n> inline
423 Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
424 {
425 CV_DbgAssert((unsigned)i < (unsigned)m);
426 return Matx<_Tp, 1, n>(&val[i*n]);
427 }
428
429
430 template<typename _Tp, int m, int n> inline
431 Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
432 {
433 CV_DbgAssert((unsigned)j < (unsigned)n);
434 Matx<_Tp, m, 1> v;
435 for( int i = 0; i < m; i++ )
436 v[i] = val[i*n + j];
437 return v;
438 }
439
440
441 template<typename _Tp, int m, int n> inline
442 Matx<_Tp, MIN(m,n), 1> Matx<_Tp, m, n>::diag() const
443 {
444 diag_type d;
445 for( int i = 0; i < MIN(m, n); i++ )
446 d.val[i] = val[i*n + i];
447 return d;
448 }
449
450
451 template<typename _Tp, int m, int n> inline
452 const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const
453 {
454 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
455 return this->val[i*n + j];
456 }
457
458
459 template<typename _Tp, int m, int n> inline
460 _Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
461 {
462 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
463 return val[i*n + j];
464 }
465
466
467 template<typename _Tp, int m, int n> inline
468 const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
469 {
470 CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
471 return val[i];
472 }
473
474
475 template<typename _Tp, int m, int n> inline
476 _Tp& Matx<_Tp, m, n>::operator ()(int i)
477 {
478 CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
479 return val[i];
480 }
481
482
483 template<typename _Tp1, typename _Tp2, int m, int n> static inline
484 Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
485 {
486 for( int i = 0; i < m*n; i++ )
487 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
488 return a;
489 }
490
491
492 template<typename _Tp1, typename _Tp2, int m, int n> static inline
493 Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
494 {
495 for( int i = 0; i < m*n; i++ )
496 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
497 return a;
498 }
499
500
501 template<typename _Tp, int m, int n> inline
502 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
503 {
504 for( int i = 0; i < m*n; i++ )
505 val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
506 }
507
508
509 template<typename _Tp, int m, int n> inline
510 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
511 {
512 for( int i = 0; i < m*n; i++ )
513 val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
514 }
515
516
517 template<typename _Tp, int m, int n> template<typename _T2> inline
518 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
519 {
520 for( int i = 0; i < m*n; i++ )
521 val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
522 }
523
524
525 template<typename _Tp, int m, int n> inline
526 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
527 {
528 for( int i = 0; i < m*n; i++ )
529 val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
530 }
531
532
533 template<typename _Tp, int m, int n> template<int l> inline
534 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
535 {
536 for( int i = 0; i < m; i++ )
537 for( int j = 0; j < n; j++ )
538 {
539 _Tp s = 0;
540 for( int k = 0; k < l; k++ )
541 s += a(i, k) * b(k, j);
542 val[i*n + j] = s;
543 }
544 }
545
546
547 template<typename _Tp, int m, int n> inline
548 Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
549 {
550 for( int i = 0; i < m; i++ )
551 for( int j = 0; j < n; j++ )
552 val[i*n + j] = a(j, i);
553 }
554
555
556 template<typename _Tp, int m, int n> static inline
557 Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
558 {
559 return Matx<_Tp, m, n>(a, b, Matx_AddOp());
560 }
561
562
563 template<typename _Tp, int m, int n> static inline
564 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
565 {
566 return Matx<_Tp, m, n>(a, b, Matx_SubOp());
567 }
568
569
570 template<typename _Tp, int m, int n> static inline
571 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
572 {
573 for( int i = 0; i < m*n; i++ )
574 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
575 }
576
577 template<typename _Tp, int m, int n> static inline
578 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
579 {
580 for( int i = 0; i < m*n; i++ )
581 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
582 }
583
584 template<typename _Tp, int m, int n> static inline
585 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
586 {
587 for( int i = 0; i < m*n; i++ )
588 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
589 }
590
591 template<typename _Tp, int m, int n> static inline
592 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
593 {
594 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
595 }
596
597 template<typename _Tp, int m, int n> static inline
598 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
599 {
600 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
601 }
602
603 template<typename _Tp, int m, int n> static inline
604 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
605 {
606 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
607 }
608
609 template<typename _Tp, int m, int n> static inline
610 Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
611 {
612 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
613 }
614
615 template<typename _Tp, int m, int n> static inline
616 Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
617 {
618 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
619 }
620
621 template<typename _Tp, int m, int n> static inline
622 Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
623 {
624 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
625 }
626
627 template<typename _Tp, int m, int n> static inline
628 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
629 {
630 return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
631 }
632
633
634 template<typename _Tp, int m, int n, int l> static inline
635 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
636 {
637 return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
638 }
639
640
641 template<typename _Tp> static inline
642 Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
643 {
644 return Point_<_Tp>(a*Vec<_Tp,2>(b));
645 }
646
647
648 template<typename _Tp> static inline
649 Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
650 {
651 return Point3_<_Tp>(a*Vec<_Tp,3>(b));
652 }
653
654
655 template<typename _Tp> static inline
656 Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
657 {
658 return Point3_<_Tp>(a*Vec<_Tp,3>(b.x, b.y, 1));
659 }
660
661
662 template<typename _Tp> static inline
663 Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
664 {
665 return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
666 }
667
668
669 template<typename _Tp> static inline
670 Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
671 {
672 return Scalar(a*Matx<_Tp, 4, 1>(b));
673 }
674
675
676 template<typename _Tp, int m, int n> inline
677 Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
678 {
679 return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
680 }
681
682
683 CV_EXPORTS int LU(float* A, int m, float* b, int n);
684 CV_EXPORTS int LU(double* A, int m, double* b, int n);
685 CV_EXPORTS bool Cholesky(float* A, int m, float* b, int n);
686 CV_EXPORTS bool Cholesky(double* A, int m, double* b, int n);
687
688
689 template<typename _Tp, int m> struct CV_EXPORTS Matx_DetOp
690 {
691 double operator ()(const Matx<_Tp, m, m>& a) const
692 {
693 Matx<_Tp, m, m> temp = a;
694 double p = LU(temp.val, m, 0, 0);
695 if( p == 0 )
696 return p;
697 for( int i = 0; i < m; i++ )
698 p *= temp(i, i);
699 return p;
700 }
701 };
702
703
704 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
705 {
706 double operator ()(const Matx<_Tp, 1, 1>& a) const
707 {
708 return a(0,0);
709 }
710 };
711
712
713 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
714 {
715 double operator ()(const Matx<_Tp, 2, 2>& a) const
716 {
717 return a(0,0)*a(1,1) - a(0,1)*a(1,0);
718 }
719 };
720
721
722 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
723 {
724 double operator ()(const Matx<_Tp, 3, 3>& a) const
725 {
726 return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
727 a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
728 a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
729 }
730 };
731
732 template<typename _Tp, int m> static inline
733 double determinant(const Matx<_Tp, m, m>& a)
734 {
735 return Matx_DetOp<_Tp, m>()(a);
736 }
737
738
739 template<typename _Tp, int m, int n> static inline
740 double trace(const Matx<_Tp, m, n>& a)
741 {
742 _Tp s = 0;
743 for( int i = 0; i < std::min(m, n); i++ )
744 s += a(i,i);
745 return s;
746 }
747
748
749 template<typename _Tp, int m, int n> inline
750 Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
751 {
752 return Matx<_Tp, n, m>(*this, Matx_TOp());
753 }
754
755
756 template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
757 {
758 bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
759 {
760 Matx<_Tp, m, m> temp = a;
761
762 // assume that b is all 0's on input => make it a unity matrix
763 for( int i = 0; i < m; i++ )
764 b(i, i) = (_Tp)1;
765
766 if( method == DECOMP_CHOLESKY )
767 return Cholesky(temp.val, m, b.val, m);
768
769 return LU(temp.val, m, b.val, m) != 0;
770 }
771 };
772
773
774 template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
775 {
776 bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
777 {
778 _Tp d = determinant(a);
779 if( d == 0 )
780 return false;
781 d = 1/d;
782 b(1,1) = a(0,0)*d;
783 b(0,0) = a(1,1)*d;
784 b(0,1) = -a(0,1)*d;
785 b(1,0) = -a(1,0)*d;
786 return true;
787 }
788 };
789
790
791 template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
792 {
793 bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
794 {
795 _Tp d = determinant(a);
796 if( d == 0 )
797 return false;
798 d = 1/d;
799 b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
800 b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
801 b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
802
803 b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
804 b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
805 b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
806
807 b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
808 b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
809 b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
810 return true;
811 }
812 };
813
814
815 template<typename _Tp, int m, int n> inline
816 Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const
817 {
818 Matx<_Tp, n, m> b;
819 bool ok;
820 if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
821 ok = Matx_FastInvOp<_Tp, m>()(*this, b, method);
822 else
823 {
824 Mat A(*this, false), B(b, false);
825 ok = invert(A, B, method);
826 }
827 return ok ? b : Matx<_Tp, n, m>::zeros();
828 }
829
830
831 template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
832 {
833 bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
834 Matx<_Tp, m, n>& x, int method) const
835 {
836 Matx<_Tp, m, m> temp = a;
837 x = b;
838 if( method == DECOMP_CHOLESKY )
839 return Cholesky(temp.val, m, x.val, n);
840
841 return LU(temp.val, m, x.val, n) != 0;
842 }
843 };
844
845
846 template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
847 {
848 bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
849 Matx<_Tp, 2, 1>& x, int method) const
850 {
851 _Tp d = determinant(a);
852 if( d == 0 )
853 return false;
854 d = 1/d;
855 x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
856 x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
857 return true;
858 }
859 };
860
861
862 template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
863 {
864 bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
865 Matx<_Tp, 3, 1>& x, int method) const
866 {
867 _Tp d = determinant(a);
868 if( d == 0 )
869 return false;
870 d = 1/d;
871 x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
872 a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
873 a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
874
875 x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
876 b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
877 a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
878
879 x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
880 a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
881 b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
882 return true;
883 }
884 };
885
886
887 template<typename _Tp, int m, int n> template<int l> inline
888 Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
889 {
890 Matx<_Tp, n, l> x;
891 bool ok;
892 if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
893 ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
894 else
895 {
896 Mat A(*this, false), B(rhs, false), X(x, false);
897 ok = cv::solve(A, B, X, method);
898 }
899
900 return ok ? x : Matx<_Tp, n, l>::zeros();
901 }
902
903
904 template<typename _Tp, int m, int n> static inline
905 double norm(const Matx<_Tp, m, n>& M)
906 {
907 double s = 0;
908 for( int i = 0; i < m*n; i++ )
909 s += (double)M.val[i]*M.val[i];
910 return std::sqrt(s);
911 }
912
913
914 template<typename _Tp, int m, int n> static inline
915 double norm(const Matx<_Tp, m, n>& M, int normType)
916 {
917 if( normType == NORM_INF )
918 {
919 _Tp s = 0;
920 for( int i = 0; i < m*n; i++ )
921 s = std::max(s, std::abs(M.val[i]));
922 return s;
923 }
924
925 if( normType == NORM_L1 )
926 {
927 _Tp s = 0;
928 for( int i = 0; i < m*n; i++ )
929 s += std::abs(M.val[i]);
930 return s;
931 }
932
933 CV_DbgAssert( normType == NORM_L2 );
934 return norm(M);
935 }
936
937
938 template<typename _Tp, int m, int n> static inline
939 bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
940 {
941 for( int i = 0; i < m*n; i++ )
942 if( a.val[i] != b.val[i] ) return false;
943 return true;
944 }
945
946 template<typename _Tp, int m, int n> static inline
947 bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
948 {
949 return !(a == b);
950 }
951
952
953 template<typename _Tp, typename _T2, int m, int n> static inline
954 MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
955 {
956 MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
957 return (commaInitializer, val);
958 }
959
960 template<typename _Tp, int m, int n> inline
961 MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
962 : dst(_mtx), idx(0)
963 {}
964
965 template<typename _Tp, int m, int n> template<typename _T2> inline
966 MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
967 {
968 CV_DbgAssert( idx < m*n );
969 dst->val[idx++] = saturate_cast<_Tp>(value);
970 return *this;
971 }
972
973 template<typename _Tp, int m, int n> inline
974 Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
975 {
976 CV_DbgAssert( idx == n*m );
977 return *dst;
978 }
979
981
982 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
983 {}
984
985 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
986 : Matx<_Tp, cn, 1>(v0)
987 {}
988
989 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
990 : Matx<_Tp, cn, 1>(v0, v1)
991 {}
992
993 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
994 : Matx<_Tp, cn, 1>(v0, v1, v2)
995 {}
996
997 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
998 : Matx<_Tp, cn, 1>(v0, v1, v2, v3)
999 {}
1000
1001 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
1002 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4)
1003 {}
1004
1005 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
1006 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5)
1007 {}
1008
1009 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1010 _Tp v4, _Tp v5, _Tp v6)
1011 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6)
1012 {}
1013
1014 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1015 _Tp v4, _Tp v5, _Tp v6, _Tp v7)
1016 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7)
1017 {}
1018
1019 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1020 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
1021 _Tp v8)
1022 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8)
1023 {}
1024
1025 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
1026 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
1027 _Tp v8, _Tp v9)
1028 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
1029 {}
1030
1031 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
1032 : Matx<_Tp, cn, 1>(values)
1033 {}
1034
1035
1036 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
1037 : Matx<_Tp, cn, 1>(v.val)
1038 {}
1039
1040 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
1041 {
1042 Vec v;
1043 for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
1044 return v;
1045 }
1046
1047 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
1048 {
1049 Vec<_Tp, cn> w;
1050 for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
1051 return w;
1052 }
1053
1054 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
1055 {
1056 CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
1057 return Vec<_Tp, cn>();
1058 }
1059
1060 template<typename _Tp, int cn> template<typename T2>
1061 inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
1062 {
1063 Vec<T2, cn> v;
1064 for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
1065 return v;
1066 }
1067
1068 template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
1069 {
1070 CvScalar s = {{0,0,0,0}};
1071 int i;
1072 for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = this->val[i];
1073 for( ; i < 4; i++ ) s.val[i] = 0;
1074 return s;
1075 }
1076
1077 template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
1078 {
1079 CV_DbgAssert( (unsigned)i < (unsigned)cn );
1080 return this->val[i];
1081 }
1082
1083 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator [](int i)
1084 {
1085 CV_DbgAssert( (unsigned)i < (unsigned)cn );
1086 return this->val[i];
1087 }
1088
1089 template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
1090 {
1091 CV_DbgAssert( (unsigned)i < (unsigned)cn );
1092 return this->val[i];
1093 }
1094
1095 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator ()(int i)
1096 {
1097 CV_DbgAssert( (unsigned)i < (unsigned)cn );
1098 return this->val[i];
1099 }
1100
1101 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
1102 operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1103 {
1104 for( int i = 0; i < cn; i++ )
1105 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
1106 return a;
1107 }
1108
1109 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
1110 operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1111 {
1112 for( int i = 0; i < cn; i++ )
1113 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
1114 return a;
1115 }
1116
1117 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1118 operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1119 {
1120 Vec<_Tp, cn> c = a;
1121 return c += b;
1122 }
1123
1124 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1125 operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1126 {
1127 Vec<_Tp, cn> c = a;
1128 return c -= b;
1129 }
1130
1131 template<typename _Tp> static inline
1132 Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha)
1133 {
1134 a[0] *= alpha; a[1] *= alpha;
1135 return a;
1136 }
1137
1138 template<typename _Tp> static inline
1139 Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha)
1140 {
1141 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha;
1142 return a;
1143 }
1144
1145 template<typename _Tp> static inline
1146 Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha)
1147 {
1148 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha;
1149 return a;
1150 }
1151
1152 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1153 operator * (const Vec<_Tp, cn>& a, _Tp alpha)
1154 {
1155 Vec<_Tp, cn> c = a;
1156 return c *= alpha;
1157 }
1158
1159 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1160 operator * (_Tp alpha, const Vec<_Tp, cn>& a)
1161 {
1162 return a * alpha;
1163 }
1164
1165
1166 template<typename _Tp> static inline Vec<_Tp, 4>
1167 operator * (const Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
1168 {
1169 return Vec<_Tp, 4>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
1170 saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
1171 saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]),
1172 saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0]));
1173 }
1174
1175
1176 template<typename _Tp> static inline Vec<_Tp, 4>&
1177 operator *= (Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
1178 {
1179 a = a*b;
1180 return a;
1181 }
1182
1183
1184 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
1185 operator - (const Vec<_Tp, cn>& a)
1186 {
1187 Vec<_Tp,cn> t;
1188 for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
1189 return t;
1190 }
1191
1192 template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
1193 {
1194 return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
1195 val[2]*v.val[0] - val[0]*v.val[2],
1196 val[0]*v.val[1] - val[1]*v.val[0]);
1197 }
1198
1199 template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
1200 {
1201 return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
1202 val[2]*v.val[0] - val[0]*v.val[2],
1203 val[0]*v.val[1] - val[1]*v.val[0]);
1204 }
1205
1206 template<typename T1, typename T2> static inline
1207 Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
1208 {
1209 a[0] = saturate_cast<T1>(a[0] + b[0]);
1210 a[1] = saturate_cast<T1>(a[1] + b[1]);
1211 return a;
1212 }
1213
1214 template<typename T1, typename T2> static inline
1215 Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
1216 {
1217 a[0] = saturate_cast<T1>(a[0] + b[0]);
1218 a[1] = saturate_cast<T1>(a[1] + b[1]);
1219 a[2] = saturate_cast<T1>(a[2] + b[2]);
1220 return a;
1221 }
1222
1223
1224 template<typename T1, typename T2> static inline
1225 Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
1226 {
1227 a[0] = saturate_cast<T1>(a[0] + b[0]);
1228 a[1] = saturate_cast<T1>(a[1] + b[1]);
1229 a[2] = saturate_cast<T1>(a[2] + b[2]);
1230 a[3] = saturate_cast<T1>(a[3] + b[3]);
1231 return a;
1232 }
1233
1234
1235 template<typename _Tp, typename _T2, int cn> static inline
1236 VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
1237 {
1238 VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
1239 return (commaInitializer, val);
1240 }
1241
1242 template<typename _Tp, int cn> inline
1243 VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
1244 : MatxCommaInitializer<_Tp, cn, 1>(_vec)
1245 {}
1246
1247 template<typename _Tp, int cn> template<typename _T2> inline
1248 VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
1249 {
1250 CV_DbgAssert( this->idx < cn );
1251 this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
1252 return *this;
1253 }
1254
1255 template<typename _Tp, int cn> inline
1256 Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
1257 {
1258 CV_DbgAssert( this->idx == cn );
1259 return *this->dst;
1260 }
1261
1263
1264 template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {}
1265 template<typename _Tp> inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {}
1266 template<typename _Tp> template<typename T2> inline Complex<_Tp>::operator Complex<T2>() const
1267 { return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); }
1268 template<typename _Tp> inline Complex<_Tp> Complex<_Tp>::conj() const
1269 { return Complex<_Tp>(re, -im); }
1270
1271 template<typename _Tp> static inline
1272 bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
1273 { return a.re == b.re && a.im == b.im; }
1274
1275 template<typename _Tp> static inline
1276 bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
1277 { return a.re != b.re || a.im != b.im; }
1278
1279 template<typename _Tp> static inline
1280 Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
1281 { return Complex<_Tp>( a.re + b.re, a.im + b.im ); }
1282
1283 template<typename _Tp> static inline
1284 Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
1285 { a.re += b.re; a.im += b.im; return a; }
1286
1287 template<typename _Tp> static inline
1288 Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
1289 { return Complex<_Tp>( a.re - b.re, a.im - b.im ); }
1290
1291 template<typename _Tp> static inline
1292 Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
1293 { a.re -= b.re; a.im -= b.im; return a; }
1294
1295 template<typename _Tp> static inline
1296 Complex<_Tp> operator - (const Complex<_Tp>& a)
1297 { return Complex<_Tp>(-a.re, -a.im); }
1298
1299 template<typename _Tp> static inline
1300 Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
1301 { return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); }
1302
1303 template<typename _Tp> static inline
1304 Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
1305 { return Complex<_Tp>( a.re*b, a.im*b ); }
1306
1307 template<typename _Tp> static inline
1308 Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
1309 { return Complex<_Tp>( a.re*b, a.im*b ); }
1310
1311 template<typename _Tp> static inline
1312 Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
1313 { return Complex<_Tp>( a.re + b, a.im ); }
1314
1315 template<typename _Tp> static inline
1316 Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
1317 { return Complex<_Tp>( a.re - b, a.im ); }
1318
1319 template<typename _Tp> static inline
1320 Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
1321 { return Complex<_Tp>( a.re + b, a.im ); }
1322
1323 template<typename _Tp> static inline
1324 Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
1325 { return Complex<_Tp>( b - a.re, -a.im ); }
1326
1327 template<typename _Tp> static inline
1328 Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
1329 { a.re += b; return a; }
1330
1331 template<typename _Tp> static inline
1332 Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
1333 { a.re -= b; return a; }
1334
1335 template<typename _Tp> static inline
1336 Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
1337 { a.re *= b; a.im *= b; return a; }
1338
1339 template<typename _Tp> static inline
1340 double abs(const Complex<_Tp>& a)
1341 { return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); }
1342
1343 template<typename _Tp> static inline
1344 Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
1345 {
1346 double t = 1./((double)b.re*b.re + (double)b.im*b.im);
1347 return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
1348 (_Tp)((-a.re*b.im + a.im*b.re)*t) );
1349 }
1350
1351 template<typename _Tp> static inline
1352 Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
1353 {
1354 return (a = a / b);
1355 }
1356
1357 template<typename _Tp> static inline
1358 Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
1359 {
1360 _Tp t = (_Tp)1/b;
1361 return Complex<_Tp>( a.re*t, a.im*t );
1362 }
1363
1364 template<typename _Tp> static inline
1365 Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
1366 {
1367 return Complex<_Tp>(b)/a;
1368 }
1369
1370 template<typename _Tp> static inline
1371 Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
1372 {
1373 _Tp t = (_Tp)1/b;
1374 a.re *= t; a.im *= t; return a;
1375 }
1376
1378
1379 template<typename _Tp> inline Point_<_Tp>::Point_() : x(0), y(0) {}
1380 template<typename _Tp> inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
1381 template<typename _Tp> inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {}
1382 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {}
1383 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint2D32f& pt)
1384 : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {}
1385 template<typename _Tp> inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {}
1386 template<typename _Tp> inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {}
1387 template<typename _Tp> inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
1388 { x = pt.x; y = pt.y; return *this; }
1389
1390 template<typename _Tp> template<typename _Tp2> inline Point_<_Tp>::operator Point_<_Tp2>() const
1391 { return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); }
1392 template<typename _Tp> inline Point_<_Tp>::operator CvPoint() const
1393 { return cvPoint(saturate_cast<int>(x), saturate_cast<int>(y)); }
1394 template<typename _Tp> inline Point_<_Tp>::operator CvPoint2D32f() const
1395 { return cvPoint2D32f((float)x, (float)y); }
1396 template<typename _Tp> inline Point_<_Tp>::operator Vec<_Tp, 2>() const
1397 { return Vec<_Tp, 2>(x, y); }
1398
1399 template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const
1400 { return saturate_cast<_Tp>(x*pt.x + y*pt.y); }
1401 template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const
1402 { return (double)x*pt.x + (double)y*pt.y; }
1403
1404 template<typename _Tp> static inline Point_<_Tp>&
1405 operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
1406 {
1407 a.x = saturate_cast<_Tp>(a.x + b.x);
1408 a.y = saturate_cast<_Tp>(a.y + b.y);
1409 return a;
1410 }
1411
1412 template<typename _Tp> static inline Point_<_Tp>&
1413 operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
1414 {
1415 a.x = saturate_cast<_Tp>(a.x - b.x);
1416 a.y = saturate_cast<_Tp>(a.y - b.y);
1417 return a;
1418 }
1419
1420 template<typename _Tp> static inline Point_<_Tp>&
1421 operator *= (Point_<_Tp>& a, int b)
1422 {
1423 a.x = saturate_cast<_Tp>(a.x*b);
1424 a.y = saturate_cast<_Tp>(a.y*b);
1425 return a;
1426 }
1427
1428 template<typename _Tp> static inline Point_<_Tp>&
1429 operator *= (Point_<_Tp>& a, float b)
1430 {
1431 a.x = saturate_cast<_Tp>(a.x*b);
1432 a.y = saturate_cast<_Tp>(a.y*b);
1433 return a;
1434 }
1435
1436 template<typename _Tp> static inline Point_<_Tp>&
1437 operator *= (Point_<_Tp>& a, double b)
1438 {
1439 a.x = saturate_cast<_Tp>(a.x*b);
1440 a.y = saturate_cast<_Tp>(a.y*b);
1441 return a;
1442 }
1443
1444 template<typename _Tp> static inline double norm(const Point_<_Tp>& pt)
1445 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); }
1446
1447 template<typename _Tp> static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
1448 { return a.x == b.x && a.y == b.y; }
1449
1450 template<typename _Tp> static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
1451 { return a.x != b.x || a.y != b.y; }
1452
1453 template<typename _Tp> static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
1454 { return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); }
1455
1456 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
1457 { return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); }
1458
1459 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a)
1460 { return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); }
1461
1462 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
1463 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1464
1465 template<typename _Tp> static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
1466 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1467
1468 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
1469 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1470
1471 template<typename _Tp> static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
1472 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1473
1474 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
1475 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
1476
1477 template<typename _Tp> static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
1478 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
1479
1481
1482 template<typename _Tp> inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {}
1483 template<typename _Tp> inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {}
1484 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
1485 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {}
1486 template<typename _Tp> inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) :
1487 x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {}
1488 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {}
1489
1490 template<typename _Tp> template<typename _Tp2> inline Point3_<_Tp>::operator Point3_<_Tp2>() const
1491 { return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); }
1492
1493 template<typename _Tp> inline Point3_<_Tp>::operator CvPoint3D32f() const
1494 { return cvPoint3D32f((float)x, (float)y, (float)z); }
1495
1496 template<typename _Tp> inline Point3_<_Tp>::operator Vec<_Tp, 3>() const
1497 { return Vec<_Tp, 3>(x, y, z); }
1498
1499 template<typename _Tp> inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
1500 { x = pt.x; y = pt.y; z = pt.z; return *this; }
1501
1502 template<typename _Tp> inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const
1503 { return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); }
1504 template<typename _Tp> inline double Point3_<_Tp>::ddot(const Point3_& pt) const
1505 { return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; }
1506
1507 template<typename _Tp> inline Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
1508 {
1509 return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
1510 }
1511
1512 template<typename _Tp> static inline Point3_<_Tp>&
1513 operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1514 {
1515 a.x = saturate_cast<_Tp>(a.x + b.x);
1516 a.y = saturate_cast<_Tp>(a.y + b.y);
1517 a.z = saturate_cast<_Tp>(a.z + b.z);
1518 return a;
1519 }
1520
1521 template<typename _Tp> static inline Point3_<_Tp>&
1522 operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
1523 {
1524 a.x = saturate_cast<_Tp>(a.x - b.x);
1525 a.y = saturate_cast<_Tp>(a.y - b.y);
1526 a.z = saturate_cast<_Tp>(a.z - b.z);
1527 return a;
1528 }
1529
1530 template<typename _Tp> static inline Point3_<_Tp>&
1531 operator *= (Point3_<_Tp>& a, int b)
1532 {
1533 a.x = saturate_cast<_Tp>(a.x*b);
1534 a.y = saturate_cast<_Tp>(a.y*b);
1535 a.z = saturate_cast<_Tp>(a.z*b);
1536 return a;
1537 }
1538
1539 template<typename _Tp> static inline Point3_<_Tp>&
1540 operator *= (Point3_<_Tp>& a, float b)
1541 {
1542 a.x = saturate_cast<_Tp>(a.x*b);
1543 a.y = saturate_cast<_Tp>(a.y*b);
1544 a.z = saturate_cast<_Tp>(a.z*b);
1545 return a;
1546 }
1547
1548 template<typename _Tp> static inline Point3_<_Tp>&
1549 operator *= (Point3_<_Tp>& a, double b)
1550 {
1551 a.x = saturate_cast<_Tp>(a.x*b);
1552 a.y = saturate_cast<_Tp>(a.y*b);
1553 a.z = saturate_cast<_Tp>(a.z*b);
1554 return a;
1555 }
1556
1557 template<typename _Tp> static inline double norm(const Point3_<_Tp>& pt)
1558 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); }
1559
1560 template<typename _Tp> static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1561 { return a.x == b.x && a.y == b.y && a.z == b.z; }
1562
1563 template<typename _Tp> static inline bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1564 { return a.x != b.x || a.y != b.y || a.z != b.z; }
1565
1566 template<typename _Tp> static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1567 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x),
1568 saturate_cast<_Tp>(a.y + b.y),
1569 saturate_cast<_Tp>(a.z + b.z)); }
1570
1571 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
1572 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x),
1573 saturate_cast<_Tp>(a.y - b.y),
1574 saturate_cast<_Tp>(a.z - b.z)); }
1575
1576 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a)
1577 { return Point3_<_Tp>( saturate_cast<_Tp>(-a.x),
1578 saturate_cast<_Tp>(-a.y),
1579 saturate_cast<_Tp>(-a.z) ); }
1580
1581 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
1582 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1583 saturate_cast<_Tp>(a.y*b),
1584 saturate_cast<_Tp>(a.z*b) ); }
1585
1586 template<typename _Tp> static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
1587 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1588 saturate_cast<_Tp>(b.y*a),
1589 saturate_cast<_Tp>(b.z*a) ); }
1590
1591 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
1592 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1593 saturate_cast<_Tp>(a.y*b),
1594 saturate_cast<_Tp>(a.z*b) ); }
1595
1596 template<typename _Tp> static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
1597 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1598 saturate_cast<_Tp>(b.y*a),
1599 saturate_cast<_Tp>(b.z*a) ); }
1600
1601 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
1602 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
1603 saturate_cast<_Tp>(a.y*b),
1604 saturate_cast<_Tp>(a.z*b) ); }
1605
1606 template<typename _Tp> static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
1607 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
1608 saturate_cast<_Tp>(b.y*a),
1609 saturate_cast<_Tp>(b.z*a) ); }
1610
1612
1613 template<typename _Tp> inline Size_<_Tp>::Size_()
1614 : width(0), height(0) {}
1615 template<typename _Tp> inline Size_<_Tp>::Size_(_Tp _width, _Tp _height)
1616 : width(_width), height(_height) {}
1617 template<typename _Tp> inline Size_<_Tp>::Size_(const Size_& sz)
1618 : width(sz.width), height(sz.height) {}
1619 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize& sz)
1620 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
1621 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize2D32f& sz)
1622 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
1623 template<typename _Tp> inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {}
1624
1625 template<typename _Tp> template<typename _Tp2> inline Size_<_Tp>::operator Size_<_Tp2>() const
1626 { return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
1627 template<typename _Tp> inline Size_<_Tp>::operator CvSize() const
1628 { return cvSize(saturate_cast<int>(width), saturate_cast<int>(height)); }
1629 template<typename _Tp> inline Size_<_Tp>::operator CvSize2D32f() const
1630 { return cvSize2D32f((float)width, (float)height); }
1631
1632 template<typename _Tp> inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
1633 { width = sz.width; height = sz.height; return *this; }
1634 template<typename _Tp> static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
1635 { return Size_<_Tp>(a.width * b, a.height * b); }
1636 template<typename _Tp> static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
1637 { return Size_<_Tp>(a.width + b.width, a.height + b.height); }
1638 template<typename _Tp> static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
1639 { return Size_<_Tp>(a.width - b.width, a.height - b.height); }
1640 template<typename _Tp> inline _Tp Size_<_Tp>::area() const { return width*height; }
1641
1642 template<typename _Tp> static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
1643 { a.width += b.width; a.height += b.height; return a; }
1644 template<typename _Tp> static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
1645 { a.width -= b.width; a.height -= b.height; return a; }
1646
1647 template<typename _Tp> static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
1648 { return a.width == b.width && a.height == b.height; }
1649 template<typename _Tp> static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
1650 { return a.width != b.width || a.height != b.height; }
1651
1653
1654
1655 template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {}
1656 template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {}
1657 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
1658 template<typename _Tp> inline Rect_<_Tp>::Rect_(const CvRect& r) : x((_Tp)r.x), y((_Tp)r.y), width((_Tp)r.width), height((_Tp)r.height) {}
1659 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) :
1660 x(org.x), y(org.y), width(sz.width), height(sz.height) {}
1661 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
1662 {
1663 x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y);
1664 width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y;
1665 }
1666 template<typename _Tp> inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
1667 { x = r.x; y = r.y; width = r.width; height = r.height; return *this; }
1668
1669 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); }
1670 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); }
1671
1672 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1673 { a.x += b.x; a.y += b.y; return a; }
1674 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
1675 { a.x -= b.x; a.y -= b.y; return a; }
1676
1677 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1678 { a.width += b.width; a.height += b.height; return a; }
1679
1680 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
1681 { a.width -= b.width; a.height -= b.height; return a; }
1682
1683 template<typename _Tp> static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1684 {
1685 _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
1686 a.width = std::min(a.x + a.width, b.x + b.width) - x1;
1687 a.height = std::min(a.y + a.height, b.y + b.height) - y1;
1688 a.x = x1; a.y = y1;
1689 if( a.width <= 0 || a.height <= 0 )
1690 a = Rect();
1691 return a;
1692 }
1693
1694 template<typename _Tp> static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
1695 {
1696 _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
1697 a.width = std::max(a.x + a.width, b.x + b.width) - x1;
1698 a.height = std::max(a.y + a.height, b.y + b.height) - y1;
1699 a.x = x1; a.y = y1;
1700 return a;
1701 }
1702
1703 template<typename _Tp> inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); }
1704 template<typename _Tp> inline _Tp Rect_<_Tp>::area() const { return width*height; }
1705
1706 template<typename _Tp> template<typename _Tp2> inline Rect_<_Tp>::operator Rect_<_Tp2>() const
1707 { return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y),
1708 saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
1709 template<typename _Tp> inline Rect_<_Tp>::operator CvRect() const
1710 { return cvRect(saturate_cast<int>(x), saturate_cast<int>(y),
1711 saturate_cast<int>(width), saturate_cast<int>(height)); }
1712
1713 template<typename _Tp> inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
1714 { return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; }
1715
1716 template<typename _Tp> static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1717 {
1718 return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
1719 }
1720
1721 template<typename _Tp> static inline bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1722 {
1723 return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
1724 }
1725
1726 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
1727 {
1728 return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
1729 }
1730
1731 template<typename _Tp> static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
1732 {
1733 return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
1734 }
1735
1736 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
1737 {
1738 return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
1739 }
1740
1741 template<typename _Tp> static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1742 {
1743 Rect_<_Tp> c = a;
1744 return c &= b;
1745 }
1746
1747 template<typename _Tp> static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
1748 {
1749 Rect_<_Tp> c = a;
1750 return c |= b;
1751 }
1752
1753 template<typename _Tp> inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
1754 {
1755 return r.contains(*this);
1756 }
1757
1758 inline RotatedRect::RotatedRect() { angle = 0; }
1759 inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
1760 : center(_center), size(_size), angle(_angle) {}
1761 inline RotatedRect::RotatedRect(const CvBox2D& box)
1762 : center(box.center), size(box.size), angle(box.angle) {}
1763 inline RotatedRect::operator CvBox2D() const
1764 {
1765 CvBox2D box; box.center = center; box.size = size; box.angle = angle;
1766 return box;
1767 }
1768
1770
1771 template<typename _Tp> inline Scalar_<_Tp>::Scalar_()
1772 { this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; }
1773
1774 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
1775 { this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; }
1776
1777 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(const CvScalar& s)
1778 {
1779 this->val[0] = saturate_cast<_Tp>(s.val[0]);
1780 this->val[1] = saturate_cast<_Tp>(s.val[1]);
1781 this->val[2] = saturate_cast<_Tp>(s.val[2]);
1782 this->val[3] = saturate_cast<_Tp>(s.val[3]);
1783 }
1784
1785 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0)
1786 { this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; }
1787
1788 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
1789 { return Scalar_<_Tp>(v0, v0, v0, v0); }
1790 template<typename _Tp> inline Scalar_<_Tp>::operator CvScalar() const
1791 { return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); }
1792
1793 template<typename _Tp> template<typename T2> inline Scalar_<_Tp>::operator Scalar_<T2>() const
1794 {
1795 return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
1796 saturate_cast<T2>(this->val[1]),
1797 saturate_cast<T2>(this->val[2]),
1798 saturate_cast<T2>(this->val[3]));
1799 }
1800
1801 template<typename _Tp> static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1802 {
1803 a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]);
1804 a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]);
1805 a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]);
1806 a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]);
1807 return a;
1808 }
1809
1810 template<typename _Tp> static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1811 {
1812 a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]);
1813 a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]);
1814 a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]);
1815 a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]);
1816 return a;
1817 }
1818
1819 template<typename _Tp> static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
1820 {
1821 a.val[0] = saturate_cast<_Tp>(a.val[0] * v);
1822 a.val[1] = saturate_cast<_Tp>(a.val[1] * v);
1823 a.val[2] = saturate_cast<_Tp>(a.val[2] * v);
1824 a.val[3] = saturate_cast<_Tp>(a.val[3] * v);
1825 return a;
1826 }
1827
1828 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const
1829 {
1830 return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale),
1831 saturate_cast<_Tp>(this->val[1]*t.val[1]*scale),
1832 saturate_cast<_Tp>(this->val[2]*t.val[2]*scale),
1833 saturate_cast<_Tp>(this->val[3]*t.val[3]*scale));
1834 }
1835
1836 template<typename _Tp> static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
1837 {
1838 return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
1839 a.val[2] == b.val[2] && a.val[3] == b.val[3];
1840 }
1841
1842 template<typename _Tp> static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
1843 {
1844 return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
1845 a.val[2] != b.val[2] || a.val[3] != b.val[3];
1846 }
1847
1848 template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1849 {
1850 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]),
1851 saturate_cast<_Tp>(a.val[1] + b.val[1]),
1852 saturate_cast<_Tp>(a.val[2] + b.val[2]),
1853 saturate_cast<_Tp>(a.val[3] + b.val[3]));
1854 }
1855
1856 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1857 {
1858 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
1859 saturate_cast<_Tp>(a.val[1] - b.val[1]),
1860 saturate_cast<_Tp>(a.val[2] - b.val[2]),
1861 saturate_cast<_Tp>(a.val[3] - b.val[3]));
1862 }
1863
1864 template<typename _Tp> static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
1865 {
1866 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha),
1867 saturate_cast<_Tp>(a.val[1] * alpha),
1868 saturate_cast<_Tp>(a.val[2] * alpha),
1869 saturate_cast<_Tp>(a.val[3] * alpha));
1870 }
1871
1872 template<typename _Tp> static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
1873 {
1874 return a*alpha;
1875 }
1876
1877 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
1878 {
1879 return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]),
1880 saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3]));
1881 }
1882
1883
1884 template<typename _Tp> static inline Scalar_<_Tp>
1885 operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1886 {
1887 return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
1888 saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
1889 saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]),
1890 saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0]));
1891 }
1892
1893 template<typename _Tp> static inline Scalar_<_Tp>&
1894 operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1895 {
1896 a = a*b;
1897 return a;
1898 }
1899
1900 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::conj() const
1901 {
1902 return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0]),
1903 saturate_cast<_Tp>(-this->val[1]),
1904 saturate_cast<_Tp>(-this->val[2]),
1905 saturate_cast<_Tp>(-this->val[3]));
1906 }
1907
1908 template<typename _Tp> inline bool Scalar_<_Tp>::isReal() const
1909 {
1910 return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
1911 }
1912
1913 template<typename _Tp> static inline
1914 Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
1915 {
1916 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] / alpha),
1917 saturate_cast<_Tp>(a.val[1] / alpha),
1918 saturate_cast<_Tp>(a.val[2] / alpha),
1919 saturate_cast<_Tp>(a.val[3] / alpha));
1920 }
1921
1922 template<typename _Tp> static inline
1923 Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
1924 {
1925 float s = 1/alpha;
1926 return Scalar_<float>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
1927 }
1928
1929 template<typename _Tp> static inline
1930 Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
1931 {
1932 double s = 1/alpha;
1933 return Scalar_<double>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
1934 }
1935
1936 template<typename _Tp> static inline
1937 Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
1938 {
1939 a = a/alpha;
1940 return a;
1941 }
1942
1943 template<typename _Tp> static inline
1944 Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
1945 {
1946 _Tp s = a/(b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
1947 return b.conj()*s;
1948 }
1949
1950 template<typename _Tp> static inline
1951 Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1952 {
1953 return a*((_Tp)1/b);
1954 }
1955
1956 template<typename _Tp> static inline
1957 Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
1958 {
1959 a = a/b;
1960 return a;
1961 }
1962
1964
1965 inline Range::Range() : start(0), end(0) {}
1966 inline Range::Range(int _start, int _end) : start(_start), end(_end) {}
1967 inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index)
1968 {
1969 if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX )
1970 *this = Range::all();
1971 }
1972
1973 inline int Range::size() const { return end - start; }
1974 inline bool Range::empty() const { return start == end; }
1975 inline Range Range::all() { return Range(INT_MIN, INT_MAX); }
1976
1977 static inline bool operator == (const Range& r1, const Range& r2)
1978 { return r1.start == r2.start && r1.end == r2.end; }
1979
1980 static inline bool operator != (const Range& r1, const Range& r2)
1981 { return !(r1 == r2); }
1982
1983 static inline bool operator !(const Range& r)
1984 { return r.start == r.end; }
1985
1986 static inline Range operator & (const Range& r1, const Range& r2)
1987 {
1988 Range r(std::max(r1.start, r2.start), std::min(r2.start, r2.end));
1989 r.end = std::max(r.end, r.start);
1990 return r;
1991 }
1992
1993 static inline Range& operator &= (Range& r1, const Range& r2)
1994 {
1995 r1 = r1 & r2;
1996 return r1;
1997 }
1998
1999 static inline Range operator + (const Range& r1, int delta)
2000 {
2001 return Range(r1.start + delta, r1.end + delta);
2002 }
2003
2004 static inline Range operator + (int delta, const Range& r1)
2005 {
2006 return Range(r1.start + delta, r1.end + delta);
2007 }
2008
2009 static inline Range operator - (const Range& r1, int delta)
2010 {
2011 return r1 + (-delta);
2012 }
2013
2014 inline Range::operator CvSlice() const
2015 { return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; }
2016
2017
2018
2020
2021 // template vector class. It is similar to STL's vector,
2022 // with a few important differences:
2023 // 1) it can be created on top of user-allocated data w/o copying it
2024 // 2) vector b = a means copying the header,
2025 // not the underlying data (use clone() to make a deep copy)
2026 template <typename _Tp> class CV_EXPORTS Vector
2027 {
2028 public:
2029 typedef _Tp value_type;
2030 typedef _Tp* iterator;
2031 typedef const _Tp* const_iterator;
2032 typedef _Tp& reference;
2033 typedef const _Tp& const_reference;
2034
2035 struct CV_EXPORTS Hdr
2036 {
2037 Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
2038 _Tp* data;
2039 _Tp* datastart;
2040 int* refcount;
2041 size_t size;
2042 size_t capacity;
2043 };
2044
2045 Vector() {}
2046 Vector(size_t _size) { resize(_size); }
2047 Vector(size_t _size, const _Tp& val)
2048 {
2049 resize(_size);
2050 for(size_t i = 0; i < _size; i++)
2051 hdr.data[i] = val;
2052 }
2053 Vector(_Tp* _data, size_t _size, bool _copyData=false)
2054 { set(_data, _size, _copyData); }
2055
2056 template<int n> Vector(const Vec<_Tp, n>& vec)
2057 { set((_Tp*)&vec.val[0], n, true); }
2058
2059 Vector(const std::vector<_Tp>& vec, bool _copyData=false)
2060 { set((_Tp*)&vec[0], vec.size(), _copyData); }
2061
2062 Vector(const Vector& d) { *this = d; }
2063
2064 Vector(const Vector& d, const Range& r_)
2065 {
2066 Range r = r_ == Range::all() ? Range(0, d.size()) : r_;
2067 /*if( r == Range::all() )
2068 r = Range(0, d.size());*/
2069 if( r.size() > 0 && r.start >= 0 && r.end <= d.size() )
2070 {
2071 if( d.hdr.refcount )
2072 CV_XADD(d.hdr.refcount, 1);
2073 hdr.refcount = d.hdr.refcount;
2074 hdr.datastart = d.hdr.datastart;
2075 hdr.data = d.hdr.data + r.start;
2076 hdr.capacity = hdr.size = r.size();
2077 }
2078 }
2079
2080 Vector<_Tp>& operator = (const Vector& d)
2081 {
2082 if( this != &d )
2083 {
2084 if( d.hdr.refcount )
2085 CV_XADD(d.hdr.refcount, 1);
2086 release();
2087 hdr = d.hdr;
2088 }
2089 return *this;
2090 }
2091
2092 ~Vector() { release(); }
2093
2094 Vector<_Tp> clone() const
2095 { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); }
2096
2097 void copyTo(Vector<_Tp>& vec) const
2098 {
2099 size_t i, sz = size();
2100 vec.resize(sz);
2101 const _Tp* src = hdr.data;
2102 _Tp* dst = vec.hdr.data;
2103 for( i = 0; i < sz; i++ )
2104 dst[i] = src[i];
2105 }
2106
2107 void copyTo(std::vector<_Tp>& vec) const
2108 {
2109 size_t i, sz = size();
2110 vec.resize(sz);
2111 const _Tp* src = hdr.data;
2112 _Tp* dst = sz ? &vec[0] : 0;
2113 for( i = 0; i < sz; i++ )
2114 dst[i] = src[i];
2115 }
2116
2117 operator CvMat() const
2118 { return cvMat((int)size(), 1, type(), (void*)hdr.data); }
2119
2120 _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; }
2121 const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; }
2122 Vector operator() (const Range& r) const { return Vector(*this, r); }
2123 _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
2124 const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
2125 _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; }
2126 const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; }
2127
2128 _Tp* begin() { return hdr.data; }
2129 _Tp* end() { return hdr.data + hdr.size; }
2130 const _Tp* begin() const { return hdr.data; }
2131 const _Tp* end() const { return hdr.data + hdr.size; }
2132
2133 void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); }
2134 void release()
2135 {
2136 if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 )
2137 {
2138 delete[] hdr.datastart;
2139 delete hdr.refcount;
2140 }
2141 hdr = Hdr();
2142 }
2143
2144 void set(_Tp* _data, size_t _size, bool _copyData=false)
2145 {
2146 if( !_copyData )
2147 {
2148 release();
2149 hdr.data = hdr.datastart = _data;
2150 hdr.size = hdr.capacity = _size;
2151 hdr.refcount = 0;
2152 }
2153 else
2154 {
2155 reserve(_size);
2156 for( size_t i = 0; i < _size; i++ )
2157 hdr.data[i] = _data[i];
2158 hdr.size = _size;
2159 }
2160 }
2161
2162 void reserve(size_t newCapacity)
2163 {
2164 _Tp* newData;
2165 int* newRefcount;
2166 size_t i, oldSize = hdr.size;
2167 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity )
2168 return;
2169 newCapacity = std::max(newCapacity, oldSize);
2170 newData = new _Tp[newCapacity];
2171 newRefcount = new int(1);
2172 for( i = 0; i < oldSize; i++ )
2173 newData[i] = hdr.data[i];
2174 release();
2175 hdr.data = hdr.datastart = newData;
2176 hdr.capacity = newCapacity;
2177 hdr.size = oldSize;
2178 hdr.refcount = newRefcount;
2179 }
2180
2181 void resize(size_t newSize)
2182 {
2183 size_t i;
2184 newSize = std::max(newSize, (size_t)0);
2185 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize )
2186 return;
2187 if( newSize > hdr.capacity )
2188 reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2)));
2189 for( i = hdr.size; i < newSize; i++ )
2190 hdr.data[i] = _Tp();
2191 hdr.size = newSize;
2192 }
2193
2194 Vector<_Tp>& push_back(const _Tp& elem)
2195 {
2196 if( hdr.size == hdr.capacity )
2197 reserve( std::max((size_t)4, hdr.capacity*2) );
2198 hdr.data[hdr.size++] = elem;
2199 return *this;
2200 }
2201
2202 Vector<_Tp>& pop_back()
2203 {
2204 if( hdr.size > 0 )
2205 --hdr.size;
2206 return *this;
2207 }
2208
2209 size_t size() const { return hdr.size; }
2210 size_t capacity() const { return hdr.capacity; }
2211 bool empty() const { return hdr.size == 0; }
2212 void clear() { resize(0); }
2213 int type() const { return DataType<_Tp>::type; }
2214
2215 protected:
2216 Hdr hdr;
2217 };
2218
2219
2220 template<typename _Tp> inline typename DataType<_Tp>::work_type
2221 dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2)
2222 {
2223 typedef typename DataType<_Tp>::work_type _Tw;
2224 size_t i, n = v1.size();
2225 assert(v1.size() == v2.size());
2226
2227 _Tw s = 0;
2228 const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0];
2229 for( i = 0; i <= n - 4; i += 4 )
2230 s += (_Tw)ptr1[i]*ptr2[i] + (_Tw)ptr1[i+1]*ptr2[i+1] +
2231 (_Tw)ptr1[i+2]*ptr2[i+2] + (_Tw)ptr1[i+3]*ptr2[i+3];
2232 for( ; i < n; i++ )
2233 s += (_Tw)ptr1[i]*ptr2[i];
2234 return s;
2235 }
2236
2237 // Multiply-with-Carry RNG
2238 inline RNG::RNG() { state = 0xffffffff; }
2239 inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
2240 inline unsigned RNG::next()
2241 {
2242 state = (uint64)(unsigned)state*A + (unsigned)(state >> 32);
2243 return (unsigned)state;
2244 }
2245
2246 inline RNG::operator uchar() { return (uchar)next(); }
2247 inline RNG::operator schar() { return (schar)next(); }
2248 inline RNG::operator ushort() { return (ushort)next(); }
2249 inline RNG::operator short() { return (short)next(); }
2250 inline RNG::operator unsigned() { return next(); }
2251 inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);}
2252 inline unsigned RNG::operator ()() {return next();}
2253 inline RNG::operator int() { return (int)next(); }
2254 // * (2^32-1)^-1
2255 inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
2256 inline RNG::operator double()
2257 {
2258 unsigned t = next();
2259 return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20;
2260 }
2261 inline int RNG::uniform(int a, int b) { return a == b ? a : next()%(b - a) + a; }
2262 inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
2263 inline double RNG::uniform(double a, double b) { return ((float)*this)*(b - a) + a; }
2264
2265 inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {}
2266 inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
2267 : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
2268 inline TermCriteria::TermCriteria(const CvTermCriteria& criteria)
2269 : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {}
2270 inline TermCriteria::operator CvTermCriteria() const
2271 { return cvTermCriteria(type, maxCount, epsilon); }
2272
2273 inline uchar* LineIterator::operator *() { return ptr; }
2274 inline LineIterator& LineIterator::operator ++()
2275 {
2276 int mask = err < 0 ? -1 : 0;
2277 err += minusDelta + (plusDelta & mask);
2278 ptr += minusStep + (plusStep & mask);
2279 return *this;
2280 }
2281 inline LineIterator LineIterator::operator ++(int)
2282 {
2283 LineIterator it = *this;
2284 ++(*this);
2285 return it;
2286 }
2287 inline Point LineIterator::pos() const
2288 {
2289 Point p;
2290 p.y = (int)((ptr - ptr0)/step);
2291 p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize);
2292 return p;
2293 }
2294
2296
2297 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
2298 : ptr(buf), size(fixed_size) {}
2299
2300 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
2301 : ptr(buf), size(fixed_size) { allocate(_size); }
2302
2303 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
2304 { deallocate(); }
2305
2306 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
2307 {
2308 if(_size <= size)
2309 return;
2310 deallocate();
2311 if(_size > fixed_size)
2312 {
2313 ptr = cv::allocate<_Tp>(_size);
2314 size = _size;
2315 }
2316 }
2317
2318 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
2319 {
2320 if( ptr != buf )
2321 {
2322 cv::deallocate<_Tp>(ptr, size);
2323 ptr = buf;
2324 size = fixed_size;
2325 }
2326 }
2327
2328 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
2329 { return ptr; }
2330
2331 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
2332 { return ptr; }
2333
2334
2336
2337 template<typename _Tp> inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {}
2338 template<typename _Tp> inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj)
2339 {
2340 if(obj)
2341 {
2342 refcount = (int*)fastMalloc(sizeof(*refcount));
2343 *refcount = 1;
2344 }
2345 else
2346 refcount = 0;
2347 }
2348
2349 template<typename _Tp> inline void Ptr<_Tp>::addref()
2350 { if( refcount ) CV_XADD(refcount, 1); }
2351
2352 template<typename _Tp> inline void Ptr<_Tp>::release()
2353 {
2354 if( refcount && CV_XADD(refcount, -1) == 1 )
2355 {
2356 delete_obj();
2357 fastFree(refcount);
2358 }
2359 refcount = 0;
2360 obj = 0;
2361 }
2362
2363 template<typename _Tp> inline void Ptr<_Tp>::delete_obj()
2364 {
2365 if( obj ) delete obj;
2366 }
2367
2368 template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); }
2369
2370 template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr)
2371 {
2372 obj = ptr.obj;
2373 refcount = ptr.refcount;
2374 addref();
2375 }
2376
2377 template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr)
2378 {
2379 int* _refcount = ptr.refcount;
2380 if( _refcount )
2381 CV_XADD(_refcount, 1);
2382 release();
2383 obj = ptr.obj;
2384 refcount = _refcount;
2385 return *this;
2386 }
2387
2388 template<typename _Tp> inline _Tp* Ptr<_Tp>::operator -> () { return obj; }
2389 template<typename _Tp> inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; }
2390
2391 template<typename _Tp> inline Ptr<_Tp>::operator _Tp* () { return obj; }
2392 template<typename _Tp> inline Ptr<_Tp>::operator const _Tp*() const { return obj; }
2393
2394 template<typename _Tp> inline bool Ptr<_Tp>::empty() const { return obj == 0; }
2395
2397
2398 template<> CV_EXPORTS void Ptr<CvMat>::delete_obj();
2399 template<> CV_EXPORTS void Ptr<IplImage>::delete_obj();
2400 template<> CV_EXPORTS void Ptr<CvMatND>::delete_obj();
2401 template<> CV_EXPORTS void Ptr<CvSparseMat>::delete_obj();
2402 template<> CV_EXPORTS void Ptr<CvMemStorage>::delete_obj();
2403 template<> CV_EXPORTS void Ptr<CvFileStorage>::delete_obj();
2404
2406
2407 CV_EXPORTS_W void write( FileStorage& fs, const string& name, int value );
2408 CV_EXPORTS_W void write( FileStorage& fs, const string& name, float value );
2409 CV_EXPORTS_W void write( FileStorage& fs, const string& name, double value );
2410 CV_EXPORTS_W void write( FileStorage& fs, const string& name, const string& value );
2411
2412 template<typename _Tp> inline void write(FileStorage& fs, const _Tp& value)
2413 { write(fs, string(), value); }
2414
2415 CV_EXPORTS void writeScalar( FileStorage& fs, int value );
2416 CV_EXPORTS void writeScalar( FileStorage& fs, float value );
2417 CV_EXPORTS void writeScalar( FileStorage& fs, double value );
2418 CV_EXPORTS void writeScalar( FileStorage& fs, const string& value );
2419
2420 template<> inline void write( FileStorage& fs, const int& value )
2421 {
2422 writeScalar(fs, value);
2423 }
2424
2425 template<> inline void write( FileStorage& fs, const float& value )
2426 {
2427 writeScalar(fs, value);
2428 }
2429
2430 template<> inline void write( FileStorage& fs, const double& value )
2431 {
2432 writeScalar(fs, value);
2433 }
2434
2435 template<> inline void write( FileStorage& fs, const string& value )
2436 {
2437 writeScalar(fs, value);
2438 }
2439
2440 template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt )
2441 {
2442 write(fs, pt.x);
2443 write(fs, pt.y);
2444 }
2445
2446 template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt )
2447 {
2448 write(fs, pt.x);
2449 write(fs, pt.y);
2450 write(fs, pt.z);
2451 }
2452
2453 template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz )
2454 {
2455 write(fs, sz.width);
2456 write(fs, sz.height);
2457 }
2458
2459 template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c )
2460 {
2461 write(fs, c.re);
2462 write(fs, c.im);
2463 }
2464
2465 template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r )
2466 {
2467 write(fs, r.x);
2468 write(fs, r.y);
2469 write(fs, r.width);
2470 write(fs, r.height);
2471 }
2472
2473 template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v )
2474 {
2475 for(int i = 0; i < cn; i++)
2476 write(fs, v.val[i]);
2477 }
2478
2479 template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s )
2480 {
2481 write(fs, s.val[0]);
2482 write(fs, s.val[1]);
2483 write(fs, s.val[2]);
2484 write(fs, s.val[3]);
2485 }
2486
2487 inline void write(FileStorage& fs, const Range& r )
2488 {
2489 write(fs, r.start);
2490 write(fs, r.end);
2491 }
2492
2493 class CV_EXPORTS WriteStructContext
2494 {
2495 public:
2496 WriteStructContext(FileStorage& _fs, const string& name,
2497 int flags, const string& typeName=string());
2498 ~WriteStructContext();
2499 FileStorage* fs;
2500 };
2501
2502 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt )
2503 {
2504 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2505 write(fs, pt.x);
2506 write(fs, pt.y);
2507 }
2508
2509 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt )
2510 {
2511 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2512 write(fs, pt.x);
2513 write(fs, pt.y);
2514 write(fs, pt.z);
2515 }
2516
2517 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz )
2518 {
2519 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2520 write(fs, sz.width);
2521 write(fs, sz.height);
2522 }
2523
2524 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c )
2525 {
2526 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2527 write(fs, c.re);
2528 write(fs, c.im);
2529 }
2530
2531 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r )
2532 {
2533 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2534 write(fs, r.x);
2535 write(fs, r.y);
2536 write(fs, r.width);
2537 write(fs, r.height);
2538 }
2539
2540 template<typename _Tp, int cn> inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v )
2541 {
2542 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2543 for(int i = 0; i < cn; i++)
2544 write(fs, v.val[i]);
2545 }
2546
2547 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s )
2548 {
2549 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2550 write(fs, s.val[0]);
2551 write(fs, s.val[1]);
2552 write(fs, s.val[2]);
2553 write(fs, s.val[3]);
2554 }
2555
2556 inline void write(FileStorage& fs, const string& name, const Range& r )
2557 {
2558 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
2559 write(fs, r.start);
2560 write(fs, r.end);
2561 }
2562
2563 template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy
2564 {
2565 public:
2566 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
2567 void operator()(const vector<_Tp>& vec) const
2568 {
2569 size_t i, count = vec.size();
2570 for( i = 0; i < count; i++ )
2571 write( *fs, vec[i] );
2572 }
2573 FileStorage* fs;
2574 };
2575
2576 template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1>
2577 {
2578 public:
2579 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
2580 void operator()(const vector<_Tp>& vec) const
2581 {
2582 int _fmt = DataType<_Tp>::fmt;
2583 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
2584 fs->writeRaw( string(fmt), (uchar*)&vec[0], vec.size()*sizeof(_Tp) );
2585 }
2586 FileStorage* fs;
2587 };
2588
2589
2590 template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec )
2591 {
2592 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
2593 w(vec);
2594 }
2595
2596 template<typename _Tp> static inline FileStorage&
2597 operator << ( FileStorage& fs, const vector<_Tp>& vec )
2598 {
2599 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
2600 w(vec);
2601 return fs;
2602 }
2603
2604 CV_EXPORTS_W void write( FileStorage& fs, const string& name, const Mat& value );
2605 CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value );
2606
2607 template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
2608 {
2609 if( !fs.isOpened() )
2610 return fs;
2611 if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
2612 CV_Error( CV_StsError, "No element name has been given" );
2613 write( fs, fs.elname, value );
2614 if( fs.state & FileStorage::INSIDE_MAP )
2615 fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
2616 return fs;
2617 }
2618
2619 CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str);
2620
2621 static inline FileStorage& operator << (FileStorage& fs, const char* str)
2622 { return (fs << string(str)); }
2623
2624 inline FileNode::FileNode() : fs(0), node(0) {}
2625 inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
2626 : fs(_fs), node(_node) {}
2627
2628 inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
2629
2630 inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
2631 inline bool FileNode::empty() const { return node == 0; }
2632 inline bool FileNode::isNone() const { return type() == NONE; }
2633 inline bool FileNode::isSeq() const { return type() == SEQ; }
2634 inline bool FileNode::isMap() const { return type() == MAP; }
2635 inline bool FileNode::isInt() const { return type() == INT; }
2636 inline bool FileNode::isReal() const { return type() == REAL; }
2637 inline bool FileNode::isString() const { return type() == STR; }
2638 inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
2639 inline size_t FileNode::size() const
2640 {
2641 int t = type();
2642 return t == MAP ? ((CvSet*)node->data.map)->active_count :
2643 t == SEQ ? node->data.seq->total : node != 0;
2644 }
2645
2646 inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
2647 inline const CvFileNode* FileNode::operator* () const { return node; }
2648
2649 static inline void read(const FileNode& node, int& value, int default_value)
2650 {
2651 value = !node.node ? default_value :
2652 CV_NODE_IS_INT(node.node->tag) ? node.node->data.i :
2653 CV_NODE_IS_REAL(node.node->tag) ? cvRound(node.node->data.f) : 0x7fffffff;
2654 }
2655
2656 static inline void read(const FileNode& node, bool& value, bool default_value)
2657 {
2658 int temp; read(node, temp, (int)default_value);
2659 value = temp != 0;
2660 }
2661
2662 static inline void read(const FileNode& node, uchar& value, uchar default_value)
2663 {
2664 int temp; read(node, temp, (int)default_value);
2665 value = saturate_cast<uchar>(temp);
2666 }
2667
2668 static inline void read(const FileNode& node, schar& value, schar default_value)
2669 {
2670 int temp; read(node, temp, (int)default_value);
2671 value = saturate_cast<schar>(temp);
2672 }
2673
2674 static inline void read(const FileNode& node, ushort& value, ushort default_value)
2675 {
2676 int temp; read(node, temp, (int)default_value);
2677 value = saturate_cast<ushort>(temp);
2678 }
2679
2680 static inline void read(const FileNode& node, short& value, short default_value)
2681 {
2682 int temp; read(node, temp, (int)default_value);
2683 value = saturate_cast<short>(temp);
2684 }
2685
2686 static inline void read(const FileNode& node, float& value, float default_value)
2687 {
2688 value = !node.node ? default_value :
2689 CV_NODE_IS_INT(node.node->tag) ? (float)node.node->data.i :
2690 CV_NODE_IS_REAL(node.node->tag) ? (float)node.node->data.f : 1e30f;
2691 }
2692
2693 static inline void read(const FileNode& node, double& value, double default_value)
2694 {
2695 value = !node.node ? default_value :
2696 CV_NODE_IS_INT(node.node->tag) ? (double)node.node->data.i :
2697 CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : 1e300;
2698 }
2699
2700 static inline void read(const FileNode& node, string& value, const string& default_value)
2701 {
2702 value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? string(node.node->data.str.ptr) : string("");
2703 }
2704
2705 CV_EXPORTS_W void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
2706 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
2707
2708 inline FileNode::operator int() const
2709 {
2710 int value;
2711 read(*this, value, 0);
2712 return value;
2713 }
2714 inline FileNode::operator float() const
2715 {
2716 float value;
2717 read(*this, value, 0.f);
2718 return value;
2719 }
2720 inline FileNode::operator double() const
2721 {
2722 double value;
2723 read(*this, value, 0.);
2724 return value;
2725 }
2726 inline FileNode::operator string() const
2727 {
2728 string value;
2729 read(*this, value, value);
2730 return value;
2731 }
2732
2733 inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const
2734 {
2735 begin().readRaw( fmt, vec, len );
2736 }
2737
2738 template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy
2739 {
2740 public:
2741 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
2742 void operator()(vector<_Tp>& vec, size_t count) const
2743 {
2744 count = std::min(count, it->remaining);
2745 vec.resize(count);
2746 for( size_t i = 0; i < count; i++, ++(*it) )
2747 read(**it, vec[i], _Tp());
2748 }
2749 FileNodeIterator* it;
2750 };
2751
2752 template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1>
2753 {
2754 public:
2755 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
2756 void operator()(vector<_Tp>& vec, size_t count) const
2757 {
2758 size_t remaining = it->remaining, cn = DataType<_Tp>::channels;
2759 int _fmt = DataType<_Tp>::fmt;
2760 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
2761 count = std::min(count, remaining/cn);
2762 vec.resize(count);
2763 it->readRaw( string(fmt), (uchar*)&vec[0], count*sizeof(_Tp) );
2764 }
2765 FileNodeIterator* it;
2766 };
2767
2768 template<typename _Tp> static inline void
2769 read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
2770 {
2771 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
2772 r(vec, maxCount);
2773 }
2774
2775 template<typename _Tp> static inline void
2776 read( FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() )
2777 {
2778 read( node.begin(), vec );
2779 }
2780
2781 inline FileNodeIterator FileNode::begin() const
2782 {
2783 return FileNodeIterator(fs, node);
2784 }
2785
2786 inline FileNodeIterator FileNode::end() const
2787 {
2788 return FileNodeIterator(fs, node, size());
2789 }
2790
2791 inline FileNode FileNodeIterator::operator *() const
2792 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
2793
2794 inline FileNode FileNodeIterator::operator ->() const
2795 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
2796
2797 template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
2798 { read( *it, value, _Tp()); return ++it; }
2799
2800 template<typename _Tp> static inline
2801 FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec)
2802 {
2803 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
2804 r(vec, (size_t)INT_MAX);
2805 return it;
2806 }
2807
2808 template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value)
2809 { FileNodeIterator it = n.begin(); it >> value; }
2810
2811 static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
2812 {
2813 return it1.fs == it2.fs && it1.container == it2.container &&
2814 it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
2815 }
2816
2817 static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
2818 {
2819 return !(it1 == it2);
2820 }
2821
2822 static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
2823 {
2824 return it2.remaining - it1.remaining;
2825 }
2826
2827 static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
2828 {
2829 return it1.remaining > it2.remaining;
2830 }
2831
2832 inline FileNode FileStorage::getFirstTopLevelNode() const
2833 {
2834 FileNode r = root();
2835 FileNodeIterator it = r.begin();
2836 return it != r.end() ? *it : FileNode();
2837 }
2838
2840
2841 template<typename _Tp> static inline _Tp gcd(_Tp a, _Tp b)
2842 {
2843 if( a < b )
2844 std::swap(a, b);
2845 while( b > 0 )
2846 {
2847 _Tp r = a % b;
2848 a = b;
2849 b = r;
2850 }
2851 return a;
2852 }
2853
2854 /****************************************************************************************\
2855
2856 Generic implementation of QuickSort algorithm
2857 Use it as: vector<_Tp> a; ... sort(a,<less_than_predictor>);
2858
2859 The current implementation was derived from *BSD system qsort():
2860
2861 * Copyright (c) 1992, 1993
2862 * The Regents of the University of California. All rights reserved.
2863 *
2864 * Redistribution and use in source and binary forms, with or without
2865 * modification, are permitted provided that the following conditions
2866 * are met:
2867 * 1. Redistributions of source code must retain the above copyright
2868 * notice, this list of conditions and the following disclaimer.
2869 * 2. Redistributions in binary form must reproduce the above copyright
2870 * notice, this list of conditions and the following disclaimer in the
2871 * documentation and/or other materials provided with the distribution.
2872 * 3. All advertising materials mentioning features or use of this software
2873 * must display the following acknowledgement:
2874 * This product includes software developed by the University of
2875 * California, Berkeley and its contributors.
2876 * 4. Neither the name of the University nor the names of its contributors
2877 * may be used to endorse or promote products derived from this software
2878 * without specific prior written permission.
2879 *
2880 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2881 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2882 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2883 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2884 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2885 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2886 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2887 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2888 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2889 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2890 * SUCH DAMAGE.
2891
2892 \****************************************************************************************/
2893
2894 template<typename _Tp, class _LT> void sort( vector<_Tp>& vec, _LT LT=_LT() )
2895 {
2896 int isort_thresh = 7;
2897 int sp = 0;
2898
2899 struct
2900 {
2901 _Tp *lb;
2902 _Tp *ub;
2903 } stack[48];
2904
2905 size_t total = vec.size();
2906
2907 if( total <= 1 )
2908 return;
2909
2910 _Tp* arr = &vec[0];
2911 stack[0].lb = arr;
2912 stack[0].ub = arr + (total - 1);
2913
2914 while( sp >= 0 )
2915 {
2916 _Tp* left = stack[sp].lb;
2917 _Tp* right = stack[sp--].ub;
2918
2919 for(;;)
2920 {
2921 int i, n = (int)(right - left) + 1, m;
2922 _Tp* ptr;
2923 _Tp* ptr2;
2924
2925 if( n <= isort_thresh )
2926 {
2927 insert_sort:
2928 for( ptr = left + 1; ptr <= right; ptr++ )
2929 {
2930 for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)
2931 std::swap( ptr2[0], ptr2[-1] );
2932 }
2933 break;
2934 }
2935 else
2936 {
2937 _Tp* left0;
2938 _Tp* left1;
2939 _Tp* right0;
2940 _Tp* right1;
2941 _Tp* pivot;
2942 _Tp* a;
2943 _Tp* b;
2944 _Tp* c;
2945 int swap_cnt = 0;
2946
2947 left0 = left;
2948 right0 = right;
2949 pivot = left + (n/2);
2950
2951 if( n > 40 )
2952 {
2953 int d = n / 8;
2954 a = left, b = left + d, c = left + 2*d;
2955 left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2956 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2957
2958 a = pivot - d, b = pivot, c = pivot + d;
2959 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2960 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2961
2962 a = right - 2*d, b = right - d, c = right;
2963 right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2964 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2965 }
2966
2967 a = left, b = pivot, c = right;
2968 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
2969 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
2970 if( pivot != left0 )
2971 {
2972 std::swap( *pivot, *left0 );
2973 pivot = left0;
2974 }
2975 left = left1 = left0 + 1;
2976 right = right1 = right0;
2977
2978 for(;;)
2979 {
2980 while( left <= right && !LT(*pivot, *left) )
2981 {
2982 if( !LT(*left, *pivot) )
2983 {
2984 if( left > left1 )
2985 std::swap( *left1, *left );
2986 swap_cnt = 1;
2987 left1++;
2988 }
2989 left++;
2990 }
2991
2992 while( left <= right && !LT(*right, *pivot) )
2993 {
2994 if( !LT(*pivot, *right) )
2995 {
2996 if( right < right1 )
2997 std::swap( *right1, *right );
2998 swap_cnt = 1;
2999 right1--;
3000 }
3001 right--;
3002 }
3003
3004 if( left > right )
3005 break;
3006 std::swap( *left, *right );
3007 swap_cnt = 1;
3008 left++;
3009 right--;
3010 }
3011
3012 if( swap_cnt == 0 )
3013 {
3014 left = left0, right = right0;
3015 goto insert_sort;
3016 }
3017
3018 n = std::min( (int)(left1 - left0), (int)(left - left1) );
3019 for( i = 0; i < n; i++ )
3020 std::swap( left0[i], left[i-n] );
3021
3022 n = std::min( (int)(right0 - right1), (int)(right1 - right) );
3023 for( i = 0; i < n; i++ )
3024 std::swap( left[i], right0[i-n+1] );
3025 n = (int)(left - left1);
3026 m = (int)(right1 - right);
3027 if( n > 1 )
3028 {
3029 if( m > 1 )
3030 {
3031 if( n > m )
3032 {
3033 stack[++sp].lb = left0;
3034 stack[sp].ub = left0 + n - 1;
3035 left = right0 - m + 1, right = right0;
3036 }
3037 else
3038 {
3039 stack[++sp].lb = right0 - m + 1;
3040 stack[sp].ub = right0;
3041 left = left0, right = left0 + n - 1;
3042 }
3043 }
3044 else
3045 left = left0, right = left0 + n - 1;
3046 }
3047 else if( m > 1 )
3048 left = right0 - m + 1, right = right0;
3049 else
3050 break;
3051 }
3052 }
3053 }
3054 }
3055
3056 template<typename _Tp> class CV_EXPORTS LessThan
3057 {
3058 public:
3059 bool operator()(const _Tp& a, const _Tp& b) const { return a < b; }
3060 };
3061
3062 template<typename _Tp> class CV_EXPORTS GreaterEq
3063 {
3064 public:
3065 bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; }
3066 };
3067
3068 template<typename _Tp> class CV_EXPORTS LessThanIdx
3069 {
3070 public:
3071 LessThanIdx( const _Tp* _arr ) : arr(_arr) {}
3072 bool operator()(int a, int b) const { return arr[a] < arr[b]; }
3073 const _Tp* arr;
3074 };
3075
3076 template<typename _Tp> class CV_EXPORTS GreaterEqIdx
3077 {
3078 public:
3079 GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {}
3080 bool operator()(int a, int b) const { return arr[a] >= arr[b]; }
3081 const _Tp* arr;
3082 };
3083
3084
3085 // This function splits the input sequence or set into one or more equivalence classes and
3086 // returns the vector of labels - 0-based class indexes for each element.
3087 // predicate(a,b) returns true if the two sequence elements certainly belong to the same class.
3088 //
3089 // The algorithm is described in "Introduction to Algorithms"
3090 // by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets"
3091 template<typename _Tp, class _EqPredicate> int
3092 partition( const vector<_Tp>& _vec, vector<int>& labels,
3093 _EqPredicate predicate=_EqPredicate())
3094 {
3095 int i, j, N = (int)_vec.size();
3096 const _Tp* vec = &_vec[0];
3097
3098 const int PARENT=0;
3099 const int RANK=1;
3100
3101 vector<int> _nodes(N*2);
3102 int (*nodes)[2] = (int(*)[2])&_nodes[0];
3103
3104 // The first O(N) pass: create N single-vertex trees
3105 for(i = 0; i < N; i++)
3106 {
3107 nodes[i][PARENT]=-1;
3108 nodes[i][RANK] = 0;
3109 }
3110
3111 // The main O(N^2) pass: merge connected components
3112 for( i = 0; i < N; i++ )
3113 {
3114 int root = i;
3115
3116 // find root
3117 while( nodes[root][PARENT] >= 0 )
3118 root = nodes[root][PARENT];
3119
3120 for( j = 0; j < N; j++ )
3121 {
3122 if( i == j || !predicate(vec[i], vec[j]))
3123 continue;
3124 int root2 = j;
3125
3126 while( nodes[root2][PARENT] >= 0 )
3127 root2 = nodes[root2][PARENT];
3128
3129 if( root2 != root )
3130 {
3131 // unite both trees
3132 int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
3133 if( rank > rank2 )
3134 nodes[root2][PARENT] = root;
3135 else
3136 {
3137 nodes[root][PARENT] = root2;
3138 nodes[root2][RANK] += rank == rank2;
3139 root = root2;
3140 }
3141 assert( nodes[root][PARENT] < 0 );
3142
3143 int k = j, parent;
3144
3145 // compress the path from node2 to root
3146 while( (parent = nodes[k][PARENT]) >= 0 )
3147 {
3148 nodes[k][PARENT] = root;
3149 k = parent;
3150 }
3151
3152 // compress the path from node to root
3153 k = i;
3154 while( (parent = nodes[k][PARENT]) >= 0 )
3155 {
3156 nodes[k][PARENT] = root;
3157 k = parent;
3158 }
3159 }
3160 }
3161 }
3162
3163 // Final O(N) pass: enumerate classes
3164 labels.resize(N);
3165 int nclasses = 0;
3166
3167 for( i = 0; i < N; i++ )
3168 {
3169 int root = i;
3170 while( nodes[root][PARENT] >= 0 )
3171 root = nodes[root][PARENT];
3172 // re-use the rank as the class label
3173 if( nodes[root][RANK] >= 0 )
3174 nodes[root][RANK] = ~nclasses++;
3175 labels[i] = ~nodes[root][RANK];
3176 }
3177
3178 return nclasses;
3179 }
3180
3181
3183
3184 // bridge C++ => C Seq API
3185 CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0);
3186 CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0);
3187 CV_EXPORTS void seqPop( CvSeq* seq, void* element=0);
3188 CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0);
3189 CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements,
3190 int count, int in_front=0 );
3191 CV_EXPORTS void seqRemove( CvSeq* seq, int index );
3192 CV_EXPORTS void clearSeq( CvSeq* seq );
3193 CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index );
3194 CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice );
3195 CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
3196
3197 template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {}
3198 template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq)
3199 {
3200 CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp));
3201 }
3202
3203 template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage,
3204 int headerSize )
3205 {
3206 CV_Assert(headerSize >= (int)sizeof(CvSeq));
3207 seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage);
3208 }
3209
3210 template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx)
3211 { return *(_Tp*)getSeqElem(seq, idx); }
3212
3213 template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const
3214 { return *(_Tp*)getSeqElem(seq, idx); }
3215
3216 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const
3217 { return SeqIterator<_Tp>(*this); }
3218
3219 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const
3220 { return SeqIterator<_Tp>(*this, true); }
3221
3222 template<typename _Tp> inline size_t Seq<_Tp>::size() const
3223 { return seq ? seq->total : 0; }
3224
3225 template<typename _Tp> inline int Seq<_Tp>::type() const
3226 { return seq ? CV_MAT_TYPE(seq->flags) : 0; }
3227
3228 template<typename _Tp> inline int Seq<_Tp>::depth() const
3229 { return seq ? CV_MAT_DEPTH(seq->flags) : 0; }
3230
3231 template<typename _Tp> inline int Seq<_Tp>::channels() const
3232 { return seq ? CV_MAT_CN(seq->flags) : 0; }
3233
3234 template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const
3235 { return seq ? seq->elem_size : 0; }
3236
3237 template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const
3238 { return cvSeqElemIdx(seq, &elem); }
3239
3240 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem)
3241 { cvSeqPush(seq, &elem); }
3242
3243 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem)
3244 { cvSeqPushFront(seq, &elem); }
3245
3246 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count)
3247 { cvSeqPushMulti(seq, elem, (int)count, 0); }
3248
3249 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count)
3250 { cvSeqPushMulti(seq, elem, (int)count, 1); }
3251
3252 template<typename _Tp> inline _Tp& Seq<_Tp>::back()
3253 { return *(_Tp*)getSeqElem(seq, -1); }
3254
3255 template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const
3256 { return *(const _Tp*)getSeqElem(seq, -1); }
3257
3258 template<typename _Tp> inline _Tp& Seq<_Tp>::front()
3259 { return *(_Tp*)getSeqElem(seq, 0); }
3260
3261 template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const
3262 { return *(const _Tp*)getSeqElem(seq, 0); }
3263
3264 template<typename _Tp> inline bool Seq<_Tp>::empty() const
3265 { return !seq || seq->total == 0; }
3266
3267 template<typename _Tp> inline void Seq<_Tp>::clear()
3268 { if(seq) clearSeq(seq); }
3269
3270 template<typename _Tp> inline void Seq<_Tp>::pop_back()
3271 { seqPop(seq); }
3272
3273 template<typename _Tp> inline void Seq<_Tp>::pop_front()
3274 { seqPopFront(seq); }
3275
3276 template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count)
3277 { seqPopMulti(seq, elem, (int)count, 0); }
3278
3279 template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count)
3280 { seqPopMulti(seq, elem, (int)count, 1); }
3281
3282 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem)
3283 { seqInsert(seq, idx, &elem); }
3284
3285 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count)
3286 {
3287 CvMat m = cvMat(1, count, DataType<_Tp>::type, elems);
3288 seqInsertSlice(seq, idx, &m);
3289 }
3290
3291 template<typename _Tp> inline void Seq<_Tp>::remove(int idx)
3292 { seqRemove(seq, idx); }
3293
3294 template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r)
3295 { seqRemoveSlice(seq, r); }
3296
3297 template<typename _Tp> inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const
3298 {
3299 size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start;
3300 vec.resize(len);
3301 if( seq && len )
3302 cvCvtSeqToArray(seq, &vec[0], range);
3303 }
3304
3305 template<typename _Tp> inline Seq<_Tp>::operator vector<_Tp>() const
3306 {
3307 vector<_Tp> vec;
3308 copyTo(vec);
3309 return vec;
3310 }
3311
3312 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
3313 { memset(this, 0, sizeof(*this)); }
3314
3315 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd)
3316 {
3317 cvStartReadSeq(seq.seq, this);
3318 index = seekEnd ? seq.seq->total : 0;
3319 }
3320
3321 template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
3322 {
3323 cvSetSeqReaderPos(this, (int)pos, false);
3324 index = pos;
3325 }
3326
3327 template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const
3328 { return index; }
3329
3330 template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *()
3331 { return *(_Tp*)ptr; }
3332
3333 template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const
3334 { return *(const _Tp*)ptr; }
3335
3336 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++()
3337 {
3338 CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this);
3339 if( ++index >= seq->total*2 )
3340 index = 0;
3341 return *this;
3342 }
3343
3344 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const
3345 {
3346 SeqIterator<_Tp> it = *this;
3347 ++*this;
3348 return it;
3349 }
3350
3351 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --()
3352 {
3353 CV_PREV_SEQ_ELEM(sizeof(_Tp), *this);
3354 if( --index < 0 )
3355 index = seq->total*2-1;
3356 return *this;
3357 }
3358
3359 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const
3360 {
3361 SeqIterator<_Tp> it = *this;
3362 --*this;
3363 return it;
3364 }
3365
3366 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta)
3367 {
3368 cvSetSeqReaderPos(this, delta, 1);
3369 index += delta;
3370 int n = seq->total*2;
3371 if( index < 0 )
3372 index += n;
3373 if( index >= n )
3374 index -= n;
3375 return *this;
3376 }
3377
3378 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta)
3379 {
3380 return (*this += -delta);
3381 }
3382
3383 template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a,
3384 const SeqIterator<_Tp>& b)
3385 {
3386 ptrdiff_t delta = a.index - b.index, n = a.seq->total;
3387 if( std::abs(static_cast<long>(delta)) > n )
3388 delta += delta < 0 ? n : -n;
3389 return delta;
3390 }
3391
3392 template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a,
3393 const SeqIterator<_Tp>& b)
3394 {
3395 return a.seq == b.seq && a.index == b.index;
3396 }
3397
3398 template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
3399 const SeqIterator<_Tp>& b)
3400 {
3401 return !(a == b);
3402 }
3403
3404
3405 template<typename _ClsName> struct CV_EXPORTS RTTIImpl
3406 {
3407 public:
3408 static int isInstance(const void* ptr)
3409 {
3410 static _ClsName dummy;
3411 return *(const void**)&dummy == *(const void**)ptr;
3412 }
3413 static void release(void** dbptr)
3414 {
3415 if(dbptr && *dbptr)
3416 {
3417 delete (_ClsName*)*dbptr;
3418 *dbptr = 0;
3419 }
3420 }
3421 static void* read(CvFileStorage* fs, CvFileNode* n)
3422 {
3423 FileNode fn(fs, n);
3424 _ClsName* obj = new _ClsName;
3425 if(obj->read(fn))
3426 return obj;
3427 delete obj;
3428 return 0;
3429 }
3430
3431 static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList)
3432 {
3433 if(ptr && _fs)
3434 {
3435 FileStorage fs(_fs);
3436 fs.fs.addref();
3437 ((const _ClsName*)ptr)->write(fs, string(name));
3438 }
3439 }
3440
3441 static void* clone(const void* ptr)
3442 {
3443 if(!ptr)
3444 return 0;
3445 return new _ClsName(*(const _ClsName*)ptr);
3446 }
3447 };
3448
3449
3450 class CV_EXPORTS Formatter
3451 {
3452 public:
3453 virtual ~Formatter() {}
3454 virtual void write(std::ostream& out, const Mat& m, const int* params=0, int nparams=0) const = 0;
3455 virtual void write(std::ostream& out, const void* data, int nelems, int type,
3456 const int* params=0, int nparams=0) const = 0;
3457 static const Formatter* get(const char* fmt="");
3458 static const Formatter* setDefault(const Formatter* fmt);
3459 };
3460
3461
3462 struct CV_EXPORTS Formatted
3463 {
3464 Formatted(const Mat& m, const Formatter* fmt,
3465 const vector<int>& params);
3466 Formatted(const Mat& m, const Formatter* fmt,
3467 const int* params=0);
3468 Mat mtx;
3469 const Formatter* fmt;
3470 vector<int> params;
3471 };
3472
3473
3476 template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point_<_Tp>& p)
3477 {
3478 out << "[" << p.x << ", " << p.y << "]";
3479 return out;
3480 }
3481
3484 template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point3_<_Tp>& p)
3485 {
3486 out << "[" << p.x << ", " << p.y << ", " << p.z << "]";
3487 return out;
3488 }
3489
3490 static inline Formatted format(const Mat& mtx, const char* fmt,
3491 const vector<int>& params=vector<int>())
3492 {
3493 return Formatted(mtx, Formatter::get(fmt), params);
3494 }
3495
3496 template<typename _Tp> static inline Formatted format(const vector<Point_<_Tp> >& vec,
3497 const char* fmt, const vector<int>& params=vector<int>())
3498 {
3499 return Formatted(Mat(vec), Formatter::get(fmt), params);
3500 }
3501
3502 template<typename _Tp> static inline Formatted format(const vector<Point3_<_Tp> >& vec,
3503 const char* fmt, const vector<int>& params=vector<int>())
3504 {
3505 return Formatted(Mat(vec), Formatter::get(fmt), params);
3506 }
3507
3515 static inline std::ostream& operator << (std::ostream& out, const Mat& mtx)
3516 {
3517 Formatter::get()->write(out, mtx);
3518 return out;
3519 }
3520
3528 static inline std::ostream& operator << (std::ostream& out, const Formatted& fmtd)
3529 {
3530 fmtd.fmt->write(out, fmtd.mtx);
3531 return out;
3532 }
3533
3534
3535 template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
3536 const vector<Point_<_Tp> >& vec)
3537 {
3538 Formatter::get()->write(out, Mat(vec));
3539 return out;
3540 }
3541
3542
3543 template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
3544 const vector<Point3_<_Tp> >& vec)
3545 {
3546 Formatter::get()->write(out, Mat(vec));
3547 return out;
3548 }
3549
3550 }
3551
3552 #endif // __cplusplus
3553 #endif