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