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