00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __OPENCV_CORE_OPERATIONS_HPP__
00044 #define __OPENCV_CORE_OPERATIONS_HPP__
00045
00046 #ifndef SKIP_INCLUDES
00047 #include <string.h>
00048 #include <limits.h>
00049 #endif // SKIP_INCLUDES
00050
00051 #ifdef __cplusplus
00052
00054 #ifdef __GNUC__
00055
00056 #if __GNUC__*10 + __GNUC_MINOR__ >= 42
00057
00058 #if !defined WIN32 && (defined __i486__ || defined __i586__ || \
00059 defined __i686__ || defined __MMX__ || defined __SSE__ || defined __ppc__)
00060 #define CV_XADD __sync_fetch_and_add
00061 #else
00062 #include <ext/atomicity.h>
00063 #define CV_XADD __gnu_cxx::__exchange_and_add
00064 #endif
00065
00066 #else
00067 #include <bits/atomicity.h>
00068 #if __GNUC__*10 + __GNUC_MINOR__ >= 34
00069 #define CV_XADD __gnu_cxx::__exchange_and_add
00070 #else
00071 #define CV_XADD __exchange_and_add
00072 #endif
00073 #endif
00074
00075 #elif defined WIN32 || defined _WIN32
00076
00077 #if defined _MSC_VER && defined _M_IX86
00078 static inline int CV_XADD( int* addr, int delta )
00079 {
00080 int tmp;
00081 __asm
00082 {
00083 mov edx, addr
00084 mov eax, delta
00085 lock xadd [edx], eax
00086 mov tmp, eax
00087 }
00088 return tmp;
00089 }
00090 #else
00091 #include "windows.h"
00092 #undef min
00093 #undef max
00094 #define CV_XADD(addr,delta) InterlockedExchangeAdd((LONG volatile*)(addr), (delta))
00095 #endif
00096
00097 #else
00098
00099 template<typename _Tp> static inline _Tp CV_XADD(_Tp* addr, _Tp delta)
00100 { int tmp = *addr; *addr += delta; return tmp; }
00101
00102 #endif
00103
00104 #include <limits>
00105
00106 namespace cv
00107 {
00108
00109 using std::cos;
00110 using std::sin;
00111 using std::max;
00112 using std::min;
00113 using std::exp;
00114 using std::log;
00115 using std::pow;
00116 using std::sqrt;
00117
00118
00120
00121 template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
00122 template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
00123 template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
00124 template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
00125 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
00126 template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
00127 template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
00128 template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
00129
00130 template<> inline uchar saturate_cast<uchar>(schar v)
00131 { return (uchar)std::max((int)v, 0); }
00132 template<> inline uchar saturate_cast<uchar>(ushort v)
00133 { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
00134 template<> inline uchar saturate_cast<uchar>(int v)
00135 { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
00136 template<> inline uchar saturate_cast<uchar>(short v)
00137 { return saturate_cast<uchar>((int)v); }
00138 template<> inline uchar saturate_cast<uchar>(unsigned v)
00139 { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
00140 template<> inline uchar saturate_cast<uchar>(float v)
00141 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
00142 template<> inline uchar saturate_cast<uchar>(double v)
00143 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
00144
00145 template<> inline schar saturate_cast<schar>(uchar v)
00146 { return (schar)std::min((int)v, SCHAR_MAX); }
00147 template<> inline schar saturate_cast<schar>(ushort v)
00148 { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
00149 template<> inline schar saturate_cast<schar>(int v)
00150 {
00151 return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ?
00152 v : v > 0 ? SCHAR_MAX : SCHAR_MIN);
00153 }
00154 template<> inline schar saturate_cast<schar>(short v)
00155 { return saturate_cast<schar>((int)v); }
00156 template<> inline schar saturate_cast<schar>(unsigned v)
00157 { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
00158
00159 template<> inline schar saturate_cast<schar>(float v)
00160 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
00161 template<> inline schar saturate_cast<schar>(double v)
00162 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
00163
00164 template<> inline ushort saturate_cast<ushort>(schar v)
00165 { return (ushort)std::max((int)v, 0); }
00166 template<> inline ushort saturate_cast<ushort>(short v)
00167 { return (ushort)std::max((int)v, 0); }
00168 template<> inline ushort saturate_cast<ushort>(int v)
00169 { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
00170 template<> inline ushort saturate_cast<ushort>(unsigned v)
00171 { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
00172 template<> inline ushort saturate_cast<ushort>(float v)
00173 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
00174 template<> inline ushort saturate_cast<ushort>(double v)
00175 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
00176
00177 template<> inline short saturate_cast<short>(ushort v)
00178 { return (short)std::min((int)v, SHRT_MAX); }
00179 template<> inline short saturate_cast<short>(int v)
00180 {
00181 return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ?
00182 v : v > 0 ? SHRT_MAX : SHRT_MIN);
00183 }
00184 template<> inline short saturate_cast<short>(unsigned v)
00185 { return (short)std::min(v, (unsigned)SHRT_MAX); }
00186 template<> inline short saturate_cast<short>(float v)
00187 { int iv = cvRound(v); return saturate_cast<short>(iv); }
00188 template<> inline short saturate_cast<short>(double v)
00189 { int iv = cvRound(v); return saturate_cast<short>(iv); }
00190
00191 template<> inline int saturate_cast<int>(float v) { return cvRound(v); }
00192 template<> inline int saturate_cast<int>(double v) { return cvRound(v); }
00193
00194
00195 template<> inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); }
00196 template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
00197
00198
00200
00201
00202 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx()
00203 {
00204 for(int i = 0; i < channels; i++) val[i] = _Tp(0);
00205 }
00206
00207 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0)
00208 {
00209 val[0] = v0;
00210 for(int i = 1; i < channels; i++) val[i] = _Tp(0);
00211 }
00212
00213 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
00214 {
00215 assert(channels >= 2);
00216 val[0] = v0; val[1] = v1;
00217 for(int i = 2; i < channels; i++) val[i] = _Tp(0);
00218 }
00219
00220 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
00221 {
00222 assert(channels >= 3);
00223 val[0] = v0; val[1] = v1; val[2] = v2;
00224 for(int i = 3; i < channels; i++) val[i] = _Tp(0);
00225 }
00226
00227 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
00228 {
00229 assert(channels >= 4);
00230 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00231 for(int i = 4; i < channels; i++) val[i] = _Tp(0);
00232 }
00233
00234 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
00235 {
00236 assert(channels >= 5);
00237 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
00238 for(int i = 5; i < channels; i++) val[i] = _Tp(0);
00239 }
00240
00241 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00242 _Tp v4, _Tp v5)
00243 {
00244 assert(channels >= 6);
00245 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00246 val[4] = v4; val[5] = v5;
00247 for(int i = 6; i < channels; i++) val[i] = _Tp(0);
00248 }
00249
00250 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00251 _Tp v4, _Tp v5, _Tp v6)
00252 {
00253 assert(channels >= 7);
00254 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00255 val[4] = v4; val[5] = v5; val[6] = v6;
00256 for(int i = 7; i < channels; i++) val[i] = _Tp(0);
00257 }
00258
00259 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00260 _Tp v4, _Tp v5, _Tp v6, _Tp v7)
00261 {
00262 assert(channels >= 8);
00263 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00264 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00265 for(int i = 8; i < channels; i++) val[i] = _Tp(0);
00266 }
00267
00268 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00269 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00270 _Tp v8)
00271 {
00272 assert(channels >= 9);
00273 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00274 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00275 val[8] = v8;
00276 for(int i = 9; i < channels; i++) val[i] = _Tp(0);
00277 }
00278
00279 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00280 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00281 _Tp v8, _Tp v9)
00282 {
00283 assert(channels >= 10);
00284 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00285 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00286 val[8] = v8; val[9] = v9;
00287 for(int i = 10; i < channels; i++) val[i] = _Tp(0);
00288 }
00289
00290
00291 template<typename _Tp, int m, int n>
00292 inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00293 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00294 _Tp v8, _Tp v9, _Tp v10, _Tp v11)
00295 {
00296 assert(channels == 12);
00297 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00298 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00299 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
00300 }
00301
00302 template<typename _Tp, int m, int n>
00303 inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00304 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00305 _Tp v8, _Tp v9, _Tp v10, _Tp v11,
00306 _Tp v12, _Tp v13, _Tp v14, _Tp v15)
00307 {
00308 assert(channels == 16);
00309 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00310 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00311 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
00312 val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
00313 }
00314
00315 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(const _Tp* values)
00316 {
00317 for( int i = 0; i < channels; i++ ) val[i] = values[i];
00318 }
00319
00320 template<typename _Tp, int m, int n> inline Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
00321 {
00322 Matx<_Tp, m, n> M;
00323 for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
00324 return M;
00325 }
00326
00327 template<typename _Tp, int m, int n> inline
00328 Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
00329 {
00330 return all(0);
00331 }
00332
00333 template<typename _Tp, int m, int n> inline
00334 Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
00335 {
00336 return all(1);
00337 }
00338
00339 template<typename _Tp, int m, int n> inline
00340 Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
00341 {
00342 Matx<_Tp,m,n> M;
00343 for(int i = 0; i < MIN(m,n); i++)
00344 M(i,i) = 1;
00345 return M;
00346 }
00347
00348 template<typename _Tp, int m, int n> inline _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
00349 {
00350 _Tp s = 0;
00351 for( int i = 0; i < m*n; i++ ) s += val[i]*M.val[i];
00352 return s;
00353 }
00354
00355
00356 template<typename _Tp, int m, int n> inline double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
00357 {
00358 double s = 0;
00359 for( int i = 0; i < m*n; i++ ) s += (double)val[i]*M.val[i];
00360 return s;
00361 }
00362
00363
00364
00365 template<typename _Tp, int m, int n> inline
00366 Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const Matx<_Tp,MIN(m,n),1>& d)
00367 {
00368 Matx<_Tp,m,n> M;
00369 for(int i = 0; i < MIN(m,n); i++)
00370 M(i,i) = d[i];
00371 return M;
00372 }
00373
00374 template<typename _Tp, int m, int n> inline
00375 Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
00376 {
00377 Matx<_Tp,m,n> M;
00378 Mat matM(M, false);
00379 cv::randu(matM, Scalar(a), Scalar(b));
00380 return M;
00381 }
00382
00383 template<typename _Tp, int m, int n> inline
00384 Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
00385 {
00386 Matx<_Tp,m,n> M;
00387 Mat matM(M, false);
00388 cv::randn(matM, Scalar(a), Scalar(b));
00389 return M;
00390 }
00391
00392 template<typename _Tp, int m, int n> template<typename T2>
00393 inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
00394 {
00395 Matx<T2, m, n> M;
00396 for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
00397 return M;
00398 }
00399
00400
00401 template<typename _Tp, int m, int n> template<int m1, int n1> inline
00402 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
00403 {
00404 CV_DbgAssert(m1*n1 == m*n);
00405 return (const Matx<_Tp, m1, n1>&)*this;
00406 }
00407
00408
00409 template<typename _Tp, int m, int n>
00410 template<int m1, int n1> inline
00411 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
00412 {
00413 CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
00414 Matx<_Tp, m1, n1> s;
00415 for( int di = 0; di < m1; di++ )
00416 for( int dj = 0; dj < n1; dj++ )
00417 s(di, dj) = (*this)(i+di, j+dj);
00418 return s;
00419 }
00420
00421
00422 template<typename _Tp, int m, int n> inline
00423 Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
00424 {
00425 CV_DbgAssert((unsigned)i < (unsigned)m);
00426 return Matx<_Tp, 1, n>(&val[i*n]);
00427 }
00428
00429
00430 template<typename _Tp, int m, int n> inline
00431 Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
00432 {
00433 CV_DbgAssert((unsigned)j < (unsigned)n);
00434 Matx<_Tp, m, 1> v;
00435 for( int i = 0; i < m; i++ )
00436 v[i] = val[i*n + j];
00437 return v;
00438 }
00439
00440
00441 template<typename _Tp, int m, int n> inline
00442 Matx<_Tp, MIN(m,n), 1> Matx<_Tp, m, n>::diag() const
00443 {
00444 diag_type d;
00445 for( int i = 0; i < MIN(m, n); i++ )
00446 d.val[i] = val[i*n + i];
00447 return d;
00448 }
00449
00450
00451 template<typename _Tp, int m, int n> inline
00452 const _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) const
00453 {
00454 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
00455 return this->val[i*n + j];
00456 }
00457
00458
00459 template<typename _Tp, int m, int n> inline
00460 _Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
00461 {
00462 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
00463 return val[i*n + j];
00464 }
00465
00466
00467 template<typename _Tp, int m, int n> inline
00468 const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
00469 {
00470 CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
00471 return val[i];
00472 }
00473
00474
00475 template<typename _Tp, int m, int n> inline
00476 _Tp& Matx<_Tp, m, n>::operator ()(int i)
00477 {
00478 CV_DbgAssert( (m == 1 || n == 1) && (unsigned)i < (unsigned)(m+n-1) );
00479 return val[i];
00480 }
00481
00482
00483 template<typename _Tp1, typename _Tp2, int m, int n> static inline
00484 Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
00485 {
00486 for( int i = 0; i < m*n; i++ )
00487 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
00488 return a;
00489 }
00490
00491
00492 template<typename _Tp1, typename _Tp2, int m, int n> static inline
00493 Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
00494 {
00495 for( int i = 0; i < m*n; i++ )
00496 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
00497 return a;
00498 }
00499
00500
00501 template<typename _Tp, int m, int n> inline
00502 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
00503 {
00504 for( int i = 0; i < m*n; i++ )
00505 val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
00506 }
00507
00508
00509 template<typename _Tp, int m, int n> inline
00510 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
00511 {
00512 for( int i = 0; i < m*n; i++ )
00513 val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
00514 }
00515
00516
00517 template<typename _Tp, int m, int n> template<typename _T2> inline
00518 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
00519 {
00520 for( int i = 0; i < m*n; i++ )
00521 val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
00522 }
00523
00524
00525 template<typename _Tp, int m, int n> inline
00526 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
00527 {
00528 for( int i = 0; i < m*n; i++ )
00529 val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
00530 }
00531
00532
00533 template<typename _Tp, int m, int n> template<int l> inline
00534 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
00535 {
00536 for( int i = 0; i < m; i++ )
00537 for( int j = 0; j < n; j++ )
00538 {
00539 _Tp s = 0;
00540 for( int k = 0; k < l; k++ )
00541 s += a(i, k) * b(k, j);
00542 val[i*n + j] = s;
00543 }
00544 }
00545
00546
00547 template<typename _Tp, int m, int n> inline
00548 Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
00549 {
00550 for( int i = 0; i < m; i++ )
00551 for( int j = 0; j < n; j++ )
00552 val[i*n + j] = a(j, i);
00553 }
00554
00555
00556 template<typename _Tp, int m, int n> static inline
00557 Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
00558 {
00559 return Matx<_Tp, m, n>(a, b, Matx_AddOp());
00560 }
00561
00562
00563 template<typename _Tp, int m, int n> static inline
00564 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
00565 {
00566 return Matx<_Tp, m, n>(a, b, Matx_SubOp());
00567 }
00568
00569
00570 template<typename _Tp, int m, int n> static inline
00571 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
00572 {
00573 for( int i = 0; i < m*n; i++ )
00574 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
00575 return a;
00576 }
00577
00578 template<typename _Tp, int m, int n> static inline
00579 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
00580 {
00581 for( int i = 0; i < m*n; i++ )
00582 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
00583 return a;
00584 }
00585
00586 template<typename _Tp, int m, int n> static inline
00587 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
00588 {
00589 for( int i = 0; i < m*n; i++ )
00590 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
00591 return a;
00592 }
00593
00594 template<typename _Tp, int m, int n> static inline
00595 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
00596 {
00597 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00598 }
00599
00600 template<typename _Tp, int m, int n> static inline
00601 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
00602 {
00603 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00604 }
00605
00606 template<typename _Tp, int m, int n> static inline
00607 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
00608 {
00609 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00610 }
00611
00612 template<typename _Tp, int m, int n> static inline
00613 Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
00614 {
00615 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00616 }
00617
00618 template<typename _Tp, int m, int n> static inline
00619 Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
00620 {
00621 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00622 }
00623
00624 template<typename _Tp, int m, int n> static inline
00625 Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
00626 {
00627 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
00628 }
00629
00630 template<typename _Tp, int m, int n> static inline
00631 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
00632 {
00633 return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
00634 }
00635
00636
00637 template<typename _Tp, int m, int n, int l> static inline
00638 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
00639 {
00640 return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
00641 }
00642
00643
00644 template<typename _Tp> static inline
00645 Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
00646 {
00647 return Point_<_Tp>(a*Vec<_Tp,2>(b));
00648 }
00649
00650
00651 template<typename _Tp> static inline
00652 Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b)
00653 {
00654 return Point3_<_Tp>(a*Vec<_Tp,3>(b));
00655 }
00656
00657
00658 template<typename _Tp> static inline
00659 Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b)
00660 {
00661 return Point3_<_Tp>(a*Vec<_Tp,3>(b.x, b.y, 1));
00662 }
00663
00664
00665 template<typename _Tp> static inline
00666 Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
00667 {
00668 return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
00669 }
00670
00671
00672 template<typename _Tp> static inline
00673 Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
00674 {
00675 return Scalar(a*Matx<_Tp, 4, 1>(b));
00676 }
00677
00678
00679 template<typename _Tp, int m, int n> inline
00680 Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
00681 {
00682 return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
00683 }
00684
00685
00686 CV_EXPORTS int LU(float* A, int m, float* b, int n);
00687 CV_EXPORTS int LU(double* A, int m, double* b, int n);
00688 CV_EXPORTS bool Cholesky(float* A, int m, float* b, int n);
00689 CV_EXPORTS bool Cholesky(double* A, int m, double* b, int n);
00690
00691
00692 template<typename _Tp, int m> struct CV_EXPORTS Matx_DetOp
00693 {
00694 double operator ()(const Matx<_Tp, m, m>& a) const
00695 {
00696 Matx<_Tp, m, m> temp = a;
00697 double p = LU(temp.val, m, 0, 0);
00698 if( p == 0 )
00699 return p;
00700 for( int i = 0; i < m; i++ )
00701 p *= temp(i, i);
00702 return p;
00703 }
00704 };
00705
00706
00707 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 1>
00708 {
00709 double operator ()(const Matx<_Tp, 1, 1>& a) const
00710 {
00711 return a(0,0);
00712 }
00713 };
00714
00715
00716 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 2>
00717 {
00718 double operator ()(const Matx<_Tp, 2, 2>& a) const
00719 {
00720 return a(0,0)*a(1,1) - a(0,1)*a(1,0);
00721 }
00722 };
00723
00724
00725 template<typename _Tp> struct CV_EXPORTS Matx_DetOp<_Tp, 3>
00726 {
00727 double operator ()(const Matx<_Tp, 3, 3>& a) const
00728 {
00729 return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
00730 a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
00731 a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
00732 }
00733 };
00734
00735 template<typename _Tp, int m> static inline
00736 double determinant(const Matx<_Tp, m, m>& a)
00737 {
00738 return Matx_DetOp<_Tp, m>()(a);
00739 }
00740
00741
00742 template<typename _Tp, int m, int n> static inline
00743 double trace(const Matx<_Tp, m, n>& a)
00744 {
00745 _Tp s = 0;
00746 for( int i = 0; i < std::min(m, n); i++ )
00747 s += a(i,i);
00748 return s;
00749 }
00750
00751
00752 template<typename _Tp, int m, int n> inline
00753 Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
00754 {
00755 return Matx<_Tp, n, m>(*this, Matx_TOp());
00756 }
00757
00758
00759 template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
00760 {
00761 bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
00762 {
00763 Matx<_Tp, m, m> temp = a;
00764
00765
00766 for( int i = 0; i < m; i++ )
00767 b(i, i) = (_Tp)1;
00768
00769 if( method == DECOMP_CHOLESKY )
00770 return Cholesky(temp.val, m, b.val, m);
00771
00772 return LU(temp.val, m, b.val, m) != 0;
00773 }
00774 };
00775
00776
00777 template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
00778 {
00779 bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
00780 {
00781 _Tp d = determinant(a);
00782 if( d == 0 )
00783 return false;
00784 d = 1/d;
00785 b(1,1) = a(0,0)*d;
00786 b(0,0) = a(1,1)*d;
00787 b(0,1) = -a(0,1)*d;
00788 b(1,0) = -a(1,0)*d;
00789 return true;
00790 }
00791 };
00792
00793
00794 template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
00795 {
00796 bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
00797 {
00798 _Tp d = determinant(a);
00799 if( d == 0 )
00800 return false;
00801 d = 1/d;
00802 b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
00803 b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
00804 b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
00805
00806 b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
00807 b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
00808 b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
00809
00810 b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
00811 b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
00812 b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
00813 return true;
00814 }
00815 };
00816
00817
00818 template<typename _Tp, int m, int n> inline
00819 Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method) const
00820 {
00821 Matx<_Tp, n, m> b;
00822 bool ok;
00823 if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
00824 ok = Matx_FastInvOp<_Tp, m>()(*this, b, method);
00825 else
00826 {
00827 Mat A(*this, false), B(b, false);
00828 ok = invert(A, B, method);
00829 }
00830 return ok ? b : Matx<_Tp, n, m>::zeros();
00831 }
00832
00833
00834 template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
00835 {
00836 bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
00837 Matx<_Tp, m, n>& x, int method) const
00838 {
00839 Matx<_Tp, m, m> temp = a;
00840 x = b;
00841 if( method == DECOMP_CHOLESKY )
00842 return Cholesky(temp.val, m, x.val, n);
00843
00844 return LU(temp.val, m, x.val, n) != 0;
00845 }
00846 };
00847
00848
00849 template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
00850 {
00851 bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
00852 Matx<_Tp, 2, 1>& x, int method) const
00853 {
00854 _Tp d = determinant(a);
00855 if( d == 0 )
00856 return false;
00857 d = 1/d;
00858 x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
00859 x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
00860 return true;
00861 }
00862 };
00863
00864
00865 template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
00866 {
00867 bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
00868 Matx<_Tp, 3, 1>& x, int method) const
00869 {
00870 _Tp d = determinant(a);
00871 if( d == 0 )
00872 return false;
00873 d = 1/d;
00874 x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
00875 a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
00876 a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
00877
00878 x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
00879 b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
00880 a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
00881
00882 x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
00883 a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
00884 b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
00885 return true;
00886 }
00887 };
00888
00889
00890 template<typename _Tp, int m, int n> template<int l> inline
00891 Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
00892 {
00893 Matx<_Tp, n, l> x;
00894 bool ok;
00895 if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
00896 ok = Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
00897 else
00898 {
00899 Mat A(*this, false), B(rhs, false), X(x, false);
00900 ok = cv::solve(A, B, X, method);
00901 }
00902
00903 return ok ? x : Matx<_Tp, n, l>::zeros();
00904 }
00905
00906
00907 template<typename _Tp, int m, int n> static inline
00908 double norm(const Matx<_Tp, m, n>& M)
00909 {
00910 double s = 0;
00911 for( int i = 0; i < m*n; i++ )
00912 s += (double)M.val[i]*M.val[i];
00913 return std::sqrt(s);
00914 }
00915
00916
00917 template<typename _Tp, int m, int n> static inline
00918 double norm(const Matx<_Tp, m, n>& M, int normType)
00919 {
00920 if( normType == NORM_INF )
00921 {
00922 _Tp s = 0;
00923 for( int i = 0; i < m*n; i++ )
00924 s = std::max(s, std::abs(M.val[i]));
00925 return s;
00926 }
00927
00928 if( normType == NORM_L1 )
00929 {
00930 _Tp s = 0;
00931 for( int i = 0; i < m*n; i++ )
00932 s += std::abs(M.val[i]);
00933 return s;
00934 }
00935
00936 CV_DbgAssert( normType == NORM_L2 );
00937 return norm(M);
00938 }
00939
00940
00941 template<typename _Tp, int m, int n> static inline
00942 bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
00943 {
00944 for( int i = 0; i < m*n; i++ )
00945 if( a.val[i] != b.val[i] ) return false;
00946 return true;
00947 }
00948
00949 template<typename _Tp, int m, int n> static inline
00950 bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
00951 {
00952 return !(a == b);
00953 }
00954
00955
00956 template<typename _Tp, typename _T2, int m, int n> static inline
00957 MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
00958 {
00959 MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
00960 return (commaInitializer, val);
00961 }
00962
00963 template<typename _Tp, int m, int n> inline
00964 MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
00965 : dst(_mtx), idx(0)
00966 {}
00967
00968 template<typename _Tp, int m, int n> template<typename _T2> inline
00969 MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
00970 {
00971 CV_DbgAssert( idx < m*n );
00972 dst->val[idx++] = saturate_cast<_Tp>(value);
00973 return *this;
00974 }
00975
00976 template<typename _Tp, int m, int n> inline
00977 Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
00978 {
00979 CV_DbgAssert( idx == n*m );
00980 return *dst;
00981 }
00982
00984
00985 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
00986 {}
00987
00988 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
00989 : Matx<_Tp, cn, 1>(v0)
00990 {}
00991
00992 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
00993 : Matx<_Tp, cn, 1>(v0, v1)
00994 {}
00995
00996 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
00997 : Matx<_Tp, cn, 1>(v0, v1, v2)
00998 {}
00999
01000 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
01001 : Matx<_Tp, cn, 1>(v0, v1, v2, v3)
01002 {}
01003
01004 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
01005 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4)
01006 {}
01007
01008 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
01009 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5)
01010 {}
01011
01012 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
01013 _Tp v4, _Tp v5, _Tp v6)
01014 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6)
01015 {}
01016
01017 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
01018 _Tp v4, _Tp v5, _Tp v6, _Tp v7)
01019 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7)
01020 {}
01021
01022 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
01023 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
01024 _Tp v8)
01025 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8)
01026 {}
01027
01028 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
01029 _Tp v4, _Tp v5, _Tp v6, _Tp v7,
01030 _Tp v8, _Tp v9)
01031 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
01032 {}
01033
01034 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const _Tp* values)
01035 : Matx<_Tp, cn, 1>(values)
01036 {}
01037
01038
01039 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
01040 : Matx<_Tp, cn, 1>(v.val)
01041 {}
01042
01043 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
01044 {
01045 Vec v;
01046 for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
01047 return v;
01048 }
01049
01050 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
01051 {
01052 Vec<_Tp, cn> w;
01053 for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
01054 return w;
01055 }
01056
01057 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
01058 {
01059 CV_Error(CV_StsError, "for arbitrary-size vector there is no cross-product defined");
01060 return Vec<_Tp, cn>();
01061 }
01062
01063 template<typename _Tp, int cn> template<typename T2>
01064 inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
01065 {
01066 Vec<T2, cn> v;
01067 for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
01068 return v;
01069 }
01070
01071 template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
01072 {
01073 CvScalar s = {{0,0,0,0}};
01074 int i;
01075 for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = this->val[i];
01076 for( ; i < 4; i++ ) s.val[i] = 0;
01077 return s;
01078 }
01079
01080 template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator [](int i) const
01081 {
01082 CV_DbgAssert( (unsigned)i < (unsigned)cn );
01083 return this->val[i];
01084 }
01085
01086 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator [](int i)
01087 {
01088 CV_DbgAssert( (unsigned)i < (unsigned)cn );
01089 return this->val[i];
01090 }
01091
01092 template<typename _Tp, int cn> inline const _Tp& Vec<_Tp, cn>::operator ()(int i) const
01093 {
01094 CV_DbgAssert( (unsigned)i < (unsigned)cn );
01095 return this->val[i];
01096 }
01097
01098 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator ()(int i)
01099 {
01100 CV_DbgAssert( (unsigned)i < (unsigned)cn );
01101 return this->val[i];
01102 }
01103
01104 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
01105 operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
01106 {
01107 for( int i = 0; i < cn; i++ )
01108 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
01109 return a;
01110 }
01111
01112 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
01113 operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
01114 {
01115 for( int i = 0; i < cn; i++ )
01116 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
01117 return a;
01118 }
01119
01120 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
01121 operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
01122 {
01123 Vec<_Tp, cn> c = a;
01124 return c += b;
01125 }
01126
01127 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
01128 operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
01129 {
01130 Vec<_Tp, cn> c = a;
01131 return c -= b;
01132 }
01133
01134 template<typename _Tp> static inline
01135 Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha)
01136 {
01137 a[0] *= alpha; a[1] *= alpha;
01138 return a;
01139 }
01140
01141 template<typename _Tp> static inline
01142 Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha)
01143 {
01144 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha;
01145 return a;
01146 }
01147
01148 template<typename _Tp> static inline
01149 Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha)
01150 {
01151 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha;
01152 return a;
01153 }
01154
01155 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
01156 operator * (const Vec<_Tp, cn>& a, _Tp alpha)
01157 {
01158 Vec<_Tp, cn> c = a;
01159 return c *= alpha;
01160 }
01161
01162 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
01163 operator * (_Tp alpha, const Vec<_Tp, cn>& a)
01164 {
01165 return a * alpha;
01166 }
01167
01168
01169 template<typename _Tp> static inline Vec<_Tp, 4>
01170 operator * (const Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
01171 {
01172 return Vec<_Tp, 4>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
01173 saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
01174 saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]),
01175 saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0]));
01176 }
01177
01178
01179 template<typename _Tp> static inline Vec<_Tp, 4>&
01180 operator *= (Vec<_Tp, 4>& a, const Vec<_Tp, 4>& b)
01181 {
01182 a = a*b;
01183 return a;
01184 }
01185
01186
01187 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
01188 operator - (const Vec<_Tp, cn>& a)
01189 {
01190 Vec<_Tp,cn> t;
01191 for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
01192 return t;
01193 }
01194
01195 template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
01196 {
01197 return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
01198 val[2]*v.val[0] - val[0]*v.val[2],
01199 val[0]*v.val[1] - val[1]*v.val[0]);
01200 }
01201
01202 template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
01203 {
01204 return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
01205 val[2]*v.val[0] - val[0]*v.val[2],
01206 val[0]*v.val[1] - val[1]*v.val[0]);
01207 }
01208
01209 template<typename T1, typename T2> static inline
01210 Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
01211 {
01212 a[0] = saturate_cast<T1>(a[0] + b[0]);
01213 a[1] = saturate_cast<T1>(a[1] + b[1]);
01214 return a;
01215 }
01216
01217 template<typename T1, typename T2> static inline
01218 Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
01219 {
01220 a[0] = saturate_cast<T1>(a[0] + b[0]);
01221 a[1] = saturate_cast<T1>(a[1] + b[1]);
01222 a[2] = saturate_cast<T1>(a[2] + b[2]);
01223 return a;
01224 }
01225
01226
01227 template<typename T1, typename T2> static inline
01228 Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
01229 {
01230 a[0] = saturate_cast<T1>(a[0] + b[0]);
01231 a[1] = saturate_cast<T1>(a[1] + b[1]);
01232 a[2] = saturate_cast<T1>(a[2] + b[2]);
01233 a[3] = saturate_cast<T1>(a[3] + b[3]);
01234 return a;
01235 }
01236
01237
01238 template<typename _Tp, typename _T2, int cn> static inline
01239 VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
01240 {
01241 VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
01242 return (commaInitializer, val);
01243 }
01244
01245 template<typename _Tp, int cn> inline
01246 VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
01247 : MatxCommaInitializer<_Tp, cn, 1>(_vec)
01248 {}
01249
01250 template<typename _Tp, int cn> template<typename _T2> inline
01251 VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
01252 {
01253 CV_DbgAssert( this->idx < cn );
01254 this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
01255 return *this;
01256 }
01257
01258 template<typename _Tp, int cn> inline
01259 Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
01260 {
01261 CV_DbgAssert( this->idx == cn );
01262 return *this->dst;
01263 }
01264
01266
01267 template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {}
01268 template<typename _Tp> inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {}
01269 template<typename _Tp> template<typename T2> inline Complex<_Tp>::operator Complex<T2>() const
01270 { return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); }
01271 template<typename _Tp> inline Complex<_Tp> Complex<_Tp>::conj() const
01272 { return Complex<_Tp>(re, -im); }
01273
01274 template<typename _Tp> static inline
01275 bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
01276 { return a.re == b.re && a.im == b.im; }
01277
01278 template<typename _Tp> static inline
01279 bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b)
01280 { return a.re != b.re || a.im != b.im; }
01281
01282 template<typename _Tp> static inline
01283 Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
01284 { return Complex<_Tp>( a.re + b.re, a.im + b.im ); }
01285
01286 template<typename _Tp> static inline
01287 Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
01288 { a.re += b.re; a.im += b.im; return a; }
01289
01290 template<typename _Tp> static inline
01291 Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
01292 { return Complex<_Tp>( a.re - b.re, a.im - b.im ); }
01293
01294 template<typename _Tp> static inline
01295 Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
01296 { a.re -= b.re; a.im -= b.im; return a; }
01297
01298 template<typename _Tp> static inline
01299 Complex<_Tp> operator - (const Complex<_Tp>& a)
01300 { return Complex<_Tp>(-a.re, -a.im); }
01301
01302 template<typename _Tp> static inline
01303 Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
01304 { return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); }
01305
01306 template<typename _Tp> static inline
01307 Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
01308 { return Complex<_Tp>( a.re*b, a.im*b ); }
01309
01310 template<typename _Tp> static inline
01311 Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
01312 { return Complex<_Tp>( a.re*b, a.im*b ); }
01313
01314 template<typename _Tp> static inline
01315 Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
01316 { return Complex<_Tp>( a.re + b, a.im ); }
01317
01318 template<typename _Tp> static inline
01319 Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
01320 { return Complex<_Tp>( a.re - b, a.im ); }
01321
01322 template<typename _Tp> static inline
01323 Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
01324 { return Complex<_Tp>( a.re + b, a.im ); }
01325
01326 template<typename _Tp> static inline
01327 Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
01328 { return Complex<_Tp>( b - a.re, -a.im ); }
01329
01330 template<typename _Tp> static inline
01331 Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
01332 { a.re += b; return a; }
01333
01334 template<typename _Tp> static inline
01335 Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
01336 { a.re -= b; return a; }
01337
01338 template<typename _Tp> static inline
01339 Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
01340 { a.re *= b; a.im *= b; return a; }
01341
01342 template<typename _Tp> static inline
01343 double abs(const Complex<_Tp>& a)
01344 { return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); }
01345
01346 template<typename _Tp> static inline
01347 Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
01348 {
01349 double t = 1./((double)b.re*b.re + (double)b.im*b.im);
01350 return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
01351 (_Tp)((-a.re*b.im + a.im*b.re)*t) );
01352 }
01353
01354 template<typename _Tp> static inline
01355 Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
01356 {
01357 return (a = a / b);
01358 }
01359
01360 template<typename _Tp> static inline
01361 Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
01362 {
01363 _Tp t = (_Tp)1/b;
01364 return Complex<_Tp>( a.re*t, a.im*t );
01365 }
01366
01367 template<typename _Tp> static inline
01368 Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
01369 {
01370 return Complex<_Tp>(b)/a;
01371 }
01372
01373 template<typename _Tp> static inline
01374 Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
01375 {
01376 _Tp t = (_Tp)1/b;
01377 a.re *= t; a.im *= t; return a;
01378 }
01379
01381
01382 template<typename _Tp> inline Point_<_Tp>::Point_() : x(0), y(0) {}
01383 template<typename _Tp> inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
01384 template<typename _Tp> inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {}
01385 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {}
01386 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint2D32f& pt)
01387 : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {}
01388 template<typename _Tp> inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {}
01389 template<typename _Tp> inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {}
01390 template<typename _Tp> inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
01391 { x = pt.x; y = pt.y; return *this; }
01392
01393 template<typename _Tp> template<typename _Tp2> inline Point_<_Tp>::operator Point_<_Tp2>() const
01394 { return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); }
01395 template<typename _Tp> inline Point_<_Tp>::operator CvPoint() const
01396 { return cvPoint(saturate_cast<int>(x), saturate_cast<int>(y)); }
01397 template<typename _Tp> inline Point_<_Tp>::operator CvPoint2D32f() const
01398 { return cvPoint2D32f((float)x, (float)y); }
01399 template<typename _Tp> inline Point_<_Tp>::operator Vec<_Tp, 2>() const
01400 { return Vec<_Tp, 2>(x, y); }
01401
01402 template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const
01403 { return saturate_cast<_Tp>(x*pt.x + y*pt.y); }
01404 template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const
01405 { return (double)x*pt.x + (double)y*pt.y; }
01406
01407 template<typename _Tp> static inline Point_<_Tp>&
01408 operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
01409 {
01410 a.x = saturate_cast<_Tp>(a.x + b.x);
01411 a.y = saturate_cast<_Tp>(a.y + b.y);
01412 return a;
01413 }
01414
01415 template<typename _Tp> static inline Point_<_Tp>&
01416 operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
01417 {
01418 a.x = saturate_cast<_Tp>(a.x - b.x);
01419 a.y = saturate_cast<_Tp>(a.y - b.y);
01420 return a;
01421 }
01422
01423 template<typename _Tp> static inline Point_<_Tp>&
01424 operator *= (Point_<_Tp>& a, int b)
01425 {
01426 a.x = saturate_cast<_Tp>(a.x*b);
01427 a.y = saturate_cast<_Tp>(a.y*b);
01428 return a;
01429 }
01430
01431 template<typename _Tp> static inline Point_<_Tp>&
01432 operator *= (Point_<_Tp>& a, float b)
01433 {
01434 a.x = saturate_cast<_Tp>(a.x*b);
01435 a.y = saturate_cast<_Tp>(a.y*b);
01436 return a;
01437 }
01438
01439 template<typename _Tp> static inline Point_<_Tp>&
01440 operator *= (Point_<_Tp>& a, double b)
01441 {
01442 a.x = saturate_cast<_Tp>(a.x*b);
01443 a.y = saturate_cast<_Tp>(a.y*b);
01444 return a;
01445 }
01446
01447 template<typename _Tp> static inline double norm(const Point_<_Tp>& pt)
01448 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); }
01449
01450 template<typename _Tp> static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
01451 { return a.x == b.x && a.y == b.y; }
01452
01453 template<typename _Tp> static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
01454 { return a.x != b.x || a.y != b.y; }
01455
01456 template<typename _Tp> static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
01457 { return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); }
01458
01459 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
01460 { return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); }
01461
01462 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a)
01463 { return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); }
01464
01465 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
01466 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
01467
01468 template<typename _Tp> static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
01469 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
01470
01471 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
01472 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
01473
01474 template<typename _Tp> static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
01475 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
01476
01477 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
01478 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
01479
01480 template<typename _Tp> static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
01481 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
01482
01484
01485 template<typename _Tp> inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {}
01486 template<typename _Tp> inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {}
01487 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
01488 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {}
01489 template<typename _Tp> inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) :
01490 x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {}
01491 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {}
01492
01493 template<typename _Tp> template<typename _Tp2> inline Point3_<_Tp>::operator Point3_<_Tp2>() const
01494 { return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); }
01495
01496 template<typename _Tp> inline Point3_<_Tp>::operator CvPoint3D32f() const
01497 { return cvPoint3D32f((float)x, (float)y, (float)z); }
01498
01499 template<typename _Tp> inline Point3_<_Tp>::operator Vec<_Tp, 3>() const
01500 { return Vec<_Tp, 3>(x, y, z); }
01501
01502 template<typename _Tp> inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
01503 { x = pt.x; y = pt.y; z = pt.z; return *this; }
01504
01505 template<typename _Tp> inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const
01506 { return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); }
01507 template<typename _Tp> inline double Point3_<_Tp>::ddot(const Point3_& pt) const
01508 { return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; }
01509
01510 template<typename _Tp> inline Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
01511 {
01512 return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
01513 }
01514
01515 template<typename _Tp> static inline Point3_<_Tp>&
01516 operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
01517 {
01518 a.x = saturate_cast<_Tp>(a.x + b.x);
01519 a.y = saturate_cast<_Tp>(a.y + b.y);
01520 a.z = saturate_cast<_Tp>(a.z + b.z);
01521 return a;
01522 }
01523
01524 template<typename _Tp> static inline Point3_<_Tp>&
01525 operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
01526 {
01527 a.x = saturate_cast<_Tp>(a.x - b.x);
01528 a.y = saturate_cast<_Tp>(a.y - b.y);
01529 a.z = saturate_cast<_Tp>(a.z - b.z);
01530 return a;
01531 }
01532
01533 template<typename _Tp> static inline Point3_<_Tp>&
01534 operator *= (Point3_<_Tp>& a, int b)
01535 {
01536 a.x = saturate_cast<_Tp>(a.x*b);
01537 a.y = saturate_cast<_Tp>(a.y*b);
01538 a.z = saturate_cast<_Tp>(a.z*b);
01539 return a;
01540 }
01541
01542 template<typename _Tp> static inline Point3_<_Tp>&
01543 operator *= (Point3_<_Tp>& a, float b)
01544 {
01545 a.x = saturate_cast<_Tp>(a.x*b);
01546 a.y = saturate_cast<_Tp>(a.y*b);
01547 a.z = saturate_cast<_Tp>(a.z*b);
01548 return a;
01549 }
01550
01551 template<typename _Tp> static inline Point3_<_Tp>&
01552 operator *= (Point3_<_Tp>& a, double b)
01553 {
01554 a.x = saturate_cast<_Tp>(a.x*b);
01555 a.y = saturate_cast<_Tp>(a.y*b);
01556 a.z = saturate_cast<_Tp>(a.z*b);
01557 return a;
01558 }
01559
01560 template<typename _Tp> static inline double norm(const Point3_<_Tp>& pt)
01561 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); }
01562
01563 template<typename _Tp> static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
01564 { return a.x == b.x && a.y == b.y && a.z == b.z; }
01565
01566 template<typename _Tp> static inline bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
01567 { return a.x != b.x || a.y != b.y || a.z != b.z; }
01568
01569 template<typename _Tp> static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
01570 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x),
01571 saturate_cast<_Tp>(a.y + b.y),
01572 saturate_cast<_Tp>(a.z + b.z)); }
01573
01574 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
01575 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x),
01576 saturate_cast<_Tp>(a.y - b.y),
01577 saturate_cast<_Tp>(a.z - b.z)); }
01578
01579 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a)
01580 { return Point3_<_Tp>( saturate_cast<_Tp>(-a.x),
01581 saturate_cast<_Tp>(-a.y),
01582 saturate_cast<_Tp>(-a.z) ); }
01583
01584 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
01585 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
01586 saturate_cast<_Tp>(a.y*b),
01587 saturate_cast<_Tp>(a.z*b) ); }
01588
01589 template<typename _Tp> static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
01590 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
01591 saturate_cast<_Tp>(b.y*a),
01592 saturate_cast<_Tp>(b.z*a) ); }
01593
01594 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
01595 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
01596 saturate_cast<_Tp>(a.y*b),
01597 saturate_cast<_Tp>(a.z*b) ); }
01598
01599 template<typename _Tp> static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
01600 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
01601 saturate_cast<_Tp>(b.y*a),
01602 saturate_cast<_Tp>(b.z*a) ); }
01603
01604 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
01605 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
01606 saturate_cast<_Tp>(a.y*b),
01607 saturate_cast<_Tp>(a.z*b) ); }
01608
01609 template<typename _Tp> static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
01610 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
01611 saturate_cast<_Tp>(b.y*a),
01612 saturate_cast<_Tp>(b.z*a) ); }
01613
01615
01616 template<typename _Tp> inline Size_<_Tp>::Size_()
01617 : width(0), height(0) {}
01618 template<typename _Tp> inline Size_<_Tp>::Size_(_Tp _width, _Tp _height)
01619 : width(_width), height(_height) {}
01620 template<typename _Tp> inline Size_<_Tp>::Size_(const Size_& sz)
01621 : width(sz.width), height(sz.height) {}
01622 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize& sz)
01623 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
01624 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize2D32f& sz)
01625 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
01626 template<typename _Tp> inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {}
01627
01628 template<typename _Tp> template<typename _Tp2> inline Size_<_Tp>::operator Size_<_Tp2>() const
01629 { return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
01630 template<typename _Tp> inline Size_<_Tp>::operator CvSize() const
01631 { return cvSize(saturate_cast<int>(width), saturate_cast<int>(height)); }
01632 template<typename _Tp> inline Size_<_Tp>::operator CvSize2D32f() const
01633 { return cvSize2D32f((float)width, (float)height); }
01634
01635 template<typename _Tp> inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
01636 { width = sz.width; height = sz.height; return *this; }
01637 template<typename _Tp> static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
01638 { return Size_<_Tp>(a.width * b, a.height * b); }
01639 template<typename _Tp> static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
01640 { return Size_<_Tp>(a.width + b.width, a.height + b.height); }
01641 template<typename _Tp> static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
01642 { return Size_<_Tp>(a.width - b.width, a.height - b.height); }
01643 template<typename _Tp> inline _Tp Size_<_Tp>::area() const { return width*height; }
01644
01645 template<typename _Tp> static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
01646 { a.width += b.width; a.height += b.height; return a; }
01647 template<typename _Tp> static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
01648 { a.width -= b.width; a.height -= b.height; return a; }
01649
01650 template<typename _Tp> static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
01651 { return a.width == b.width && a.height == b.height; }
01652 template<typename _Tp> static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
01653 { return a.width != b.width || a.height != b.height; }
01654
01656
01657
01658 template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {}
01659 template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {}
01660 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
01661 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) {}
01662 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) :
01663 x(org.x), y(org.y), width(sz.width), height(sz.height) {}
01664 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
01665 {
01666 x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y);
01667 width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y;
01668 }
01669 template<typename _Tp> inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
01670 { x = r.x; y = r.y; width = r.width; height = r.height; return *this; }
01671
01672 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); }
01673 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); }
01674
01675 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
01676 { a.x += b.x; a.y += b.y; return a; }
01677 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
01678 { a.x -= b.x; a.y -= b.y; return a; }
01679
01680 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
01681 { a.width += b.width; a.height += b.height; return a; }
01682
01683 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
01684 { a.width -= b.width; a.height -= b.height; return a; }
01685
01686 template<typename _Tp> static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
01687 {
01688 _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
01689 a.width = std::min(a.x + a.width, b.x + b.width) - x1;
01690 a.height = std::min(a.y + a.height, b.y + b.height) - y1;
01691 a.x = x1; a.y = y1;
01692 if( a.width <= 0 || a.height <= 0 )
01693 a = Rect();
01694 return a;
01695 }
01696
01697 template<typename _Tp> static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
01698 {
01699 _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
01700 a.width = std::max(a.x + a.width, b.x + b.width) - x1;
01701 a.height = std::max(a.y + a.height, b.y + b.height) - y1;
01702 a.x = x1; a.y = y1;
01703 return a;
01704 }
01705
01706 template<typename _Tp> inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); }
01707 template<typename _Tp> inline _Tp Rect_<_Tp>::area() const { return width*height; }
01708
01709 template<typename _Tp> template<typename _Tp2> inline Rect_<_Tp>::operator Rect_<_Tp2>() const
01710 { return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y),
01711 saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
01712 template<typename _Tp> inline Rect_<_Tp>::operator CvRect() const
01713 { return cvRect(saturate_cast<int>(x), saturate_cast<int>(y),
01714 saturate_cast<int>(width), saturate_cast<int>(height)); }
01715
01716 template<typename _Tp> inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
01717 { return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; }
01718
01719 template<typename _Tp> static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
01720 {
01721 return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
01722 }
01723
01724 template<typename _Tp> static inline bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
01725 {
01726 return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
01727 }
01728
01729 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
01730 {
01731 return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
01732 }
01733
01734 template<typename _Tp> static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
01735 {
01736 return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
01737 }
01738
01739 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
01740 {
01741 return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
01742 }
01743
01744 template<typename _Tp> static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
01745 {
01746 Rect_<_Tp> c = a;
01747 return c &= b;
01748 }
01749
01750 template<typename _Tp> static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
01751 {
01752 Rect_<_Tp> c = a;
01753 return c |= b;
01754 }
01755
01756 template<typename _Tp> inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
01757 {
01758 return r.contains(*this);
01759 }
01760
01761 inline RotatedRect::RotatedRect() { angle = 0; }
01762 inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
01763 : center(_center), size(_size), angle(_angle) {}
01764 inline RotatedRect::RotatedRect(const CvBox2D& box)
01765 : center(box.center), size(box.size), angle(box.angle) {}
01766 inline RotatedRect::operator CvBox2D() const
01767 {
01768 CvBox2D box; box.center = center; box.size = size; box.angle = angle;
01769 return box;
01770 }
01771
01773
01774 template<typename _Tp> inline Scalar_<_Tp>::Scalar_()
01775 { this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; }
01776
01777 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
01778 { this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; }
01779
01780 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(const CvScalar& s)
01781 {
01782 this->val[0] = saturate_cast<_Tp>(s.val[0]);
01783 this->val[1] = saturate_cast<_Tp>(s.val[1]);
01784 this->val[2] = saturate_cast<_Tp>(s.val[2]);
01785 this->val[3] = saturate_cast<_Tp>(s.val[3]);
01786 }
01787
01788 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0)
01789 { this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; }
01790
01791 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
01792 { return Scalar_<_Tp>(v0, v0, v0, v0); }
01793 template<typename _Tp> inline Scalar_<_Tp>::operator CvScalar() const
01794 { return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); }
01795
01796 template<typename _Tp> template<typename T2> inline Scalar_<_Tp>::operator Scalar_<T2>() const
01797 {
01798 return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
01799 saturate_cast<T2>(this->val[1]),
01800 saturate_cast<T2>(this->val[2]),
01801 saturate_cast<T2>(this->val[3]));
01802 }
01803
01804 template<typename _Tp> static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01805 {
01806 a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]);
01807 a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]);
01808 a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]);
01809 a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]);
01810 return a;
01811 }
01812
01813 template<typename _Tp> static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01814 {
01815 a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]);
01816 a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]);
01817 a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]);
01818 a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]);
01819 return a;
01820 }
01821
01822 template<typename _Tp> static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
01823 {
01824 a.val[0] = saturate_cast<_Tp>(a.val[0] * v);
01825 a.val[1] = saturate_cast<_Tp>(a.val[1] * v);
01826 a.val[2] = saturate_cast<_Tp>(a.val[2] * v);
01827 a.val[3] = saturate_cast<_Tp>(a.val[3] * v);
01828 return a;
01829 }
01830
01831 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const
01832 {
01833 return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale),
01834 saturate_cast<_Tp>(this->val[1]*t.val[1]*scale),
01835 saturate_cast<_Tp>(this->val[2]*t.val[2]*scale),
01836 saturate_cast<_Tp>(this->val[3]*t.val[3]*scale));
01837 }
01838
01839 template<typename _Tp> static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
01840 {
01841 return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
01842 a.val[2] == b.val[2] && a.val[3] == b.val[3];
01843 }
01844
01845 template<typename _Tp> static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
01846 {
01847 return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
01848 a.val[2] != b.val[2] || a.val[3] != b.val[3];
01849 }
01850
01851 template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01852 {
01853 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]),
01854 saturate_cast<_Tp>(a.val[1] + b.val[1]),
01855 saturate_cast<_Tp>(a.val[2] + b.val[2]),
01856 saturate_cast<_Tp>(a.val[3] + b.val[3]));
01857 }
01858
01859 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01860 {
01861 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
01862 saturate_cast<_Tp>(a.val[1] - b.val[1]),
01863 saturate_cast<_Tp>(a.val[2] - b.val[2]),
01864 saturate_cast<_Tp>(a.val[3] - b.val[3]));
01865 }
01866
01867 template<typename _Tp> static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
01868 {
01869 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha),
01870 saturate_cast<_Tp>(a.val[1] * alpha),
01871 saturate_cast<_Tp>(a.val[2] * alpha),
01872 saturate_cast<_Tp>(a.val[3] * alpha));
01873 }
01874
01875 template<typename _Tp> static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
01876 {
01877 return a*alpha;
01878 }
01879
01880 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
01881 {
01882 return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]),
01883 saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3]));
01884 }
01885
01886
01887 template<typename _Tp> static inline Scalar_<_Tp>
01888 operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01889 {
01890 return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]),
01891 saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]),
01892 saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] - a[3]*b[1]),
01893 saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] - a[3]*b[0]));
01894 }
01895
01896 template<typename _Tp> static inline Scalar_<_Tp>&
01897 operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01898 {
01899 a = a*b;
01900 return a;
01901 }
01902
01903 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::conj() const
01904 {
01905 return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0]),
01906 saturate_cast<_Tp>(-this->val[1]),
01907 saturate_cast<_Tp>(-this->val[2]),
01908 saturate_cast<_Tp>(-this->val[3]));
01909 }
01910
01911 template<typename _Tp> inline bool Scalar_<_Tp>::isReal() const
01912 {
01913 return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0;
01914 }
01915
01916 template<typename _Tp> static inline
01917 Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha)
01918 {
01919 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] / alpha),
01920 saturate_cast<_Tp>(a.val[1] / alpha),
01921 saturate_cast<_Tp>(a.val[2] / alpha),
01922 saturate_cast<_Tp>(a.val[3] / alpha));
01923 }
01924
01925 template<typename _Tp> static inline
01926 Scalar_<float> operator / (const Scalar_<float>& a, float alpha)
01927 {
01928 float s = 1/alpha;
01929 return Scalar_<float>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
01930 }
01931
01932 template<typename _Tp> static inline
01933 Scalar_<double> operator / (const Scalar_<double>& a, double alpha)
01934 {
01935 double s = 1/alpha;
01936 return Scalar_<double>(a.val[0]*s, a.val[1]*s, a.val[2]*s, a.val[3]*s);
01937 }
01938
01939 template<typename _Tp> static inline
01940 Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha)
01941 {
01942 a = a/alpha;
01943 return a;
01944 }
01945
01946 template<typename _Tp> static inline
01947 Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b)
01948 {
01949 _Tp s = a/(b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]);
01950 return b.conj()*s;
01951 }
01952
01953 template<typename _Tp> static inline
01954 Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01955 {
01956 return a*((_Tp)1/b);
01957 }
01958
01959 template<typename _Tp> static inline
01960 Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01961 {
01962 a = a/b;
01963 return a;
01964 }
01965
01967
01968 inline Range::Range() : start(0), end(0) {}
01969 inline Range::Range(int _start, int _end) : start(_start), end(_end) {}
01970 inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index)
01971 {
01972 if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX )
01973 *this = Range::all();
01974 }
01975
01976 inline int Range::size() const { return end - start; }
01977 inline bool Range::empty() const { return start == end; }
01978 inline Range Range::all() { return Range(INT_MIN, INT_MAX); }
01979
01980 static inline bool operator == (const Range& r1, const Range& r2)
01981 { return r1.start == r2.start && r1.end == r2.end; }
01982
01983 static inline bool operator != (const Range& r1, const Range& r2)
01984 { return !(r1 == r2); }
01985
01986 static inline bool operator !(const Range& r)
01987 { return r.start == r.end; }
01988
01989 static inline Range operator & (const Range& r1, const Range& r2)
01990 {
01991 Range r(std::max(r1.start, r2.start), std::min(r2.start, r2.end));
01992 r.end = std::max(r.end, r.start);
01993 return r;
01994 }
01995
01996 static inline Range& operator &= (Range& r1, const Range& r2)
01997 {
01998 r1 = r1 & r2;
01999 return r1;
02000 }
02001
02002 static inline Range operator + (const Range& r1, int delta)
02003 {
02004 return Range(r1.start + delta, r1.end + delta);
02005 }
02006
02007 static inline Range operator + (int delta, const Range& r1)
02008 {
02009 return Range(r1.start + delta, r1.end + delta);
02010 }
02011
02012 static inline Range operator - (const Range& r1, int delta)
02013 {
02014 return r1 + (-delta);
02015 }
02016
02017 inline Range::operator CvSlice() const
02018 { return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; }
02019
02020
02021
02023
02024
02025
02026
02027
02028
02029 template <typename _Tp> class CV_EXPORTS Vector
02030 {
02031 public:
02032 typedef _Tp value_type;
02033 typedef _Tp* iterator;
02034 typedef const _Tp* const_iterator;
02035 typedef _Tp& reference;
02036 typedef const _Tp& const_reference;
02037
02038 struct CV_EXPORTS Hdr
02039 {
02040 Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
02041 _Tp* data;
02042 _Tp* datastart;
02043 int* refcount;
02044 size_t size;
02045 size_t capacity;
02046 };
02047
02048 Vector() {}
02049 Vector(size_t _size) { resize(_size); }
02050 Vector(size_t _size, const _Tp& val)
02051 {
02052 resize(_size);
02053 for(size_t i = 0; i < _size; i++)
02054 hdr.data[i] = val;
02055 }
02056 Vector(_Tp* _data, size_t _size, bool _copyData=false)
02057 { set(_data, _size, _copyData); }
02058
02059 template<int n> Vector(const Vec<_Tp, n>& vec)
02060 { set((_Tp*)&vec.val[0], n, true); }
02061
02062 Vector(const std::vector<_Tp>& vec, bool _copyData=false)
02063 { set((_Tp*)&vec[0], vec.size(), _copyData); }
02064
02065 Vector(const Vector& d) { *this = d; }
02066
02067 Vector(const Vector& d, const Range& r_)
02068 {
02069 Range r = r_ == Range::all() ? Range(0, d.size()) : r_;
02070
02071
02072 if( r.size() > 0 && r.start >= 0 && r.end <= d.size() )
02073 {
02074 if( d.hdr.refcount )
02075 CV_XADD(d.hdr.refcount, 1);
02076 hdr.refcount = d.hdr.refcount;
02077 hdr.datastart = d.hdr.datastart;
02078 hdr.data = d.hdr.data + r.start;
02079 hdr.capacity = hdr.size = r.size();
02080 }
02081 }
02082
02083 Vector<_Tp>& operator = (const Vector& d)
02084 {
02085 if( this != &d )
02086 {
02087 if( d.hdr.refcount )
02088 CV_XADD(d.hdr.refcount, 1);
02089 release();
02090 hdr = d.hdr;
02091 }
02092 return *this;
02093 }
02094
02095 ~Vector() { release(); }
02096
02097 Vector<_Tp> clone() const
02098 { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); }
02099
02100 void copyTo(Vector<_Tp>& vec) const
02101 {
02102 size_t i, sz = size();
02103 vec.resize(sz);
02104 const _Tp* src = hdr.data;
02105 _Tp* dst = vec.hdr.data;
02106 for( i = 0; i < sz; i++ )
02107 dst[i] = src[i];
02108 }
02109
02110 void copyTo(std::vector<_Tp>& vec) const
02111 {
02112 size_t i, sz = size();
02113 vec.resize(sz);
02114 const _Tp* src = hdr.data;
02115 _Tp* dst = sz ? &vec[0] : 0;
02116 for( i = 0; i < sz; i++ )
02117 dst[i] = src[i];
02118 }
02119
02120 operator CvMat() const
02121 { return cvMat((int)size(), 1, type(), (void*)hdr.data); }
02122
02123 _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; }
02124 const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; }
02125 Vector operator() (const Range& r) const { return Vector(*this, r); }
02126 _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
02127 const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
02128 _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; }
02129 const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; }
02130
02131 _Tp* begin() { return hdr.data; }
02132 _Tp* end() { return hdr.data + hdr.size; }
02133 const _Tp* begin() const { return hdr.data; }
02134 const _Tp* end() const { return hdr.data + hdr.size; }
02135
02136 void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); }
02137 void release()
02138 {
02139 if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 )
02140 {
02141 delete[] hdr.datastart;
02142 delete hdr.refcount;
02143 }
02144 hdr = Hdr();
02145 }
02146
02147 void set(_Tp* _data, size_t _size, bool _copyData=false)
02148 {
02149 if( !_copyData )
02150 {
02151 release();
02152 hdr.data = hdr.datastart = _data;
02153 hdr.size = hdr.capacity = _size;
02154 hdr.refcount = 0;
02155 }
02156 else
02157 {
02158 reserve(_size);
02159 for( size_t i = 0; i < _size; i++ )
02160 hdr.data[i] = _data[i];
02161 hdr.size = _size;
02162 }
02163 }
02164
02165 void reserve(size_t newCapacity)
02166 {
02167 _Tp* newData;
02168 int* newRefcount;
02169 size_t i, oldSize = hdr.size;
02170 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity )
02171 return;
02172 newCapacity = std::max(newCapacity, oldSize);
02173 newData = new _Tp[newCapacity];
02174 newRefcount = new int(1);
02175 for( i = 0; i < oldSize; i++ )
02176 newData[i] = hdr.data[i];
02177 release();
02178 hdr.data = hdr.datastart = newData;
02179 hdr.capacity = newCapacity;
02180 hdr.size = oldSize;
02181 hdr.refcount = newRefcount;
02182 }
02183
02184 void resize(size_t newSize)
02185 {
02186 size_t i;
02187 newSize = std::max(newSize, (size_t)0);
02188 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize )
02189 return;
02190 if( newSize > hdr.capacity )
02191 reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2)));
02192 for( i = hdr.size; i < newSize; i++ )
02193 hdr.data[i] = _Tp();
02194 hdr.size = newSize;
02195 }
02196
02197 Vector<_Tp>& push_back(const _Tp& elem)
02198 {
02199 if( hdr.size == hdr.capacity )
02200 reserve( std::max((size_t)4, hdr.capacity*2) );
02201 hdr.data[hdr.size++] = elem;
02202 return *this;
02203 }
02204
02205 Vector<_Tp>& pop_back()
02206 {
02207 if( hdr.size > 0 )
02208 --hdr.size;
02209 return *this;
02210 }
02211
02212 size_t size() const { return hdr.size; }
02213 size_t capacity() const { return hdr.capacity; }
02214 bool empty() const { return hdr.size == 0; }
02215 void clear() { resize(0); }
02216 int type() const { return DataType<_Tp>::type; }
02217
02218 protected:
02219 Hdr hdr;
02220 };
02221
02222
02223 template<typename _Tp> inline typename DataType<_Tp>::work_type
02224 dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2)
02225 {
02226 typedef typename DataType<_Tp>::work_type _Tw;
02227 size_t i, n = v1.size();
02228 assert(v1.size() == v2.size());
02229
02230 _Tw s = 0;
02231 const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0];
02232 for( i = 0; i <= n - 4; i += 4 )
02233 s += (_Tw)ptr1[i]*ptr2[i] + (_Tw)ptr1[i+1]*ptr2[i+1] +
02234 (_Tw)ptr1[i+2]*ptr2[i+2] + (_Tw)ptr1[i+3]*ptr2[i+3];
02235 for( ; i < n; i++ )
02236 s += (_Tw)ptr1[i]*ptr2[i];
02237 return s;
02238 }
02239
02240
02241 inline RNG::RNG() { state = 0xffffffff; }
02242 inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
02243 inline unsigned RNG::next()
02244 {
02245 state = (uint64)(unsigned)state*CV_RNG_COEFF + (unsigned)(state >> 32);
02246 return (unsigned)state;
02247 }
02248
02249 inline RNG::operator uchar() { return (uchar)next(); }
02250 inline RNG::operator schar() { return (schar)next(); }
02251 inline RNG::operator ushort() { return (ushort)next(); }
02252 inline RNG::operator short() { return (short)next(); }
02253 inline RNG::operator unsigned() { return next(); }
02254 inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);}
02255 inline unsigned RNG::operator ()() {return next();}
02256 inline RNG::operator int() { return (int)next(); }
02257
02258 inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
02259 inline RNG::operator double()
02260 {
02261 unsigned t = next();
02262 return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20;
02263 }
02264 inline int RNG::uniform(int a, int b) { return a == b ? a : next()%(b - a) + a; }
02265 inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
02266 inline double RNG::uniform(double a, double b) { return ((float)*this)*(b - a) + a; }
02267
02268 inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {}
02269 inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
02270 : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
02271 inline TermCriteria::TermCriteria(const CvTermCriteria& criteria)
02272 : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {}
02273 inline TermCriteria::operator CvTermCriteria() const
02274 { return cvTermCriteria(type, maxCount, epsilon); }
02275
02276 inline uchar* LineIterator::operator *() { return ptr; }
02277 inline LineIterator& LineIterator::operator ++()
02278 {
02279 int mask = err < 0 ? -1 : 0;
02280 err += minusDelta + (plusDelta & mask);
02281 ptr += minusStep + (plusStep & mask);
02282 return *this;
02283 }
02284 inline LineIterator LineIterator::operator ++(int)
02285 {
02286 LineIterator it = *this;
02287 ++(*this);
02288 return it;
02289 }
02290 inline Point LineIterator::pos() const
02291 {
02292 Point p;
02293 p.y = (int)((ptr - ptr0)/step);
02294 p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize);
02295 return p;
02296 }
02297
02299
02300 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
02301 : ptr(buf), size(fixed_size) {}
02302
02303 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
02304 : ptr(buf), size(fixed_size) { allocate(_size); }
02305
02306 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
02307 { deallocate(); }
02308
02309 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
02310 {
02311 if(_size <= size)
02312 return;
02313 deallocate();
02314 if(_size > fixed_size)
02315 {
02316 ptr = cv::allocate<_Tp>(_size);
02317 size = _size;
02318 }
02319 }
02320
02321 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
02322 {
02323 if( ptr != buf )
02324 {
02325 cv::deallocate<_Tp>(ptr, size);
02326 ptr = buf;
02327 size = fixed_size;
02328 }
02329 }
02330
02331 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
02332 { return ptr; }
02333
02334 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
02335 { return ptr; }
02336
02337
02339
02340 template<typename _Tp> inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {}
02341 template<typename _Tp> inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj)
02342 {
02343 if(obj)
02344 {
02345 refcount = (int*)fastMalloc(sizeof(*refcount));
02346 *refcount = 1;
02347 }
02348 else
02349 refcount = 0;
02350 }
02351
02352 template<typename _Tp> inline void Ptr<_Tp>::addref()
02353 { if( refcount ) CV_XADD(refcount, 1); }
02354
02355 template<typename _Tp> inline void Ptr<_Tp>::release()
02356 {
02357 if( refcount && CV_XADD(refcount, -1) == 1 )
02358 {
02359 delete_obj();
02360 fastFree(refcount);
02361 }
02362 refcount = 0;
02363 obj = 0;
02364 }
02365
02366 template<typename _Tp> inline void Ptr<_Tp>::delete_obj()
02367 {
02368 if( obj ) delete obj;
02369 }
02370
02371 template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); }
02372
02373 template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr)
02374 {
02375 obj = ptr.obj;
02376 refcount = ptr.refcount;
02377 addref();
02378 }
02379
02380 template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr)
02381 {
02382 int* _refcount = ptr.refcount;
02383 if( _refcount )
02384 CV_XADD(_refcount, 1);
02385 release();
02386 obj = ptr.obj;
02387 refcount = _refcount;
02388 return *this;
02389 }
02390
02391 template<typename _Tp> inline _Tp* Ptr<_Tp>::operator -> () { return obj; }
02392 template<typename _Tp> inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; }
02393
02394 template<typename _Tp> inline Ptr<_Tp>::operator _Tp* () { return obj; }
02395 template<typename _Tp> inline Ptr<_Tp>::operator const _Tp*() const { return obj; }
02396
02397 template<typename _Tp> inline bool Ptr<_Tp>::empty() const { return obj == 0; }
02398
02400
02401 template<> CV_EXPORTS void Ptr<CvMat>::delete_obj();
02402 template<> CV_EXPORTS void Ptr<IplImage>::delete_obj();
02403 template<> CV_EXPORTS void Ptr<CvMatND>::delete_obj();
02404 template<> CV_EXPORTS void Ptr<CvSparseMat>::delete_obj();
02405 template<> CV_EXPORTS void Ptr<CvMemStorage>::delete_obj();
02406 template<> CV_EXPORTS void Ptr<CvFileStorage>::delete_obj();
02407
02409
02410 CV_EXPORTS_W void write( FileStorage& fs, const string& name, int value );
02411 CV_EXPORTS_W void write( FileStorage& fs, const string& name, float value );
02412 CV_EXPORTS_W void write( FileStorage& fs, const string& name, double value );
02413 CV_EXPORTS_W void write( FileStorage& fs, const string& name, const string& value );
02414
02415 template<typename _Tp> inline void write(FileStorage& fs, const _Tp& value)
02416 { write(fs, string(), value); }
02417
02418 CV_EXPORTS void writeScalar( FileStorage& fs, int value );
02419 CV_EXPORTS void writeScalar( FileStorage& fs, float value );
02420 CV_EXPORTS void writeScalar( FileStorage& fs, double value );
02421 CV_EXPORTS void writeScalar( FileStorage& fs, const string& value );
02422
02423 template<> inline void write( FileStorage& fs, const int& value )
02424 {
02425 writeScalar(fs, value);
02426 }
02427
02428 template<> inline void write( FileStorage& fs, const float& value )
02429 {
02430 writeScalar(fs, value);
02431 }
02432
02433 template<> inline void write( FileStorage& fs, const double& value )
02434 {
02435 writeScalar(fs, value);
02436 }
02437
02438 template<> inline void write( FileStorage& fs, const string& value )
02439 {
02440 writeScalar(fs, value);
02441 }
02442
02443 template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt )
02444 {
02445 write(fs, pt.x);
02446 write(fs, pt.y);
02447 }
02448
02449 template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt )
02450 {
02451 write(fs, pt.x);
02452 write(fs, pt.y);
02453 write(fs, pt.z);
02454 }
02455
02456 template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz )
02457 {
02458 write(fs, sz.width);
02459 write(fs, sz.height);
02460 }
02461
02462 template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c )
02463 {
02464 write(fs, c.re);
02465 write(fs, c.im);
02466 }
02467
02468 template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r )
02469 {
02470 write(fs, r.x);
02471 write(fs, r.y);
02472 write(fs, r.width);
02473 write(fs, r.height);
02474 }
02475
02476 template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v )
02477 {
02478 for(int i = 0; i < cn; i++)
02479 write(fs, v.val[i]);
02480 }
02481
02482 template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s )
02483 {
02484 write(fs, s.val[0]);
02485 write(fs, s.val[1]);
02486 write(fs, s.val[2]);
02487 write(fs, s.val[3]);
02488 }
02489
02490 inline void write(FileStorage& fs, const Range& r )
02491 {
02492 write(fs, r.start);
02493 write(fs, r.end);
02494 }
02495
02496 class CV_EXPORTS WriteStructContext
02497 {
02498 public:
02499 WriteStructContext(FileStorage& _fs, const string& name,
02500 int flags, const string& typeName=string());
02501 ~WriteStructContext();
02502 FileStorage* fs;
02503 };
02504
02505 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt )
02506 {
02507 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02508 write(fs, pt.x);
02509 write(fs, pt.y);
02510 }
02511
02512 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt )
02513 {
02514 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02515 write(fs, pt.x);
02516 write(fs, pt.y);
02517 write(fs, pt.z);
02518 }
02519
02520 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz )
02521 {
02522 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02523 write(fs, sz.width);
02524 write(fs, sz.height);
02525 }
02526
02527 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c )
02528 {
02529 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02530 write(fs, c.re);
02531 write(fs, c.im);
02532 }
02533
02534 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r )
02535 {
02536 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02537 write(fs, r.x);
02538 write(fs, r.y);
02539 write(fs, r.width);
02540 write(fs, r.height);
02541 }
02542
02543 template<typename _Tp, int cn> inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v )
02544 {
02545 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02546 for(int i = 0; i < cn; i++)
02547 write(fs, v.val[i]);
02548 }
02549
02550 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s )
02551 {
02552 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02553 write(fs, s.val[0]);
02554 write(fs, s.val[1]);
02555 write(fs, s.val[2]);
02556 write(fs, s.val[3]);
02557 }
02558
02559 inline void write(FileStorage& fs, const string& name, const Range& r )
02560 {
02561 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
02562 write(fs, r.start);
02563 write(fs, r.end);
02564 }
02565
02566 template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy
02567 {
02568 public:
02569 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
02570 void operator()(const vector<_Tp>& vec) const
02571 {
02572 size_t i, count = vec.size();
02573 for( i = 0; i < count; i++ )
02574 write( *fs, vec[i] );
02575 }
02576 FileStorage* fs;
02577 };
02578
02579 template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1>
02580 {
02581 public:
02582 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
02583 void operator()(const vector<_Tp>& vec) const
02584 {
02585 int _fmt = DataType<_Tp>::fmt;
02586 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
02587 fs->writeRaw( string(fmt), (uchar*)&vec[0], vec.size()*sizeof(_Tp) );
02588 }
02589 FileStorage* fs;
02590 };
02591
02592
02593 template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec )
02594 {
02595 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
02596 w(vec);
02597 }
02598
02599 template<typename _Tp> static inline FileStorage&
02600 operator << ( FileStorage& fs, const vector<_Tp>& vec )
02601 {
02602 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
02603 w(vec);
02604 return fs;
02605 }
02606
02607 CV_EXPORTS_W void write( FileStorage& fs, const string& name, const Mat& value );
02608 CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value );
02609
02610 template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
02611 {
02612 if( !fs.isOpened() )
02613 return fs;
02614 if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
02615 CV_Error( CV_StsError, "No element name has been given" );
02616 write( fs, fs.elname, value );
02617 if( fs.state & FileStorage::INSIDE_MAP )
02618 fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
02619 return fs;
02620 }
02621
02622 CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str);
02623
02624 static inline FileStorage& operator << (FileStorage& fs, const char* str)
02625 { return (fs << string(str)); }
02626
02627 inline FileNode::FileNode() : fs(0), node(0) {}
02628 inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
02629 : fs(_fs), node(_node) {}
02630
02631 inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
02632
02633 inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
02634 inline bool FileNode::empty() const { return node == 0; }
02635 inline bool FileNode::isNone() const { return type() == NONE; }
02636 inline bool FileNode::isSeq() const { return type() == SEQ; }
02637 inline bool FileNode::isMap() const { return type() == MAP; }
02638 inline bool FileNode::isInt() const { return type() == INT; }
02639 inline bool FileNode::isReal() const { return type() == REAL; }
02640 inline bool FileNode::isString() const { return type() == STR; }
02641 inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
02642 inline size_t FileNode::size() const
02643 {
02644 int t = type();
02645 return t == MAP ? ((CvSet*)node->data.map)->active_count :
02646 t == SEQ ? node->data.seq->total : node != 0;
02647 }
02648
02649 inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
02650 inline const CvFileNode* FileNode::operator* () const { return node; }
02651
02652 static inline void read(const FileNode& node, int& value, int default_value)
02653 {
02654 value = !node.node ? default_value :
02655 CV_NODE_IS_INT(node.node->tag) ? node.node->data.i :
02656 CV_NODE_IS_REAL(node.node->tag) ? cvRound(node.node->data.f) : 0x7fffffff;
02657 }
02658
02659 static inline void read(const FileNode& node, bool& value, bool default_value)
02660 {
02661 int temp; read(node, temp, (int)default_value);
02662 value = temp != 0;
02663 }
02664
02665 static inline void read(const FileNode& node, uchar& value, uchar default_value)
02666 {
02667 int temp; read(node, temp, (int)default_value);
02668 value = saturate_cast<uchar>(temp);
02669 }
02670
02671 static inline void read(const FileNode& node, schar& value, schar default_value)
02672 {
02673 int temp; read(node, temp, (int)default_value);
02674 value = saturate_cast<schar>(temp);
02675 }
02676
02677 static inline void read(const FileNode& node, ushort& value, ushort default_value)
02678 {
02679 int temp; read(node, temp, (int)default_value);
02680 value = saturate_cast<ushort>(temp);
02681 }
02682
02683 static inline void read(const FileNode& node, short& value, short default_value)
02684 {
02685 int temp; read(node, temp, (int)default_value);
02686 value = saturate_cast<short>(temp);
02687 }
02688
02689 static inline void read(const FileNode& node, float& value, float default_value)
02690 {
02691 value = !node.node ? default_value :
02692 CV_NODE_IS_INT(node.node->tag) ? (float)node.node->data.i :
02693 CV_NODE_IS_REAL(node.node->tag) ? (float)node.node->data.f : 1e30f;
02694 }
02695
02696 static inline void read(const FileNode& node, double& value, double default_value)
02697 {
02698 value = !node.node ? default_value :
02699 CV_NODE_IS_INT(node.node->tag) ? (double)node.node->data.i :
02700 CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : 1e300;
02701 }
02702
02703 static inline void read(const FileNode& node, string& value, const string& default_value)
02704 {
02705 value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? string(node.node->data.str.ptr) : string("");
02706 }
02707
02708 CV_EXPORTS_W void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
02709 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
02710
02711 inline FileNode::operator int() const
02712 {
02713 int value;
02714 read(*this, value, 0);
02715 return value;
02716 }
02717 inline FileNode::operator float() const
02718 {
02719 float value;
02720 read(*this, value, 0.f);
02721 return value;
02722 }
02723 inline FileNode::operator double() const
02724 {
02725 double value;
02726 read(*this, value, 0.);
02727 return value;
02728 }
02729 inline FileNode::operator string() const
02730 {
02731 string value;
02732 read(*this, value, value);
02733 return value;
02734 }
02735
02736 inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const
02737 {
02738 begin().readRaw( fmt, vec, len );
02739 }
02740
02741 template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy
02742 {
02743 public:
02744 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
02745 void operator()(vector<_Tp>& vec, size_t count) const
02746 {
02747 count = std::min(count, it->remaining);
02748 vec.resize(count);
02749 for( size_t i = 0; i < count; i++, ++(*it) )
02750 read(**it, vec[i], _Tp());
02751 }
02752 FileNodeIterator* it;
02753 };
02754
02755 template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1>
02756 {
02757 public:
02758 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
02759 void operator()(vector<_Tp>& vec, size_t count) const
02760 {
02761 size_t remaining = it->remaining, cn = DataType<_Tp>::channels;
02762 int _fmt = DataType<_Tp>::fmt;
02763 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
02764 count = std::min(count, remaining/cn);
02765 vec.resize(count);
02766 it->readRaw( string(fmt), (uchar*)&vec[0], count*sizeof(_Tp) );
02767 }
02768 FileNodeIterator* it;
02769 };
02770
02771 template<typename _Tp> static inline void
02772 read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
02773 {
02774 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
02775 r(vec, maxCount);
02776 }
02777
02778 template<typename _Tp> static inline void
02779 read( FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() )
02780 {
02781 read( node.begin(), vec );
02782 }
02783
02784 inline FileNodeIterator FileNode::begin() const
02785 {
02786 return FileNodeIterator(fs, node);
02787 }
02788
02789 inline FileNodeIterator FileNode::end() const
02790 {
02791 return FileNodeIterator(fs, node, size());
02792 }
02793
02794 inline FileNode FileNodeIterator::operator *() const
02795 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
02796
02797 inline FileNode FileNodeIterator::operator ->() const
02798 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
02799
02800 template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
02801 { read( *it, value, _Tp()); return ++it; }
02802
02803 template<typename _Tp> static inline
02804 FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec)
02805 {
02806 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
02807 r(vec, (size_t)INT_MAX);
02808 return it;
02809 }
02810
02811 template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value)
02812 { FileNodeIterator it = n.begin(); it >> value; }
02813
02814 static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
02815 {
02816 return it1.fs == it2.fs && it1.container == it2.container &&
02817 it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
02818 }
02819
02820 static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
02821 {
02822 return !(it1 == it2);
02823 }
02824
02825 static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
02826 {
02827 return it2.remaining - it1.remaining;
02828 }
02829
02830 static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
02831 {
02832 return it1.remaining > it2.remaining;
02833 }
02834
02835 inline FileNode FileStorage::getFirstTopLevelNode() const
02836 {
02837 FileNode r = root();
02838 FileNodeIterator it = r.begin();
02839 return it != r.end() ? *it : FileNode();
02840 }
02841
02843
02844 template<typename _Tp> static inline _Tp gcd(_Tp a, _Tp b)
02845 {
02846 if( a < b )
02847 std::swap(a, b);
02848 while( b > 0 )
02849 {
02850 _Tp r = a % b;
02851 a = b;
02852 b = r;
02853 }
02854 return a;
02855 }
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897 template<typename _Tp, class _LT> void sort( vector<_Tp>& vec, _LT LT=_LT() )
02898 {
02899 int isort_thresh = 7;
02900 int sp = 0;
02901
02902 struct
02903 {
02904 _Tp *lb;
02905 _Tp *ub;
02906 } stack[48];
02907
02908 size_t total = vec.size();
02909
02910 if( total <= 1 )
02911 return;
02912
02913 _Tp* arr = &vec[0];
02914 stack[0].lb = arr;
02915 stack[0].ub = arr + (total - 1);
02916
02917 while( sp >= 0 )
02918 {
02919 _Tp* left = stack[sp].lb;
02920 _Tp* right = stack[sp--].ub;
02921
02922 for(;;)
02923 {
02924 int i, n = (int)(right - left) + 1, m;
02925 _Tp* ptr;
02926 _Tp* ptr2;
02927
02928 if( n <= isort_thresh )
02929 {
02930 insert_sort:
02931 for( ptr = left + 1; ptr <= right; ptr++ )
02932 {
02933 for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)
02934 std::swap( ptr2[0], ptr2[-1] );
02935 }
02936 break;
02937 }
02938 else
02939 {
02940 _Tp* left0;
02941 _Tp* left1;
02942 _Tp* right0;
02943 _Tp* right1;
02944 _Tp* pivot;
02945 _Tp* a;
02946 _Tp* b;
02947 _Tp* c;
02948 int swap_cnt = 0;
02949
02950 left0 = left;
02951 right0 = right;
02952 pivot = left + (n/2);
02953
02954 if( n > 40 )
02955 {
02956 int d = n / 8;
02957 a = left, b = left + d, c = left + 2*d;
02958 left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02959 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02960
02961 a = pivot - d, b = pivot, c = pivot + d;
02962 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02963 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02964
02965 a = right - 2*d, b = right - d, c = right;
02966 right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02967 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02968 }
02969
02970 a = left, b = pivot, c = right;
02971 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02972 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02973 if( pivot != left0 )
02974 {
02975 std::swap( *pivot, *left0 );
02976 pivot = left0;
02977 }
02978 left = left1 = left0 + 1;
02979 right = right1 = right0;
02980
02981 for(;;)
02982 {
02983 while( left <= right && !LT(*pivot, *left) )
02984 {
02985 if( !LT(*left, *pivot) )
02986 {
02987 if( left > left1 )
02988 std::swap( *left1, *left );
02989 swap_cnt = 1;
02990 left1++;
02991 }
02992 left++;
02993 }
02994
02995 while( left <= right && !LT(*right, *pivot) )
02996 {
02997 if( !LT(*pivot, *right) )
02998 {
02999 if( right < right1 )
03000 std::swap( *right1, *right );
03001 swap_cnt = 1;
03002 right1--;
03003 }
03004 right--;
03005 }
03006
03007 if( left > right )
03008 break;
03009 std::swap( *left, *right );
03010 swap_cnt = 1;
03011 left++;
03012 right--;
03013 }
03014
03015 if( swap_cnt == 0 )
03016 {
03017 left = left0, right = right0;
03018 goto insert_sort;
03019 }
03020
03021 n = std::min( (int)(left1 - left0), (int)(left - left1) );
03022 for( i = 0; i < n; i++ )
03023 std::swap( left0[i], left[i-n] );
03024
03025 n = std::min( (int)(right0 - right1), (int)(right1 - right) );
03026 for( i = 0; i < n; i++ )
03027 std::swap( left[i], right0[i-n+1] );
03028 n = (int)(left - left1);
03029 m = (int)(right1 - right);
03030 if( n > 1 )
03031 {
03032 if( m > 1 )
03033 {
03034 if( n > m )
03035 {
03036 stack[++sp].lb = left0;
03037 stack[sp].ub = left0 + n - 1;
03038 left = right0 - m + 1, right = right0;
03039 }
03040 else
03041 {
03042 stack[++sp].lb = right0 - m + 1;
03043 stack[sp].ub = right0;
03044 left = left0, right = left0 + n - 1;
03045 }
03046 }
03047 else
03048 left = left0, right = left0 + n - 1;
03049 }
03050 else if( m > 1 )
03051 left = right0 - m + 1, right = right0;
03052 else
03053 break;
03054 }
03055 }
03056 }
03057 }
03058
03059 template<typename _Tp> class CV_EXPORTS LessThan
03060 {
03061 public:
03062 bool operator()(const _Tp& a, const _Tp& b) const { return a < b; }
03063 };
03064
03065 template<typename _Tp> class CV_EXPORTS GreaterEq
03066 {
03067 public:
03068 bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; }
03069 };
03070
03071 template<typename _Tp> class CV_EXPORTS LessThanIdx
03072 {
03073 public:
03074 LessThanIdx( const _Tp* _arr ) : arr(_arr) {}
03075 bool operator()(int a, int b) const { return arr[a] < arr[b]; }
03076 const _Tp* arr;
03077 };
03078
03079 template<typename _Tp> class CV_EXPORTS GreaterEqIdx
03080 {
03081 public:
03082 GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {}
03083 bool operator()(int a, int b) const { return arr[a] >= arr[b]; }
03084 const _Tp* arr;
03085 };
03086
03087
03088
03089
03090
03091
03092
03093
03094 template<typename _Tp, class _EqPredicate> int
03095 partition( const vector<_Tp>& _vec, vector<int>& labels,
03096 _EqPredicate predicate=_EqPredicate())
03097 {
03098 int i, j, N = (int)_vec.size();
03099 const _Tp* vec = &_vec[0];
03100
03101 const int PARENT=0;
03102 const int RANK=1;
03103
03104 vector<int> _nodes(N*2);
03105 int (*nodes)[2] = (int(*)[2])&_nodes[0];
03106
03107
03108 for(i = 0; i < N; i++)
03109 {
03110 nodes[i][PARENT]=-1;
03111 nodes[i][RANK] = 0;
03112 }
03113
03114
03115 for( i = 0; i < N; i++ )
03116 {
03117 int root = i;
03118
03119
03120 while( nodes[root][PARENT] >= 0 )
03121 root = nodes[root][PARENT];
03122
03123 for( j = 0; j < N; j++ )
03124 {
03125 if( i == j || !predicate(vec[i], vec[j]))
03126 continue;
03127 int root2 = j;
03128
03129 while( nodes[root2][PARENT] >= 0 )
03130 root2 = nodes[root2][PARENT];
03131
03132 if( root2 != root )
03133 {
03134
03135 int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
03136 if( rank > rank2 )
03137 nodes[root2][PARENT] = root;
03138 else
03139 {
03140 nodes[root][PARENT] = root2;
03141 nodes[root2][RANK] += rank == rank2;
03142 root = root2;
03143 }
03144 assert( nodes[root][PARENT] < 0 );
03145
03146 int k = j, parent;
03147
03148
03149 while( (parent = nodes[k][PARENT]) >= 0 )
03150 {
03151 nodes[k][PARENT] = root;
03152 k = parent;
03153 }
03154
03155
03156 k = i;
03157 while( (parent = nodes[k][PARENT]) >= 0 )
03158 {
03159 nodes[k][PARENT] = root;
03160 k = parent;
03161 }
03162 }
03163 }
03164 }
03165
03166
03167 labels.resize(N);
03168 int nclasses = 0;
03169
03170 for( i = 0; i < N; i++ )
03171 {
03172 int root = i;
03173 while( nodes[root][PARENT] >= 0 )
03174 root = nodes[root][PARENT];
03175
03176 if( nodes[root][RANK] >= 0 )
03177 nodes[root][RANK] = ~nclasses++;
03178 labels[i] = ~nodes[root][RANK];
03179 }
03180
03181 return nclasses;
03182 }
03183
03184
03186
03187
03188 CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0);
03189 CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0);
03190 CV_EXPORTS void seqPop( CvSeq* seq, void* element=0);
03191 CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0);
03192 CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements,
03193 int count, int in_front=0 );
03194 CV_EXPORTS void seqRemove( CvSeq* seq, int index );
03195 CV_EXPORTS void clearSeq( CvSeq* seq );
03196 CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index );
03197 CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice );
03198 CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
03199
03200 template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {}
03201 template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq)
03202 {
03203 CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp));
03204 }
03205
03206 template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage,
03207 int headerSize )
03208 {
03209 CV_Assert(headerSize >= (int)sizeof(CvSeq));
03210 seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage);
03211 }
03212
03213 template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx)
03214 { return *(_Tp*)getSeqElem(seq, idx); }
03215
03216 template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const
03217 { return *(_Tp*)getSeqElem(seq, idx); }
03218
03219 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const
03220 { return SeqIterator<_Tp>(*this); }
03221
03222 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const
03223 { return SeqIterator<_Tp>(*this, true); }
03224
03225 template<typename _Tp> inline size_t Seq<_Tp>::size() const
03226 { return seq ? seq->total : 0; }
03227
03228 template<typename _Tp> inline int Seq<_Tp>::type() const
03229 { return seq ? CV_MAT_TYPE(seq->flags) : 0; }
03230
03231 template<typename _Tp> inline int Seq<_Tp>::depth() const
03232 { return seq ? CV_MAT_DEPTH(seq->flags) : 0; }
03233
03234 template<typename _Tp> inline int Seq<_Tp>::channels() const
03235 { return seq ? CV_MAT_CN(seq->flags) : 0; }
03236
03237 template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const
03238 { return seq ? seq->elem_size : 0; }
03239
03240 template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const
03241 { return cvSeqElemIdx(seq, &elem); }
03242
03243 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem)
03244 { cvSeqPush(seq, &elem); }
03245
03246 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem)
03247 { cvSeqPushFront(seq, &elem); }
03248
03249 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count)
03250 { cvSeqPushMulti(seq, elem, (int)count, 0); }
03251
03252 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count)
03253 { cvSeqPushMulti(seq, elem, (int)count, 1); }
03254
03255 template<typename _Tp> inline _Tp& Seq<_Tp>::back()
03256 { return *(_Tp*)getSeqElem(seq, -1); }
03257
03258 template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const
03259 { return *(const _Tp*)getSeqElem(seq, -1); }
03260
03261 template<typename _Tp> inline _Tp& Seq<_Tp>::front()
03262 { return *(_Tp*)getSeqElem(seq, 0); }
03263
03264 template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const
03265 { return *(const _Tp*)getSeqElem(seq, 0); }
03266
03267 template<typename _Tp> inline bool Seq<_Tp>::empty() const
03268 { return !seq || seq->total == 0; }
03269
03270 template<typename _Tp> inline void Seq<_Tp>::clear()
03271 { if(seq) clearSeq(seq); }
03272
03273 template<typename _Tp> inline void Seq<_Tp>::pop_back()
03274 { seqPop(seq); }
03275
03276 template<typename _Tp> inline void Seq<_Tp>::pop_front()
03277 { seqPopFront(seq); }
03278
03279 template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count)
03280 { seqPopMulti(seq, elem, (int)count, 0); }
03281
03282 template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count)
03283 { seqPopMulti(seq, elem, (int)count, 1); }
03284
03285 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem)
03286 { seqInsert(seq, idx, &elem); }
03287
03288 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count)
03289 {
03290 CvMat m = cvMat(1, count, DataType<_Tp>::type, elems);
03291 seqInsertSlice(seq, idx, &m);
03292 }
03293
03294 template<typename _Tp> inline void Seq<_Tp>::remove(int idx)
03295 { seqRemove(seq, idx); }
03296
03297 template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r)
03298 { seqRemoveSlice(seq, r); }
03299
03300 template<typename _Tp> inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const
03301 {
03302 size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start;
03303 vec.resize(len);
03304 if( seq && len )
03305 cvCvtSeqToArray(seq, &vec[0], range);
03306 }
03307
03308 template<typename _Tp> inline Seq<_Tp>::operator vector<_Tp>() const
03309 {
03310 vector<_Tp> vec;
03311 copyTo(vec);
03312 return vec;
03313 }
03314
03315 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
03316 { memset(this, 0, sizeof(*this)); }
03317
03318 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd)
03319 {
03320 cvStartReadSeq(seq.seq, this);
03321 index = seekEnd ? seq.seq->total : 0;
03322 }
03323
03324 template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
03325 {
03326 cvSetSeqReaderPos(this, (int)pos, false);
03327 index = pos;
03328 }
03329
03330 template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const
03331 { return index; }
03332
03333 template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *()
03334 { return *(_Tp*)ptr; }
03335
03336 template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const
03337 { return *(const _Tp*)ptr; }
03338
03339 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++()
03340 {
03341 CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this);
03342 if( ++index >= seq->total*2 )
03343 index = 0;
03344 return *this;
03345 }
03346
03347 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const
03348 {
03349 SeqIterator<_Tp> it = *this;
03350 ++*this;
03351 return it;
03352 }
03353
03354 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --()
03355 {
03356 CV_PREV_SEQ_ELEM(sizeof(_Tp), *this);
03357 if( --index < 0 )
03358 index = seq->total*2-1;
03359 return *this;
03360 }
03361
03362 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const
03363 {
03364 SeqIterator<_Tp> it = *this;
03365 --*this;
03366 return it;
03367 }
03368
03369 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta)
03370 {
03371 cvSetSeqReaderPos(this, delta, 1);
03372 index += delta;
03373 int n = seq->total*2;
03374 if( index < 0 )
03375 index += n;
03376 if( index >= n )
03377 index -= n;
03378 return *this;
03379 }
03380
03381 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta)
03382 {
03383 return (*this += -delta);
03384 }
03385
03386 template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a,
03387 const SeqIterator<_Tp>& b)
03388 {
03389 ptrdiff_t delta = a.index - b.index, n = a.seq->total;
03390 if( std::abs(static_cast<long>(delta)) > n )
03391 delta += delta < 0 ? n : -n;
03392 return delta;
03393 }
03394
03395 template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a,
03396 const SeqIterator<_Tp>& b)
03397 {
03398 return a.seq == b.seq && a.index == b.index;
03399 }
03400
03401 template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
03402 const SeqIterator<_Tp>& b)
03403 {
03404 return !(a == b);
03405 }
03406
03407
03408 template<typename _ClsName> struct CV_EXPORTS RTTIImpl
03409 {
03410 public:
03411 static int isInstance(const void* ptr)
03412 {
03413 static _ClsName dummy;
03414 return *(const void**)&dummy == *(const void**)ptr;
03415 }
03416 static void release(void** dbptr)
03417 {
03418 if(dbptr && *dbptr)
03419 {
03420 delete (_ClsName*)*dbptr;
03421 *dbptr = 0;
03422 }
03423 }
03424 static void* read(CvFileStorage* fs, CvFileNode* n)
03425 {
03426 FileNode fn(fs, n);
03427 _ClsName* obj = new _ClsName;
03428 if(obj->read(fn))
03429 return obj;
03430 delete obj;
03431 return 0;
03432 }
03433
03434 static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList)
03435 {
03436 if(ptr && _fs)
03437 {
03438 FileStorage fs(_fs);
03439 fs.fs.addref();
03440 ((const _ClsName*)ptr)->write(fs, string(name));
03441 }
03442 }
03443
03444 static void* clone(const void* ptr)
03445 {
03446 if(!ptr)
03447 return 0;
03448 return new _ClsName(*(const _ClsName*)ptr);
03449 }
03450 };
03451
03452
03453 class CV_EXPORTS Formatter
03454 {
03455 public:
03456 virtual ~Formatter() {}
03457 virtual void write(std::ostream& out, const Mat& m, const int* params=0, int nparams=0) const = 0;
03458 virtual void write(std::ostream& out, const void* data, int nelems, int type,
03459 const int* params=0, int nparams=0) const = 0;
03460 static const Formatter* get(const char* fmt="");
03461 static const Formatter* setDefault(const Formatter* fmt);
03462 };
03463
03464
03465 struct CV_EXPORTS Formatted
03466 {
03467 Formatted(const Mat& m, const Formatter* fmt,
03468 const vector<int>& params);
03469 Formatted(const Mat& m, const Formatter* fmt,
03470 const int* params=0);
03471 Mat mtx;
03472 const Formatter* fmt;
03473 vector<int> params;
03474 };
03475
03476
03479 template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point_<_Tp>& p)
03480 {
03481 out << "[" << p.x << ", " << p.y << "]";
03482 return out;
03483 }
03484
03487 template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const Point3_<_Tp>& p)
03488 {
03489 out << "[" << p.x << ", " << p.y << ", " << p.z << "]";
03490 return out;
03491 }
03492
03493 static inline Formatted format(const Mat& mtx, const char* fmt,
03494 const vector<int>& params=vector<int>())
03495 {
03496 return Formatted(mtx, Formatter::get(fmt), params);
03497 }
03498
03499 template<typename _Tp> static inline Formatted format(const vector<Point_<_Tp> >& vec,
03500 const char* fmt, const vector<int>& params=vector<int>())
03501 {
03502 return Formatted(Mat(vec), Formatter::get(fmt), params);
03503 }
03504
03505 template<typename _Tp> static inline Formatted format(const vector<Point3_<_Tp> >& vec,
03506 const char* fmt, const vector<int>& params=vector<int>())
03507 {
03508 return Formatted(Mat(vec), Formatter::get(fmt), params);
03509 }
03510
03518 static inline std::ostream& operator << (std::ostream& out, const Mat& mtx)
03519 {
03520 Formatter::get()->write(out, mtx);
03521 return out;
03522 }
03523
03531 static inline std::ostream& operator << (std::ostream& out, const Formatted& fmtd)
03532 {
03533 fmtd.fmt->write(out, fmtd.mtx);
03534 return out;
03535 }
03536
03537
03538 template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
03539 const vector<Point_<_Tp> >& vec)
03540 {
03541 Formatter::get()->write(out, Mat(vec));
03542 return out;
03543 }
03544
03545
03546 template<typename _Tp> static inline std::ostream& operator << (std::ostream& out,
03547 const vector<Point3_<_Tp> >& vec)
03548 {
03549 Formatter::get()->write(out, Mat(vec));
03550 return out;
03551 }
03552
03553 }
03554
03555 #endif // __cplusplus
03556 #endif