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