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