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