opencv  2.2.0
 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
329 {
330  return all(0);
331 }
332 
333 template<typename _Tp, int m, int n> inline
335 {
336  return all(1);
337 }
338 
339 template<typename _Tp, int m, int n> inline
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
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
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>
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
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
412 {
413  CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
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
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
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
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
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
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
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
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
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
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
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
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
558 {
559  return Matx<_Tp, m, n>(a, b, Matx_AddOp());
560 }
561 
562 
563 template<typename _Tp, int m, int n> static inline
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
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
636 {
637  return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
638 }
639 
640 
641 template<typename _Tp> static inline
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
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
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
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
889 {
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
962  : dst(_mtx), idx(0)
963 {}
964 
965 template<typename _Tp, int m, int n> template<typename _T2> inline
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
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>
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
1244  : MatxCommaInitializer<_Tp, cn, 1>(_vec)
1245 {}
1246 
1247 template<typename _Tp, int cn> template<typename _T2> inline
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
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
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
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 
1759 inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
1760  : center(_center), size(_size), angle(_angle) {}
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 
2036  {
2037  Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
2038  _Tp* data;
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:
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) {}
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; }
2275 {
2276  int mask = err < 0 ? -1 : 0;
2277  err += minusDelta + (plusDelta & mask);
2278  ptr += minusStep + (plusStep & mask);
2279  return *this;
2280 }
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 
2494 {
2495 public:
2496  WriteStructContext(FileStorage& _fs, const string& name,
2497  int flags, const string& typeName=string());
2498  ~WriteStructContext();
2500 };
2501 
2502 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt )
2503 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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  }
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  }
2587 };
2588 
2589 
2590 template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec )
2591 {
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;
2612  CV_Error( CV_StsError, "No element name has been given" );
2613  write( fs, fs.elname, value );
2614  if( fs.state & 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 
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  }
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  }
2766 };
2767 
2768 template<typename _Tp> static inline void
2769 read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
2770 {
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 
2782 {
2783  return FileNodeIterator(fs, node);
2784 }
2785 
2787 {
2788  return FileNodeIterator(fs, node, size());
2789 }
2790 
2792 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
2793 
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 
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 
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 
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);
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