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_H__ 00044 #define __OPENCV_CORE_OPERATIONS_H__ 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 WIN64 && !defined _WIN64 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 00105 namespace cv 00106 { 00107 00108 using std::cos; 00109 using std::sin; 00110 using std::max; 00111 using std::min; 00112 using std::exp; 00113 using std::log; 00114 using std::pow; 00115 using std::sqrt; 00116 00117 00119 00120 template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); } 00121 template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); } 00122 template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); } 00123 template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); } 00124 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } 00125 template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); } 00126 template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); } 00127 template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); } 00128 00129 template<> inline uchar saturate_cast<uchar>(schar v) 00130 { return (uchar)std::max((int)v, 0); } 00131 template<> inline uchar saturate_cast<uchar>(ushort v) 00132 { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } 00133 template<> inline uchar saturate_cast<uchar>(int v) 00134 { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } 00135 template<> inline uchar saturate_cast<uchar>(short v) 00136 { return saturate_cast<uchar>((int)v); } 00137 template<> inline uchar saturate_cast<uchar>(unsigned v) 00138 { return (uchar)std::min(v, (unsigned)UCHAR_MAX); } 00139 template<> inline uchar saturate_cast<uchar>(float v) 00140 { int iv = cvRound(v); return saturate_cast<uchar>(iv); } 00141 template<> inline uchar saturate_cast<uchar>(double v) 00142 { int iv = cvRound(v); return saturate_cast<uchar>(iv); } 00143 00144 template<> inline schar saturate_cast<schar>(uchar v) 00145 { return (schar)std::min((int)v, SCHAR_MAX); } 00146 template<> inline schar saturate_cast<schar>(ushort v) 00147 { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); } 00148 template<> inline schar saturate_cast<schar>(int v) 00149 { 00150 return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? 00151 v : v > 0 ? SCHAR_MAX : SCHAR_MIN); 00152 } 00153 template<> inline schar saturate_cast<schar>(short v) 00154 { return saturate_cast<schar>((int)v); } 00155 template<> inline schar saturate_cast<schar>(unsigned v) 00156 { return (schar)std::min(v, (unsigned)SCHAR_MAX); } 00157 00158 template<> inline schar saturate_cast<schar>(float v) 00159 { int iv = cvRound(v); return saturate_cast<schar>(iv); } 00160 template<> inline schar saturate_cast<schar>(double v) 00161 { int iv = cvRound(v); return saturate_cast<schar>(iv); } 00162 00163 template<> inline ushort saturate_cast<ushort>(schar v) 00164 { return (ushort)std::max((int)v, 0); } 00165 template<> inline ushort saturate_cast<ushort>(short v) 00166 { return (ushort)std::max((int)v, 0); } 00167 template<> inline ushort saturate_cast<ushort>(int v) 00168 { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } 00169 template<> inline ushort saturate_cast<ushort>(unsigned v) 00170 { return (ushort)std::min(v, (unsigned)USHRT_MAX); } 00171 template<> inline ushort saturate_cast<ushort>(float v) 00172 { int iv = cvRound(v); return saturate_cast<ushort>(iv); } 00173 template<> inline ushort saturate_cast<ushort>(double v) 00174 { int iv = cvRound(v); return saturate_cast<ushort>(iv); } 00175 00176 template<> inline short saturate_cast<short>(ushort v) 00177 { return (short)std::min((int)v, SHRT_MAX); } 00178 template<> inline short saturate_cast<short>(int v) 00179 { 00180 return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? 00181 v : v > 0 ? SHRT_MAX : SHRT_MIN); 00182 } 00183 template<> inline short saturate_cast<short>(unsigned v) 00184 { return (short)std::min(v, (unsigned)SHRT_MAX); } 00185 template<> inline short saturate_cast<short>(float v) 00186 { int iv = cvRound(v); return saturate_cast<short>(iv); } 00187 template<> inline short saturate_cast<short>(double v) 00188 { int iv = cvRound(v); return saturate_cast<short>(iv); } 00189 00190 template<> inline int saturate_cast<int>(float v) { return cvRound(v); } 00191 template<> inline int saturate_cast<int>(double v) { return cvRound(v); } 00192 00193 // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. 00194 template<> inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); } 00195 template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); } 00196 00197 00199 00200 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec() 00201 { 00202 for(int i = 0; i < cn; i++) val[i] = _Tp(0); 00203 } 00204 00205 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0) 00206 { 00207 val[0] = v0; 00208 for(int i = 1; i < cn; i++) val[i] = _Tp(0); 00209 } 00210 00211 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) 00212 { 00213 assert(cn >= 2); 00214 val[0] = v0; val[1] = v1; 00215 for(int i = 2; i < cn; i++) val[i] = _Tp(0); 00216 } 00217 00218 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) 00219 { 00220 assert(cn >= 3); 00221 val[0] = v0; val[1] = v1; val[2] = v2; 00222 for(int i = 3; i < cn; i++) val[i] = _Tp(0); 00223 } 00224 00225 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 00226 { 00227 assert(cn >= 4); 00228 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00229 for(int i = 4; i < cn; i++) val[i] = _Tp(0); 00230 } 00231 00232 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 00233 { 00234 assert(cn >= 5); 00235 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; 00236 for(int i = 5; i < cn; i++) val[i] = _Tp(0); 00237 } 00238 00239 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00240 _Tp v4, _Tp v5) 00241 { 00242 assert(cn >= 6); 00243 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00244 val[4] = v4; val[5] = v5; 00245 for(int i = 6; i < cn; i++) val[i] = _Tp(0); 00246 } 00247 00248 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00249 _Tp v4, _Tp v5, _Tp v6) 00250 { 00251 assert(cn >= 7); 00252 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00253 val[4] = v4; val[5] = v5; val[6] = v6; 00254 for(int i = 7; i < cn; i++) val[i] = _Tp(0); 00255 } 00256 00257 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00258 _Tp v4, _Tp v5, _Tp v6, _Tp v7) 00259 { 00260 assert(cn >= 8); 00261 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00262 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00263 for(int i = 8; i < cn; i++) val[i] = _Tp(0); 00264 } 00265 00266 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00267 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 00268 _Tp v8) 00269 { 00270 assert(cn >= 9); 00271 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00272 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00273 val[8] = v8; 00274 for(int i = 9; i < cn; i++) val[i] = _Tp(0); 00275 } 00276 00277 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00278 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 00279 _Tp v8, _Tp v9) 00280 { 00281 assert(cn >= 10); 00282 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00283 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00284 val[8] = v8; val[9] = v9; 00285 for(int i = 10; i < cn; i++) val[i] = _Tp(0); 00286 } 00287 00288 00289 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v) 00290 { 00291 for( int i = 0; i < cn; i++ ) val[i] = v.val[i]; 00292 } 00293 00294 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) 00295 { 00296 Vec v; 00297 for( int i = 0; i < cn; i++ ) v.val[i] = alpha; 00298 return v; 00299 } 00300 00301 template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::dot(const Vec<_Tp, cn>& v) const 00302 { 00303 _Tp s = 0; 00304 for( int i = 0; i < cn; i++ ) s += val[i]*v.val[i]; 00305 return s; 00306 } 00307 00308 template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, cn>& v) const 00309 { 00310 double s = 0; 00311 for( int i = 0; i < cn; i++ ) s += (double)val[i]*v.val[i]; 00312 return s; 00313 } 00314 00315 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const 00316 { 00317 return Vec<_Tp, cn>(); // for arbitrary-size vector there is no cross-product defined 00318 } 00319 00320 template<typename _Tp, int cn> template<typename T2> 00321 inline Vec<_Tp, cn>::operator Vec<T2, cn>() const 00322 { 00323 Vec<T2, cn> v; 00324 for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(val[i]); 00325 return v; 00326 } 00327 00328 template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const 00329 { 00330 CvScalar s = {{0,0,0,0}}; 00331 int i; 00332 for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = val[i]; 00333 for( ; i < 4; i++ ) s.val[i] = 0; 00334 return s; 00335 } 00336 00337 template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::operator [](int i) const { return val[i]; } 00338 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator[](int i) { return val[i]; } 00339 00340 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>& 00341 operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 00342 { 00343 for( int i = 0; i < cn; i++ ) 00344 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); 00345 return a; 00346 } 00347 00348 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>& 00349 operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 00350 { 00351 for( int i = 0; i < cn; i++ ) 00352 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); 00353 return a; 00354 } 00355 00356 template<typename _Tp, int cn> static inline Vec<_Tp, cn> 00357 operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 00358 { 00359 Vec<_Tp, cn> c = a; 00360 return c += b; 00361 } 00362 00363 template<typename _Tp, int cn> static inline Vec<_Tp, cn> 00364 operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 00365 { 00366 Vec<_Tp, cn> c = a; 00367 return c -= b; 00368 } 00369 00370 template<typename _Tp> static inline 00371 Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha) 00372 { 00373 a[0] *= alpha; a[1] *= alpha; 00374 return a; 00375 } 00376 00377 template<typename _Tp> static inline 00378 Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha) 00379 { 00380 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; 00381 return a; 00382 } 00383 00384 template<typename _Tp> static inline 00385 Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha) 00386 { 00387 a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha; 00388 return a; 00389 } 00390 00391 template<typename _Tp, int cn> static inline Vec<_Tp, cn> 00392 operator * (const Vec<_Tp, cn>& a, _Tp alpha) 00393 { 00394 Vec<_Tp, cn> c = a; 00395 return c *= alpha; 00396 } 00397 00398 template<typename _Tp, int cn> static inline Vec<_Tp, cn> 00399 operator * (_Tp alpha, const Vec<_Tp, cn>& a) 00400 { 00401 return a * alpha; 00402 } 00403 00404 template<typename _Tp, int cn> static inline Vec<_Tp, cn> 00405 operator - (const Vec<_Tp, cn>& a) 00406 { 00407 Vec<_Tp,cn> t; 00408 for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); 00409 return t; 00410 } 00411 00412 template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const 00413 { 00414 return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1], 00415 val[2]*v.val[0] - val[0]*v.val[2], 00416 val[0]*v.val[1] - val[1]*v.val[0]); 00417 } 00418 00419 template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const 00420 { 00421 return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1], 00422 val[2]*v.val[0] - val[0]*v.val[2], 00423 val[0]*v.val[1] - val[1]*v.val[0]); 00424 } 00425 00426 template<typename T1, typename T2> static inline 00427 Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b) 00428 { 00429 a[0] = saturate_cast<T1>(a[0] + b[0]); 00430 a[1] = saturate_cast<T1>(a[1] + b[1]); 00431 return a; 00432 } 00433 00434 template<typename T1, typename T2> static inline 00435 Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b) 00436 { 00437 a[0] = saturate_cast<T1>(a[0] + b[0]); 00438 a[1] = saturate_cast<T1>(a[1] + b[1]); 00439 a[2] = saturate_cast<T1>(a[2] + b[2]); 00440 return a; 00441 } 00442 00443 template<typename T1, typename T2> static inline 00444 Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b) 00445 { 00446 a[0] = saturate_cast<T1>(a[0] + b[0]); 00447 a[1] = saturate_cast<T1>(a[1] + b[1]); 00448 a[2] = saturate_cast<T1>(a[2] + b[2]); 00449 a[3] = saturate_cast<T1>(a[3] + b[3]); 00450 return a; 00451 } 00452 00453 template<typename T1, int n> static inline 00454 double norm(const Vec<T1, n>& a) 00455 { 00456 double s = 0; 00457 for( int i = 0; i < n; i++ ) 00458 s += (double)a.val[i]*a.val[i]; 00459 return std::sqrt(s); 00460 } 00461 00462 template<typename T1, int n> static inline 00463 bool operator == (const Vec<T1, n>& a, const Vec<T1, n>& b) 00464 { 00465 for( int i = 0; i < n; i++ ) 00466 if( a[i] != b[i] ) return false; 00467 return true; 00468 } 00469 00470 template<typename T1, int n> static inline 00471 bool operator != (const Vec<T1, n>& a, const Vec<T1, n>& b) 00472 { 00473 return !(a == b); 00474 } 00475 00477 00478 template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {} 00479 template<typename _Tp> inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {} 00480 template<typename _Tp> template<typename T2> inline Complex<_Tp>::operator Complex<T2>() const 00481 { return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); } 00482 template<typename _Tp> inline Complex<_Tp> Complex<_Tp>::conj() const 00483 { return Complex<_Tp>(re, -im); } 00484 00485 template<typename _Tp> static inline 00486 bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b) 00487 { return a.re == b.re && a.im == b.im; } 00488 00489 template<typename _Tp> static inline 00490 Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b) 00491 { return Complex<_Tp>( a.re + b.re, a.im + b.im ); } 00492 00493 template<typename _Tp> static inline 00494 Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b) 00495 { a.re += b.re; a.im += b.im; return a; } 00496 00497 template<typename _Tp> static inline 00498 Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b) 00499 { return Complex<_Tp>( a.re - b.re, a.im - b.im ); } 00500 00501 template<typename _Tp> static inline 00502 Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b) 00503 { a.re -= b.re; a.im -= b.im; return a; } 00504 00505 template<typename _Tp> static inline 00506 Complex<_Tp> operator - (const Complex<_Tp>& a) 00507 { return Complex<_Tp>(-a.re, -a.im); } 00508 00509 template<typename _Tp> static inline 00510 Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b) 00511 { return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); } 00512 00513 template<typename _Tp> static inline 00514 Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b) 00515 { return Complex<_Tp>( a.re*b, a.im*b ); } 00516 00517 template<typename _Tp> static inline 00518 Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a) 00519 { return Complex<_Tp>( a.re*b, a.im*b ); } 00520 00521 template<typename _Tp> static inline 00522 Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b) 00523 { return Complex<_Tp>( a.re + b, a.im ); } 00524 00525 template<typename _Tp> static inline 00526 Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b) 00527 { return Complex<_Tp>( a.re - b, a.im ); } 00528 00529 template<typename _Tp> static inline 00530 Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a) 00531 { return Complex<_Tp>( a.re + b, a.im ); } 00532 00533 template<typename _Tp> static inline 00534 Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a) 00535 { return Complex<_Tp>( b - a.re, -a.im ); } 00536 00537 template<typename _Tp> static inline 00538 Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b) 00539 { a.re += b; return a; } 00540 00541 template<typename _Tp> static inline 00542 Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b) 00543 { a.re -= b; return a; } 00544 00545 template<typename _Tp> static inline 00546 Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b) 00547 { a.re *= b; a.im *= b; return a; } 00548 00549 template<typename _Tp> static inline 00550 double abs(const Complex<_Tp>& a) 00551 { return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); } 00552 00553 template<typename _Tp> static inline 00554 Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b) 00555 { 00556 double t = 1./((double)b.re*b.re + (double)b.im*b.im); 00557 return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t), 00558 (_Tp)((-a.re*b.im + a.im*b.re)*t) ); 00559 } 00560 00561 template<typename _Tp> static inline 00562 Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b) 00563 { 00564 return (a = a / b); 00565 } 00566 00567 template<typename _Tp> static inline 00568 Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b) 00569 { 00570 _Tp t = (_Tp)1/b; 00571 return Complex<_Tp>( a.re*t, a.im*t ); 00572 } 00573 00574 template<typename _Tp> static inline 00575 Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a) 00576 { 00577 return Complex<_Tp>(b)/a; 00578 } 00579 00580 template<typename _Tp> static inline 00581 Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b) 00582 { 00583 _Tp t = (_Tp)1/b; 00584 a.re *= t; a.im *= t; return a; 00585 } 00586 00588 00589 template<typename _Tp> inline Point_<_Tp>::Point_() : x(0), y(0) {} 00590 template<typename _Tp> inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {} 00591 template<typename _Tp> inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {} 00592 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {} 00593 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint2D32f& pt) 00594 : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {} 00595 template<typename _Tp> inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {} 00596 template<typename _Tp> inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {} 00597 template<typename _Tp> inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt) 00598 { x = pt.x; y = pt.y; return *this; } 00599 00600 template<typename _Tp> template<typename _Tp2> inline Point_<_Tp>::operator Point_<_Tp2>() const 00601 { return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); } 00602 template<typename _Tp> inline Point_<_Tp>::operator CvPoint() const 00603 { return cvPoint(saturate_cast<int>(x), saturate_cast<int>(y)); } 00604 template<typename _Tp> inline Point_<_Tp>::operator CvPoint2D32f() const 00605 { return cvPoint2D32f((float)x, (float)y); } 00606 template<typename _Tp> inline Point_<_Tp>::operator Vec<_Tp, 2>() const 00607 { return Vec<_Tp, 2>(x, y); } 00608 00609 template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const 00610 { return saturate_cast<_Tp>(x*pt.x + y*pt.y); } 00611 template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const 00612 { return (double)x*pt.x + (double)y*pt.y; } 00613 00614 template<typename _Tp> static inline Point_<_Tp>& 00615 operator += (Point_<_Tp>& a, const Point_<_Tp>& b) 00616 { 00617 a.x = saturate_cast<_Tp>(a.x + b.x); 00618 a.y = saturate_cast<_Tp>(a.y + b.y); 00619 return a; 00620 } 00621 00622 template<typename _Tp> static inline Point_<_Tp>& 00623 operator -= (Point_<_Tp>& a, const Point_<_Tp>& b) 00624 { 00625 a.x = saturate_cast<_Tp>(a.x - b.x); 00626 a.y = saturate_cast<_Tp>(a.y - b.y); 00627 return a; 00628 } 00629 00630 template<typename _Tp> static inline Point_<_Tp>& 00631 operator *= (Point_<_Tp>& a, int b) 00632 { 00633 a.x = saturate_cast<_Tp>(a.x*b); 00634 a.y = saturate_cast<_Tp>(a.y*b); 00635 return a; 00636 } 00637 00638 template<typename _Tp> static inline Point_<_Tp>& 00639 operator *= (Point_<_Tp>& a, float b) 00640 { 00641 a.x = saturate_cast<_Tp>(a.x*b); 00642 a.y = saturate_cast<_Tp>(a.y*b); 00643 return a; 00644 } 00645 00646 template<typename _Tp> static inline Point_<_Tp>& 00647 operator *= (Point_<_Tp>& a, double b) 00648 { 00649 a.x = saturate_cast<_Tp>(a.x*b); 00650 a.y = saturate_cast<_Tp>(a.y*b); 00651 return a; 00652 } 00653 00654 template<typename _Tp> static inline double norm(const Point_<_Tp>& pt) 00655 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); } 00656 00657 template<typename _Tp> static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b) 00658 { return a.x == b.x && a.y == b.y; } 00659 00660 template<typename _Tp> static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b) 00661 { return !(a == b); } 00662 00663 template<typename _Tp> static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b) 00664 { return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); } 00665 00666 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b) 00667 { return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); } 00668 00669 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a) 00670 { return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); } 00671 00672 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b) 00673 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } 00674 00675 template<typename _Tp> static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b) 00676 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } 00677 00678 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b) 00679 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } 00680 00681 template<typename _Tp> static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b) 00682 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } 00683 00684 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b) 00685 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); } 00686 00687 template<typename _Tp> static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b) 00688 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); } 00689 00691 00692 template<typename _Tp> inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {} 00693 template<typename _Tp> inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {} 00694 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {} 00695 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {} 00696 template<typename _Tp> inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) : 00697 x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {} 00698 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {} 00699 00700 template<typename _Tp> template<typename _Tp2> inline Point3_<_Tp>::operator Point3_<_Tp2>() const 00701 { return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); } 00702 00703 template<typename _Tp> inline Point3_<_Tp>::operator CvPoint3D32f() const 00704 { return cvPoint3D32f((float)x, (float)y, (float)z); } 00705 00706 template<typename _Tp> inline Point3_<_Tp>::operator Vec<_Tp, 3>() const 00707 { return Vec<_Tp, 3>(x, y, z); } 00708 00709 template<typename _Tp> inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt) 00710 { x = pt.x; y = pt.y; z = pt.z; return *this; } 00711 00712 template<typename _Tp> inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const 00713 { return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); } 00714 template<typename _Tp> inline double Point3_<_Tp>::ddot(const Point3_& pt) const 00715 { return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; } 00716 00717 template<typename _Tp> static inline Point3_<_Tp>& 00718 operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b) 00719 { 00720 a.x = saturate_cast<_Tp>(a.x + b.x); 00721 a.y = saturate_cast<_Tp>(a.y + b.y); 00722 a.z = saturate_cast<_Tp>(a.z + b.z); 00723 return a; 00724 } 00725 00726 template<typename _Tp> static inline Point3_<_Tp>& 00727 operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b) 00728 { 00729 a.x = saturate_cast<_Tp>(a.x - b.x); 00730 a.y = saturate_cast<_Tp>(a.y - b.y); 00731 a.z = saturate_cast<_Tp>(a.z - b.z); 00732 return a; 00733 } 00734 00735 template<typename _Tp> static inline Point3_<_Tp>& 00736 operator *= (Point3_<_Tp>& a, int b) 00737 { 00738 a.x = saturate_cast<_Tp>(a.x*b); 00739 a.y = saturate_cast<_Tp>(a.y*b); 00740 a.z = saturate_cast<_Tp>(a.z*b); 00741 return a; 00742 } 00743 00744 template<typename _Tp> static inline Point3_<_Tp>& 00745 operator *= (Point3_<_Tp>& a, float b) 00746 { 00747 a.x = saturate_cast<_Tp>(a.x*b); 00748 a.y = saturate_cast<_Tp>(a.y*b); 00749 a.z = saturate_cast<_Tp>(a.z*b); 00750 return a; 00751 } 00752 00753 template<typename _Tp> static inline Point3_<_Tp>& 00754 operator *= (Point3_<_Tp>& a, double b) 00755 { 00756 a.x = saturate_cast<_Tp>(a.x*b); 00757 a.y = saturate_cast<_Tp>(a.y*b); 00758 a.z = saturate_cast<_Tp>(a.z*b); 00759 return a; 00760 } 00761 00762 template<typename _Tp> static inline double norm(const Point3_<_Tp>& pt) 00763 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); } 00764 00765 template<typename _Tp> static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b) 00766 { return a.x == b.x && a.y == b.y && a.z == b.z; } 00767 00768 template<typename _Tp> static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b) 00769 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), 00770 saturate_cast<_Tp>(a.y + b.y), 00771 saturate_cast<_Tp>(a.z + b.z)); } 00772 00773 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b) 00774 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), 00775 saturate_cast<_Tp>(a.y - b.y), 00776 saturate_cast<_Tp>(a.z - b.z)); } 00777 00778 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a) 00779 { return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), 00780 saturate_cast<_Tp>(-a.y), 00781 saturate_cast<_Tp>(-a.z) ); } 00782 00783 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b) 00784 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), 00785 saturate_cast<_Tp>(a.y*b), 00786 saturate_cast<_Tp>(a.z*b) ); } 00787 00788 template<typename _Tp> static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b) 00789 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), 00790 saturate_cast<_Tp>(b.y*a), 00791 saturate_cast<_Tp>(b.z*a) ); } 00792 00793 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b) 00794 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), 00795 saturate_cast<_Tp>(a.y*b), 00796 saturate_cast<_Tp>(a.z*b) ); } 00797 00798 template<typename _Tp> static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b) 00799 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), 00800 saturate_cast<_Tp>(b.y*a), 00801 saturate_cast<_Tp>(b.z*a) ); } 00802 00803 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b) 00804 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), 00805 saturate_cast<_Tp>(a.y*b), 00806 saturate_cast<_Tp>(a.z*b) ); } 00807 00808 template<typename _Tp> static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b) 00809 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a), 00810 saturate_cast<_Tp>(b.y*a), 00811 saturate_cast<_Tp>(b.z*a) ); } 00812 00814 00815 template<typename _Tp> inline Size_<_Tp>::Size_() 00816 : width(0), height(0) {} 00817 template<typename _Tp> inline Size_<_Tp>::Size_(_Tp _width, _Tp _height) 00818 : width(_width), height(_height) {} 00819 template<typename _Tp> inline Size_<_Tp>::Size_(const Size_& sz) 00820 : width(sz.width), height(sz.height) {} 00821 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize& sz) 00822 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {} 00823 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize2D32f& sz) 00824 : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {} 00825 template<typename _Tp> inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {} 00826 00827 template<typename _Tp> template<typename _Tp2> inline Size_<_Tp>::operator Size_<_Tp2>() const 00828 { return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); } 00829 template<typename _Tp> inline Size_<_Tp>::operator CvSize() const 00830 { return cvSize(saturate_cast<int>(width), saturate_cast<int>(height)); } 00831 template<typename _Tp> inline Size_<_Tp>::operator CvSize2D32f() const 00832 { return cvSize2D32f((float)width, (float)height); } 00833 00834 template<typename _Tp> inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz) 00835 { width = sz.width; height = sz.height; return *this; } 00836 template<typename _Tp> static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b) 00837 { return Size_<_Tp>(a.width * b, a.height * b); } 00838 template<typename _Tp> static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b) 00839 { return Size_<_Tp>(a.width + b.width, a.height + b.height); } 00840 template<typename _Tp> static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b) 00841 { return Size_<_Tp>(a.width - b.width, a.height - b.height); } 00842 template<typename _Tp> inline _Tp Size_<_Tp>::area() const { return width*height; } 00843 00844 template<typename _Tp> static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b) 00845 { a.width += b.width; a.height += b.height; return a; } 00846 template<typename _Tp> static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b) 00847 { a.width -= b.width; a.height -= b.height; return a; } 00848 00849 template<typename _Tp> static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b) 00850 { return a.width == b.width && a.height == b.height; } 00851 template<typename _Tp> static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b) 00852 { return a.width != b.width || a.height != b.height; } 00853 00855 00856 00857 template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {} 00858 template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {} 00859 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {} 00860 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) {} 00861 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) : 00862 x(org.x), y(org.y), width(sz.width), height(sz.height) {} 00863 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2) 00864 { 00865 x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y); 00866 width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y; 00867 } 00868 template<typename _Tp> inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r ) 00869 { x = r.x; y = r.y; width = r.width; height = r.height; return *this; } 00870 00871 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); } 00872 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); } 00873 00874 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b ) 00875 { a.x += b.x; a.y += b.y; return a; } 00876 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b ) 00877 { a.x -= b.x; a.y -= b.y; return a; } 00878 00879 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b ) 00880 { a.width += b.width; a.height += b.height; return a; } 00881 00882 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b ) 00883 { a.width -= b.width; a.height -= b.height; return a; } 00884 00885 template<typename _Tp> static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) 00886 { 00887 _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y); 00888 a.width = std::min(a.x + a.width, b.x + b.width) - x1; 00889 a.height = std::min(a.y + a.height, b.y + b.height) - y1; 00890 a.x = x1; a.y = y1; 00891 if( a.width <= 0 || a.height <= 0 ) 00892 a = Rect(); 00893 return a; 00894 } 00895 00896 template<typename _Tp> static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) 00897 { 00898 _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y); 00899 a.width = std::max(a.x + a.width, b.x + b.width) - x1; 00900 a.height = std::max(a.y + a.height, b.y + b.height) - y1; 00901 a.x = x1; a.y = y1; 00902 return a; 00903 } 00904 00905 template<typename _Tp> inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); } 00906 template<typename _Tp> inline _Tp Rect_<_Tp>::area() const { return width*height; } 00907 00908 template<typename _Tp> template<typename _Tp2> inline Rect_<_Tp>::operator Rect_<_Tp2>() const 00909 { return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), 00910 saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); } 00911 template<typename _Tp> inline Rect_<_Tp>::operator CvRect() const 00912 { return cvRect(saturate_cast<int>(x), saturate_cast<int>(y), 00913 saturate_cast<int>(width), saturate_cast<int>(height)); } 00914 00915 template<typename _Tp> inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const 00916 { return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; } 00917 00918 template<typename _Tp> static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b) 00919 { 00920 return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; 00921 } 00922 00923 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b) 00924 { 00925 return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height ); 00926 } 00927 00928 template<typename _Tp> static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b) 00929 { 00930 return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height ); 00931 } 00932 00933 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b) 00934 { 00935 return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height ); 00936 } 00937 00938 template<typename _Tp> static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b) 00939 { 00940 Rect_<_Tp> c = a; 00941 return c &= b; 00942 } 00943 00944 template<typename _Tp> static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b) 00945 { 00946 Rect_<_Tp> c = a; 00947 return c |= b; 00948 } 00949 00950 template<typename _Tp> inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const 00951 { 00952 return r.contains(*this); 00953 } 00954 00955 inline RotatedRect::RotatedRect() { angle = 0; } 00956 inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle) 00957 : center(_center), size(_size), angle(_angle) {} 00958 inline RotatedRect::RotatedRect(const CvBox2D& box) 00959 : center(box.center), size(box.size), angle(box.angle) {} 00960 inline RotatedRect::operator CvBox2D() const 00961 { 00962 CvBox2D box; box.center = center; box.size = size; box.angle = angle; 00963 return box; 00964 } 00965 inline void RotatedRect::points(Point2f pt[]) const 00966 { 00967 double _angle = angle*CV_PI/180.; 00968 float a = (float)cos(_angle)*0.5f; 00969 float b = (float)sin(_angle)*0.5f; 00970 00971 pt[0].x = center.x - a*size.height - b*size.width; 00972 pt[0].y = center.y + b*size.height - a*size.width; 00973 pt[1].x = center.x + a*size.height - b*size.width; 00974 pt[1].y = center.y - b*size.height - a*size.width; 00975 pt[2].x = 2*center.x - pt[0].x; 00976 pt[2].y = 2*center.y - pt[0].y; 00977 pt[3].x = 2*center.x - pt[1].x; 00978 pt[3].y = 2*center.y - pt[1].y; 00979 } 00980 00981 inline Rect RotatedRect::boundingRect() const 00982 { 00983 Point2f pt[4]; 00984 points(pt); 00985 Rect r(cvFloor(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), 00986 cvFloor(min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)), 00987 cvCeil(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), 00988 cvCeil(max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y))); 00989 r.width -= r.x - 1; 00990 r.height -= r.y - 1; 00991 return r; 00992 } 00993 00995 00996 template<typename _Tp> inline Scalar_<_Tp>::Scalar_() 00997 { this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; } 00998 00999 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 01000 { this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; } 01001 01002 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(const CvScalar& s) 01003 { 01004 this->val[0] = saturate_cast<_Tp>(s.val[0]); 01005 this->val[1] = saturate_cast<_Tp>(s.val[1]); 01006 this->val[2] = saturate_cast<_Tp>(s.val[2]); 01007 this->val[3] = saturate_cast<_Tp>(s.val[3]); 01008 } 01009 01010 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0) 01011 { this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; } 01012 01013 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0) 01014 { return Scalar_<_Tp>(v0, v0, v0, v0); } 01015 template<typename _Tp> inline Scalar_<_Tp>::operator CvScalar() const 01016 { return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); } 01017 01018 template<typename _Tp> template<typename T2> inline Scalar_<_Tp>::operator Scalar_<T2>() const 01019 { 01020 return Scalar_<T2>(saturate_cast<T2>(this->val[0]), 01021 saturate_cast<T2>(this->val[1]), 01022 saturate_cast<T2>(this->val[2]), 01023 saturate_cast<T2>(this->val[3])); 01024 } 01025 01026 template<typename _Tp> static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) 01027 { 01028 a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]); 01029 a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]); 01030 a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]); 01031 a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]); 01032 return a; 01033 } 01034 01035 template<typename _Tp> static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) 01036 { 01037 a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]); 01038 a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]); 01039 a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]); 01040 a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]); 01041 return a; 01042 } 01043 01044 template<typename _Tp> static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v ) 01045 { 01046 a.val[0] = saturate_cast<_Tp>(a.val[0] * v); 01047 a.val[1] = saturate_cast<_Tp>(a.val[1] * v); 01048 a.val[2] = saturate_cast<_Tp>(a.val[2] * v); 01049 a.val[3] = saturate_cast<_Tp>(a.val[3] * v); 01050 return a; 01051 } 01052 01053 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const 01054 { 01055 return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale), 01056 saturate_cast<_Tp>(this->val[1]*t.val[1]*scale), 01057 saturate_cast<_Tp>(this->val[2]*t.val[2]*scale), 01058 saturate_cast<_Tp>(this->val[3]*t.val[3]*scale)); 01059 } 01060 01061 template<typename _Tp> static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) 01062 { 01063 return a.val[0] == b.val[0] && a.val[1] == b.val[1] && 01064 a.val[2] == b.val[2] && a.val[3] == b.val[3]; 01065 } 01066 01067 template<typename _Tp> static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) 01068 { 01069 return a.val[0] != b.val[0] || a.val[1] != b.val[1] || 01070 a.val[2] != b.val[2] || a.val[3] != b.val[3]; 01071 } 01072 01073 template<typename _Tp> template<typename T2> inline void Scalar_<_Tp>::convertTo(T2* buf, int cn, int unroll_to) const 01074 { 01075 int i; 01076 CV_Assert(cn <= 4); 01077 for( i = 0; i < cn; i++ ) 01078 buf[i] = saturate_cast<T2>(this->val[i]); 01079 for( ; i < unroll_to; i++ ) 01080 buf[i] = buf[i-cn]; 01081 } 01082 01083 static inline void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0) 01084 { 01085 int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); 01086 switch(depth) 01087 { 01088 case CV_8U: 01089 s.convertTo((uchar*)buf, cn, unroll_to); 01090 break; 01091 case CV_8S: 01092 s.convertTo((schar*)buf, cn, unroll_to); 01093 break; 01094 case CV_16U: 01095 s.convertTo((ushort*)buf, cn, unroll_to); 01096 break; 01097 case CV_16S: 01098 s.convertTo((short*)buf, cn, unroll_to); 01099 break; 01100 case CV_32S: 01101 s.convertTo((int*)buf, cn, unroll_to); 01102 break; 01103 case CV_32F: 01104 s.convertTo((float*)buf, cn, unroll_to); 01105 break; 01106 case CV_64F: 01107 s.convertTo((double*)buf, cn, unroll_to); 01108 break; 01109 default: 01110 CV_Error(CV_StsUnsupportedFormat,""); 01111 } 01112 } 01113 01114 01115 template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) 01116 { 01117 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]), 01118 saturate_cast<_Tp>(a.val[1] + b.val[1]), 01119 saturate_cast<_Tp>(a.val[2] + b.val[2]), 01120 saturate_cast<_Tp>(a.val[3] + b.val[3])); 01121 } 01122 01123 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) 01124 { 01125 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]), 01126 saturate_cast<_Tp>(a.val[1] - b.val[1]), 01127 saturate_cast<_Tp>(a.val[2] - b.val[2]), 01128 saturate_cast<_Tp>(a.val[3] - b.val[3])); 01129 } 01130 01131 template<typename _Tp> static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha) 01132 { 01133 return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha), 01134 saturate_cast<_Tp>(a.val[1] * alpha), 01135 saturate_cast<_Tp>(a.val[2] * alpha), 01136 saturate_cast<_Tp>(a.val[3] * alpha)); 01137 } 01138 01139 template<typename _Tp> static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a) 01140 { 01141 return a*alpha; 01142 } 01143 01144 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a) 01145 { 01146 return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]), 01147 saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3])); 01148 } 01149 01151 01152 inline Range::Range() : start(0), end(0) {} 01153 inline Range::Range(int _start, int _end) : start(_start), end(_end) {} 01154 inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index) 01155 { 01156 if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX ) 01157 *this = Range::all(); 01158 } 01159 01160 inline int Range::size() const { return end - start; } 01161 inline bool Range::empty() const { return start == end; } 01162 inline Range Range::all() { return Range(INT_MIN, INT_MAX); } 01163 01164 static inline bool operator == (const Range& r1, const Range& r2) 01165 { return r1.start == r2.start && r1.end == r2.end; } 01166 01167 static inline bool operator != (const Range& r1, const Range& r2) 01168 { return !(r1 == r2); } 01169 01170 static inline bool operator !(const Range& r) 01171 { return r.start == r.end; } 01172 01173 static inline Range operator & (const Range& r1, const Range& r2) 01174 { 01175 Range r(std::max(r1.start, r2.start), std::min(r2.start, r2.end)); 01176 r.end = std::max(r.end, r.start); 01177 return r; 01178 } 01179 01180 static inline Range& operator &= (Range& r1, const Range& r2) 01181 { 01182 r1 = r1 & r2; 01183 return r1; 01184 } 01185 01186 static inline Range operator + (const Range& r1, int delta) 01187 { 01188 return Range(r1.start + delta, r1.end + delta); 01189 } 01190 01191 static inline Range operator + (int delta, const Range& r1) 01192 { 01193 return Range(r1.start + delta, r1.end + delta); 01194 } 01195 01196 static inline Range operator - (const Range& r1, int delta) 01197 { 01198 return r1 + (-delta); 01199 } 01200 01201 inline Range::operator CvSlice() const 01202 { return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; } 01203 01204 01205 01207 01208 // template vector class. It is similar to STL's vector, 01209 // with a few important differences: 01210 // 1) it can be created on top of user-allocated data w/o copying it 01211 // 2) vector b = a means copying the header, 01212 // not the underlying data (use clone() to make a deep copy) 01213 template <typename _Tp> class CV_EXPORTS Vector 01214 { 01215 public: 01216 typedef _Tp value_type; 01217 typedef _Tp* iterator; 01218 typedef const _Tp* const_iterator; 01219 typedef _Tp& reference; 01220 typedef const _Tp& const_reference; 01221 01222 struct CV_EXPORTS Hdr 01223 { 01224 Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {}; 01225 _Tp* data; 01226 _Tp* datastart; 01227 int* refcount; 01228 size_t size; 01229 size_t capacity; 01230 }; 01231 01232 Vector() {} 01233 Vector(size_t _size) { resize(_size); } 01234 Vector(size_t _size, const _Tp& val) 01235 { 01236 resize(_size); 01237 for(size_t i = 0; i < _size; i++) 01238 hdr.data[i] = val; 01239 } 01240 Vector(_Tp* _data, size_t _size, bool _copyData=false) 01241 { set(_data, _size, _copyData); } 01242 01243 template<int n> Vector(const Vec<_Tp, n>& vec) 01244 { set((_Tp*)&vec.val[0], n, true); } 01245 01246 Vector(const std::vector<_Tp>& vec, bool _copyData=false) 01247 { set((_Tp*)&vec[0], vec.size(), _copyData); } 01248 01249 Vector(const Vector& d) { *this = d; } 01250 01251 Vector(const Vector& d, const Range& r) 01252 { 01253 if( r == Range::all() ) 01254 r = Range(0, d.size()); 01255 if( r.size() > 0 && r.start >= 0 && r.end <= d.size() ) 01256 { 01257 if( d.hdr.refcount ) 01258 CV_XADD(d.hdr.refcount, 1); 01259 hdr.refcount = d.hdr.refcount; 01260 hdr.datastart = d.hdr.datastart; 01261 hdr.data = d.hdr.data + r.start; 01262 hdr.capacity = hdr.size = r.size(); 01263 } 01264 } 01265 01266 Vector<_Tp>& operator = (const Vector& d) 01267 { 01268 if( this != &d ) 01269 { 01270 if( d.hdr.refcount ) 01271 CV_XADD(d.hdr.refcount, 1); 01272 release(); 01273 hdr = d.hdr; 01274 } 01275 return *this; 01276 } 01277 01278 ~Vector() { release(); } 01279 01280 Vector<_Tp> clone() const 01281 { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); } 01282 01283 void copyTo(Vector<_Tp>& vec) const 01284 { 01285 size_t i, sz = size(); 01286 vec.resize(sz); 01287 const _Tp* src = hdr.data; 01288 _Tp* dst = vec.hdr.data; 01289 for( i = 0; i < sz; i++ ) 01290 dst[i] = src[i]; 01291 } 01292 01293 void copyTo(std::vector<_Tp>& vec) const 01294 { 01295 size_t i, sz = size(); 01296 vec.resize(sz); 01297 const _Tp* src = hdr.data; 01298 _Tp* dst = sz ? &vec[0] : 0; 01299 for( i = 0; i < sz; i++ ) 01300 dst[i] = src[i]; 01301 } 01302 01303 operator CvMat() const 01304 { return cvMat((int)size(), 1, type(), (void*)hdr.data); } 01305 01306 _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; } 01307 const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; } 01308 Vector operator() (const Range& r) const { return Vector(*this, r); } 01309 _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; } 01310 const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; } 01311 _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; } 01312 const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; } 01313 01314 _Tp* begin() { return hdr.data; } 01315 _Tp* end() { return hdr.data + hdr.size; } 01316 const _Tp* begin() const { return hdr.data; } 01317 const _Tp* end() const { return hdr.data + hdr.size; } 01318 01319 void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); } 01320 void release() 01321 { 01322 if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 ) 01323 { 01324 delete[] hdr.datastart; 01325 delete hdr.refcount; 01326 } 01327 hdr = Hdr(); 01328 } 01329 01330 void set(_Tp* _data, size_t _size, bool _copyData=false) 01331 { 01332 if( !_copyData ) 01333 { 01334 release(); 01335 hdr.data = hdr.datastart = _data; 01336 hdr.size = hdr.capacity = _size; 01337 hdr.refcount = 0; 01338 } 01339 else 01340 { 01341 reserve(_size); 01342 for( size_t i = 0; i < _size; i++ ) 01343 hdr.data[i] = _data[i]; 01344 hdr.size = _size; 01345 } 01346 } 01347 01348 void reserve(size_t newCapacity) 01349 { 01350 _Tp* newData; 01351 int* newRefcount; 01352 size_t i, oldSize = hdr.size; 01353 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity ) 01354 return; 01355 newCapacity = std::max(newCapacity, oldSize); 01356 newData = new _Tp[newCapacity]; 01357 newRefcount = new int(1); 01358 for( i = 0; i < oldSize; i++ ) 01359 newData[i] = hdr.data[i]; 01360 release(); 01361 hdr.data = hdr.datastart = newData; 01362 hdr.capacity = newCapacity; 01363 hdr.size = oldSize; 01364 hdr.refcount = newRefcount; 01365 } 01366 01367 void resize(size_t newSize) 01368 { 01369 size_t i; 01370 newSize = std::max(newSize, (size_t)0); 01371 if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize ) 01372 return; 01373 if( newSize > hdr.capacity ) 01374 reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2))); 01375 for( i = hdr.size; i < newSize; i++ ) 01376 hdr.data[i] = _Tp(); 01377 hdr.size = newSize; 01378 } 01379 01380 Vector<_Tp>& push_back(const _Tp& elem) 01381 { 01382 if( hdr.size == hdr.capacity ) 01383 reserve( std::max((size_t)4, hdr.capacity*2) ); 01384 hdr.data[hdr.size++] = elem; 01385 return *this; 01386 } 01387 01388 Vector<_Tp>& pop_back() 01389 { 01390 if( hdr.size > 0 ) 01391 --hdr.size; 01392 return *this; 01393 } 01394 01395 size_t size() const { return hdr.size; } 01396 size_t capacity() const { return hdr.capacity; } 01397 bool empty() const { return hdr.size == 0; } 01398 void clear() { resize(0); } 01399 int type() const { return DataType<_Tp>::type; } 01400 01401 protected: 01402 Hdr hdr; 01403 }; 01404 01405 01406 template<typename _Tp> inline typename DataType<_Tp>::work_type 01407 dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2) 01408 { 01409 typedef typename DataType<_Tp>::work_type _Tw; 01410 size_t i, n = v1.size(); 01411 assert(v1.size() == v2.size()); 01412 01413 _Tw s = 0; 01414 const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0]; 01415 for( i = 0; i <= n - 4; i += 4 ) 01416 s += (_Tw)ptr1[i]*ptr2[i] + (_Tw)ptr1[i+1]*ptr2[i+1] + 01417 (_Tw)ptr1[i+2]*ptr2[i+2] + (_Tw)ptr1[i+3]*ptr2[i+3]; 01418 for( ; i < n; i++ ) 01419 s += (_Tw)ptr1[i]*ptr2[i]; 01420 return s; 01421 } 01422 01423 // Multiply-with-Carry RNG 01424 inline RNG::RNG() { state = 0xffffffff; } 01425 inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; } 01426 inline unsigned RNG::next() 01427 { 01428 state = (uint64)(unsigned)state*A + (unsigned)(state >> 32); 01429 return (unsigned)state; 01430 } 01431 01432 inline RNG::operator uchar() { return (uchar)next(); } 01433 inline RNG::operator schar() { return (schar)next(); } 01434 inline RNG::operator ushort() { return (ushort)next(); } 01435 inline RNG::operator short() { return (short)next(); } 01436 inline RNG::operator unsigned() { return next(); } 01437 inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);} 01438 inline unsigned RNG::operator ()() {return next();} 01439 inline RNG::operator int() { return (int)next(); } 01440 // * (2^32-1)^-1 01441 inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; } 01442 inline RNG::operator double() 01443 { 01444 unsigned t = next(); 01445 return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20; 01446 } 01447 inline int RNG::uniform(int a, int b) { return a == b ? a : next()%(b - a) + a; } 01448 inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; } 01449 inline double RNG::uniform(double a, double b) { return ((float)*this)*(b - a) + a; } 01450 01451 inline double RNG::gaussian(double sigma) 01452 { 01453 CvMat* values = cvCreateMat( 1, 1, CV_64FC1 ); 01454 01455 cvRandArr( &state, values, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(sigma) ); 01456 double res = values->data.db[0]; 01457 cvReleaseMat(&values); 01458 next(); 01459 return res; 01460 } 01461 01462 inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {} 01463 inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon) 01464 : type(_type), maxCount(_maxCount), epsilon(_epsilon) {} 01465 inline TermCriteria::TermCriteria(const CvTermCriteria& criteria) 01466 : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {} 01467 inline TermCriteria::operator CvTermCriteria() const 01468 { return cvTermCriteria(type, maxCount, epsilon); } 01469 01470 inline uchar* LineIterator::operator *() { return ptr; } 01471 inline LineIterator& LineIterator::operator ++() 01472 { 01473 int mask = err < 0 ? -1 : 0; 01474 err += minusDelta + (plusDelta & mask); 01475 ptr += minusStep + (plusStep & mask); 01476 return *this; 01477 } 01478 inline LineIterator LineIterator::operator ++(int) 01479 { 01480 LineIterator it = *this; 01481 ++(*this); 01482 return it; 01483 } 01484 01485 #if 0 01486 template<typename _Tp> inline VectorCommaInitializer_<_Tp>:: 01487 VectorCommaInitializer_(vector<_Tp>* _vec) : vec(_vec), idx(0) {} 01488 01489 template<typename _Tp> template<typename T2> inline VectorCommaInitializer_<_Tp>& 01490 VectorCommaInitializer_<_Tp>::operator , (T2 val) 01491 { 01492 if( (size_t)idx < vec->size() ) 01493 (*vec)[idx] = _Tp(val); 01494 else 01495 vec->push_back(_Tp(val)); 01496 idx++; 01497 return *this; 01498 } 01499 01500 template<typename _Tp> inline VectorCommaInitializer_<_Tp>::operator vector<_Tp>() const 01501 { return *vec; } 01502 01503 template<typename _Tp> inline vector<_Tp> VectorCommaInitializer_<_Tp>::operator *() const 01504 { return *vec; } 01505 01506 template<typename _Tp, typename T2> static inline VectorCommaInitializer_<_Tp> 01507 operator << (const vector<_Tp>& vec, T2 val) 01508 { 01509 VectorCommaInitializer_<_Tp> commaInitializer((vector<_Tp>*)&vec); 01510 return (commaInitializer, val); 01511 } 01512 #endif 01513 01515 01516 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer() 01517 : ptr(buf), size(fixed_size) {} 01518 01519 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size) 01520 : ptr(buf), size(fixed_size) { allocate(_size); } 01521 01522 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer() 01523 { deallocate(); } 01524 01525 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size) 01526 { 01527 if(_size <= size) 01528 return; 01529 deallocate(); 01530 if(_size > fixed_size) 01531 { 01532 ptr = cv::allocate<_Tp>(_size); 01533 size = _size; 01534 } 01535 } 01536 01537 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate() 01538 { 01539 if( ptr != buf ) 01540 { 01541 cv::deallocate<_Tp>(ptr, size); 01542 ptr = buf; 01543 size = fixed_size; 01544 } 01545 } 01546 01547 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* () 01548 { return ptr; } 01549 01550 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const 01551 { return ptr; } 01552 01553 01555 01556 template<typename _Tp> inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {} 01557 template<typename _Tp> inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj) 01558 { 01559 if(obj) 01560 { 01561 refcount = (int*)fastMalloc(sizeof(*refcount)); 01562 *refcount = 1; 01563 } 01564 else 01565 refcount = 0; 01566 } 01567 01568 template<typename _Tp> inline void Ptr<_Tp>::addref() 01569 { if( refcount ) CV_XADD(refcount, 1); } 01570 01571 template<typename _Tp> inline void Ptr<_Tp>::release() 01572 { 01573 if( refcount && CV_XADD(refcount, -1) == 1 ) 01574 { 01575 delete_obj(); 01576 fastFree(refcount); 01577 } 01578 refcount = 0; 01579 obj = 0; 01580 } 01581 01582 template<typename _Tp> inline void Ptr<_Tp>::delete_obj() 01583 { 01584 if( obj ) delete obj; 01585 } 01586 01587 template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); } 01588 01589 template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr) 01590 { 01591 obj = ptr.obj; 01592 refcount = ptr.refcount; 01593 addref(); 01594 } 01595 01596 template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr) 01597 { 01598 int* _refcount = ptr.refcount; 01599 if( _refcount ) 01600 CV_XADD(_refcount, 1); 01601 release(); 01602 obj = ptr.obj; 01603 refcount = _refcount; 01604 return *this; 01605 } 01606 01607 template<typename _Tp> inline _Tp* Ptr<_Tp>::operator -> () { return obj; } 01608 template<typename _Tp> inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; } 01609 01610 template<typename _Tp> inline Ptr<_Tp>::operator _Tp* () { return obj; } 01611 template<typename _Tp> inline Ptr<_Tp>::operator const _Tp*() const { return obj; } 01612 01613 template<typename _Tp> inline bool Ptr<_Tp>::empty() const { return obj == 0; } 01614 01616 01617 template<> inline void Ptr<CvMat>::delete_obj() 01618 { cvReleaseMat(&obj); } 01619 01620 template<> inline void Ptr<IplImage>::delete_obj() 01621 { cvReleaseImage(&obj); } 01622 01623 template<> inline void Ptr<CvMatND>::delete_obj() 01624 { cvReleaseMatND(&obj); } 01625 01626 template<> inline void Ptr<CvSparseMat>::delete_obj() 01627 { cvReleaseSparseMat(&obj); } 01628 01629 template<> inline void Ptr<CvMemStorage>::delete_obj() 01630 { cvReleaseMemStorage(&obj); } 01631 01632 template<> inline void Ptr<CvFileStorage>::delete_obj() 01633 { cvReleaseFileStorage(&obj); } 01634 01636 01637 static inline void write( FileStorage& fs, const string& name, int value ) 01638 { cvWriteInt( *fs, name.size() ? name.c_str() : 0, value ); } 01639 01640 static inline void write( FileStorage& fs, const string& name, float value ) 01641 { cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); } 01642 01643 static inline void write( FileStorage& fs, const string& name, double value ) 01644 { cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); } 01645 01646 static inline void write( FileStorage& fs, const string& name, const string& value ) 01647 { cvWriteString( *fs, name.size() ? name.c_str() : 0, value.c_str() ); } 01648 01649 template<typename _Tp> static inline void write(FileStorage& fs, const _Tp& value) 01650 { write(fs, string(), value); } 01651 01652 template<> inline void write(FileStorage& fs, const int& value ) 01653 { cvWriteInt( *fs, 0, value ); } 01654 01655 template<> inline void write(FileStorage& fs, const float& value ) 01656 { cvWriteReal( *fs, 0, value ); } 01657 01658 template<> inline void write(FileStorage& fs, const double& value ) 01659 { cvWriteReal( *fs, 0, value ); } 01660 01661 template<> inline void write(FileStorage& fs, const string& value ) 01662 { cvWriteString( *fs, 0, value.c_str() ); } 01663 01664 template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt ) 01665 { 01666 write(fs, pt.x); 01667 write(fs, pt.y); 01668 } 01669 01670 template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt ) 01671 { 01672 write(fs, pt.x); 01673 write(fs, pt.y); 01674 write(fs, pt.z); 01675 } 01676 01677 template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz ) 01678 { 01679 write(fs, sz.width); 01680 write(fs, sz.height); 01681 } 01682 01683 template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c ) 01684 { 01685 write(fs, c.re); 01686 write(fs, c.im); 01687 } 01688 01689 template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r ) 01690 { 01691 write(fs, r.x); 01692 write(fs, r.y); 01693 write(fs, r.width); 01694 write(fs, r.height); 01695 } 01696 01697 template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v ) 01698 { 01699 for(int i = 0; i < cn; i++) 01700 write(fs, v.val[i]); 01701 } 01702 01703 template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s ) 01704 { 01705 write(fs, s.val[0]); 01706 write(fs, s.val[1]); 01707 write(fs, s.val[2]); 01708 write(fs, s.val[3]); 01709 } 01710 01711 inline void write(FileStorage& fs, const Range& r ) 01712 { 01713 write(fs, r.start); 01714 write(fs, r.end); 01715 } 01716 01717 class CV_EXPORTS WriteStructContext 01718 { 01719 public: 01720 WriteStructContext(FileStorage& _fs, const string& name, 01721 int flags, const string& typeName=string()) : fs(&_fs) 01722 { 01723 cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags, 01724 !typeName.empty() ? typeName.c_str() : 0); 01725 } 01726 ~WriteStructContext() { cvEndWriteStruct(**fs); } 01727 FileStorage* fs; 01728 }; 01729 01730 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt ) 01731 { 01732 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01733 write(fs, pt.x); 01734 write(fs, pt.y); 01735 } 01736 01737 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt ) 01738 { 01739 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01740 write(fs, pt.x); 01741 write(fs, pt.y); 01742 write(fs, pt.z); 01743 } 01744 01745 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz ) 01746 { 01747 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01748 write(fs, sz.width); 01749 write(fs, sz.height); 01750 } 01751 01752 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c ) 01753 { 01754 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01755 write(fs, c.re); 01756 write(fs, c.im); 01757 } 01758 01759 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r ) 01760 { 01761 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01762 write(fs, r.x); 01763 write(fs, r.y); 01764 write(fs, r.width); 01765 write(fs, r.height); 01766 } 01767 01768 template<typename _Tp, int cn> inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v ) 01769 { 01770 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01771 for(int i = 0; i < cn; i++) 01772 write(fs, v.val[i]); 01773 } 01774 01775 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s ) 01776 { 01777 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01778 write(fs, s.val[0]); 01779 write(fs, s.val[1]); 01780 write(fs, s.val[2]); 01781 write(fs, s.val[3]); 01782 } 01783 01784 inline void write(FileStorage& fs, const string& name, const Range& r ) 01785 { 01786 WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW); 01787 write(fs, r.start); 01788 write(fs, r.end); 01789 } 01790 01791 template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy 01792 { 01793 public: 01794 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} 01795 void operator()(const vector<_Tp>& vec) const 01796 { 01797 size_t i, count = vec.size(); 01798 for( i = 0; i < count; i++ ) 01799 write( *fs, vec[i] ); 01800 } 01801 FileStorage* fs; 01802 }; 01803 01804 template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1> 01805 { 01806 public: 01807 VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} 01808 void operator()(const vector<_Tp>& vec) const 01809 { 01810 int _fmt = DataType<_Tp>::fmt; 01811 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' }; 01812 fs->writeRaw( string(fmt), (uchar*)&vec[0], vec.size()*sizeof(_Tp) ); 01813 } 01814 FileStorage* fs; 01815 }; 01816 01817 01818 template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec ) 01819 { 01820 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); 01821 w(vec); 01822 } 01823 01824 template<typename _Tp> static inline FileStorage& 01825 operator << ( FileStorage& fs, const vector<_Tp>& vec ) 01826 { 01827 VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); 01828 w(vec); 01829 return fs; 01830 } 01831 01832 CV_EXPORTS void write( FileStorage& fs, const string& name, const Mat& value ); 01833 CV_EXPORTS void write( FileStorage& fs, const string& name, const MatND& value ); 01834 CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value ); 01835 01836 template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value) 01837 { 01838 if( !fs.isOpened() ) 01839 return fs; 01840 if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP ) 01841 CV_Error( CV_StsError, "No element name has been given" ); 01842 write( fs, fs.elname, value ); 01843 if( fs.state & FileStorage::INSIDE_MAP ) 01844 fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP; 01845 return fs; 01846 } 01847 01848 CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str); 01849 01850 static inline FileStorage& operator << (FileStorage& fs, const char* str) 01851 { return (fs << string(str)); } 01852 01853 inline FileNode FileStorage::operator[](const string& nodename) const 01854 { 01855 return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename.c_str())); 01856 } 01857 inline FileNode FileStorage::operator[](const char* nodename) const 01858 { 01859 return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename)); 01860 } 01861 01862 inline FileNode::FileNode() : fs(0), node(0) {} 01863 inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) 01864 : fs(_fs), node(_node) {} 01865 01866 inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {} 01867 inline FileNode FileNode::operator[](const string& nodename) const 01868 { 01869 return FileNode(fs, cvGetFileNodeByName(fs, node, nodename.c_str())); 01870 } 01871 inline FileNode FileNode::operator[](const char* nodename) const 01872 { 01873 return FileNode(fs, cvGetFileNodeByName(fs, node, nodename)); 01874 } 01875 01876 inline FileNode FileNode::operator[](int i) const 01877 { 01878 return isSeq() ? FileNode(fs, (CvFileNode*)cvGetSeqElem(node->data.seq, i)) : 01879 i == 0 ? *this : FileNode(); 01880 } 01881 01882 inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); } 01883 inline bool FileNode::empty() const { return node == 0; } 01884 inline bool FileNode::isNone() const { return type() == NONE; } 01885 inline bool FileNode::isSeq() const { return type() == SEQ; } 01886 inline bool FileNode::isMap() const { return type() == MAP; } 01887 inline bool FileNode::isInt() const { return type() == INT; } 01888 inline bool FileNode::isReal() const { return type() == REAL; } 01889 inline bool FileNode::isString() const { return type() == STR; } 01890 inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; } 01891 inline string FileNode::name() const 01892 { 01893 const char* str; 01894 return !node || (str = cvGetFileNodeName(node)) == 0 ? string() : string(str); 01895 } 01896 inline size_t FileNode::size() const 01897 { 01898 int t = type(); 01899 return t == MAP ? ((CvSet*)node->data.map)->active_count : 01900 t == SEQ ? node->data.seq->total : node != 0; 01901 } 01902 01903 inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; } 01904 inline const CvFileNode* FileNode::operator* () const { return node; } 01905 01906 static inline void read(const FileNode& node, bool& value, bool default_value) 01907 { value = cvReadInt(node.node, default_value) != 0; } 01908 01909 static inline void read(const FileNode& node, uchar& value, uchar default_value) 01910 { value = saturate_cast<uchar>(cvReadInt(node.node, default_value)); } 01911 01912 static inline void read(const FileNode& node, schar& value, schar default_value) 01913 { value = saturate_cast<schar>(cvReadInt(node.node, default_value)); } 01914 01915 static inline void read(const FileNode& node, ushort& value, ushort default_value) 01916 { value = saturate_cast<ushort>(cvReadInt(node.node, default_value)); } 01917 01918 static inline void read(const FileNode& node, short& value, short default_value) 01919 { value = saturate_cast<short>(cvReadInt(node.node, default_value)); } 01920 01921 static inline void read(const FileNode& node, int& value, int default_value) 01922 { value = cvReadInt(node.node, default_value); } 01923 01924 static inline void read(const FileNode& node, float& value, float default_value) 01925 { value = (float)cvReadReal(node.node, default_value); } 01926 01927 static inline void read(const FileNode& node, double& value, double default_value) 01928 { value = cvReadReal(node.node, default_value); } 01929 01930 static inline void read(const FileNode& node, string& value, const string& default_value) 01931 { value = string(cvReadString(node.node, default_value.c_str())); } 01932 01933 CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() ); 01934 CV_EXPORTS void read(const FileNode& node, MatND& mat, const MatND& default_mat=MatND() ); 01935 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() ); 01936 01937 inline FileNode::operator int() const 01938 { 01939 return cvReadInt(node, 0); 01940 } 01941 inline FileNode::operator float() const 01942 { 01943 return (float)cvReadReal(node, 0); 01944 } 01945 inline FileNode::operator double() const 01946 { 01947 return cvReadReal(node, 0); 01948 } 01949 inline FileNode::operator string() const 01950 { 01951 return string(cvReadString(node, "")); 01952 } 01953 01954 inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const 01955 { 01956 begin().readRaw( fmt, vec, len ); 01957 } 01958 01959 template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy 01960 { 01961 public: 01962 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} 01963 void operator()(vector<_Tp>& vec, size_t count) const 01964 { 01965 count = std::min(count, it->remaining); 01966 vec.resize(count); 01967 for( size_t i = 0; i < count; i++, ++(*it) ) 01968 read(**it, vec[i], _Tp()); 01969 } 01970 FileNodeIterator* it; 01971 }; 01972 01973 template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1> 01974 { 01975 public: 01976 VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} 01977 void operator()(vector<_Tp>& vec, size_t count) const 01978 { 01979 size_t remaining = it->remaining, cn = DataType<_Tp>::channels; 01980 int _fmt = DataType<_Tp>::fmt; 01981 char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' }; 01982 count = std::min(count, remaining/cn); 01983 vec.resize(count); 01984 it->readRaw( string(fmt), (uchar*)&vec[0], count*sizeof(_Tp) ); 01985 } 01986 FileNodeIterator* it; 01987 }; 01988 01989 template<typename _Tp> static inline void 01990 read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX ) 01991 { 01992 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); 01993 r(vec, maxCount); 01994 } 01995 01996 template<typename _Tp> static inline void 01997 read( FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() ) 01998 { 01999 read( node.begin(), vec ); 02000 } 02001 02002 inline FileNodeIterator FileNode::begin() const 02003 { 02004 return FileNodeIterator(fs, node); 02005 } 02006 02007 inline FileNodeIterator FileNode::end() const 02008 { 02009 return FileNodeIterator(fs, node, size()); 02010 } 02011 02012 inline FileNode FileNodeIterator::operator *() const 02013 { return FileNode(fs, (const CvFileNode*)reader.ptr); } 02014 02015 inline FileNode FileNodeIterator::operator ->() const 02016 { return FileNode(fs, (const CvFileNode*)reader.ptr); } 02017 02018 template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) 02019 { read( *it, value, _Tp()); return ++it; } 02020 02021 template<typename _Tp> static inline 02022 FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec) 02023 { 02024 VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); 02025 r(vec, (size_t)INT_MAX); 02026 return it; 02027 } 02028 02029 template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value) 02030 { FileNodeIterator it = n.begin(); it >> value; } 02031 02032 static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2) 02033 { 02034 return it1.fs == it2.fs && it1.container == it2.container && 02035 it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining; 02036 } 02037 02038 static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2) 02039 { 02040 return !(it1 == it2); 02041 } 02042 02043 static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2) 02044 { 02045 return it2.remaining - it1.remaining; 02046 } 02047 02048 static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) 02049 { 02050 return it1.remaining > it2.remaining; 02051 } 02052 02053 inline FileNode FileStorage::getFirstTopLevelNode() const 02054 { 02055 FileNode r = root(); 02056 FileNodeIterator it = r.begin(); 02057 return it != r.end() ? *it : FileNode(); 02058 } 02059 02061 02062 template<typename _Tp> static inline _Tp gcd(_Tp a, _Tp b) 02063 { 02064 if( a < b ) 02065 std::swap(a, b); 02066 while( b > 0 ) 02067 { 02068 _Tp r = a % b; 02069 a = b; 02070 b = r; 02071 } 02072 return a; 02073 } 02074 02075 /****************************************************************************************\ 02076 02077 Generic implementation of QuickSort algorithm 02078 Use it as: vector<_Tp> a; ... sort(a,<less_than_predictor>); 02079 02080 The current implementation was derived from *BSD system qsort(): 02081 02082 * Copyright (c) 1992, 1993 02083 * The Regents of the University of California. All rights reserved. 02084 * 02085 * Redistribution and use in source and binary forms, with or without 02086 * modification, are permitted provided that the following conditions 02087 * are met: 02088 * 1. Redistributions of source code must retain the above copyright 02089 * notice, this list of conditions and the following disclaimer. 02090 * 2. Redistributions in binary form must reproduce the above copyright 02091 * notice, this list of conditions and the following disclaimer in the 02092 * documentation and/or other materials provided with the distribution. 02093 * 3. All advertising materials mentioning features or use of this software 02094 * must display the following acknowledgement: 02095 * This product includes software developed by the University of 02096 * California, Berkeley and its contributors. 02097 * 4. Neither the name of the University nor the names of its contributors 02098 * may be used to endorse or promote products derived from this software 02099 * without specific prior written permission. 02100 * 02101 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 02102 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 02103 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 02104 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 02105 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 02106 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 02107 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 02108 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 02109 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 02110 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 02111 * SUCH DAMAGE. 02112 02113 \****************************************************************************************/ 02114 02115 template<typename _Tp, class _LT> void sort( vector<_Tp>& vec, _LT LT=_LT() ) 02116 { 02117 int isort_thresh = 7; 02118 int sp = 0; 02119 02120 struct 02121 { 02122 _Tp *lb; 02123 _Tp *ub; 02124 } 02125 stack[48]; 02126 02127 size_t total = vec.size(); 02128 02129 if( total <= 1 ) 02130 return; 02131 02132 _Tp* arr = &vec[0]; 02133 stack[0].lb = arr; 02134 stack[0].ub = arr + (total - 1); 02135 02136 while( sp >= 0 ) 02137 { 02138 _Tp* left = stack[sp].lb; 02139 _Tp* right = stack[sp--].ub; 02140 02141 for(;;) 02142 { 02143 int i, n = (int)(right - left) + 1, m; 02144 _Tp* ptr; 02145 _Tp* ptr2; 02146 02147 if( n <= isort_thresh ) 02148 { 02149 insert_sort: 02150 for( ptr = left + 1; ptr <= right; ptr++ ) 02151 { 02152 for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) 02153 std::swap( ptr2[0], ptr2[-1] ); 02154 } 02155 break; 02156 } 02157 else 02158 { 02159 _Tp* left0; 02160 _Tp* left1; 02161 _Tp* right0; 02162 _Tp* right1; 02163 _Tp* pivot; 02164 _Tp* a; 02165 _Tp* b; 02166 _Tp* c; 02167 int swap_cnt = 0; 02168 02169 left0 = left; 02170 right0 = right; 02171 pivot = left + (n/2); 02172 02173 if( n > 40 ) 02174 { 02175 int d = n / 8; 02176 a = left, b = left + d, c = left + 2*d; 02177 left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) 02178 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); 02179 02180 a = pivot - d, b = pivot, c = pivot + d; 02181 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) 02182 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); 02183 02184 a = right - 2*d, b = right - d, c = right; 02185 right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) 02186 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); 02187 } 02188 02189 a = left, b = pivot, c = right; 02190 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) 02191 : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); 02192 if( pivot != left0 ) 02193 { 02194 std::swap( *pivot, *left0 ); 02195 pivot = left0; 02196 } 02197 left = left1 = left0 + 1; 02198 right = right1 = right0; 02199 02200 for(;;) 02201 { 02202 while( left <= right && !LT(*pivot, *left) ) 02203 { 02204 if( !LT(*left, *pivot) ) 02205 { 02206 if( left > left1 ) 02207 std::swap( *left1, *left ); 02208 swap_cnt = 1; 02209 left1++; 02210 } 02211 left++; 02212 } 02213 02214 while( left <= right && !LT(*right, *pivot) ) 02215 { 02216 if( !LT(*pivot, *right) ) 02217 { 02218 if( right < right1 ) 02219 std::swap( *right1, *right ); 02220 swap_cnt = 1; 02221 right1--; 02222 } 02223 right--; 02224 } 02225 02226 if( left > right ) 02227 break; 02228 std::swap( *left, *right ); 02229 swap_cnt = 1; 02230 left++; 02231 right--; 02232 } 02233 02234 if( swap_cnt == 0 ) 02235 { 02236 left = left0, right = right0; 02237 goto insert_sort; 02238 } 02239 02240 n = std::min( (int)(left1 - left0), (int)(left - left1) ); 02241 for( i = 0; i < n; i++ ) 02242 std::swap( left0[i], left[i-n] ); 02243 02244 n = std::min( (int)(right0 - right1), (int)(right1 - right) ); 02245 for( i = 0; i < n; i++ ) 02246 std::swap( left[i], right0[i-n+1] ); 02247 n = (int)(left - left1); 02248 m = (int)(right1 - right); 02249 if( n > 1 ) 02250 { 02251 if( m > 1 ) 02252 { 02253 if( n > m ) 02254 { 02255 stack[++sp].lb = left0; 02256 stack[sp].ub = left0 + n - 1; 02257 left = right0 - m + 1, right = right0; 02258 } 02259 else 02260 { 02261 stack[++sp].lb = right0 - m + 1; 02262 stack[sp].ub = right0; 02263 left = left0, right = left0 + n - 1; 02264 } 02265 } 02266 else 02267 left = left0, right = left0 + n - 1; 02268 } 02269 else if( m > 1 ) 02270 left = right0 - m + 1, right = right0; 02271 else 02272 break; 02273 } 02274 } 02275 } 02276 } 02277 02278 template<typename _Tp> class CV_EXPORTS LessThan 02279 { 02280 public: 02281 bool operator()(const _Tp& a, const _Tp& b) const { return a < b; } 02282 }; 02283 02284 template<typename _Tp> class CV_EXPORTS GreaterEq 02285 { 02286 public: 02287 bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; } 02288 }; 02289 02290 template<typename _Tp> class CV_EXPORTS LessThanIdx 02291 { 02292 public: 02293 LessThanIdx( const _Tp* _arr ) : arr(_arr) {} 02294 bool operator()(int a, int b) const { return arr[a] < arr[b]; } 02295 const _Tp* arr; 02296 }; 02297 02298 template<typename _Tp> class CV_EXPORTS GreaterEqIdx 02299 { 02300 public: 02301 GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {} 02302 bool operator()(int a, int b) const { return arr[a] >= arr[b]; } 02303 const _Tp* arr; 02304 }; 02305 02306 02307 // This function splits the input sequence or set into one or more equivalence classes and 02308 // returns the vector of labels - 0-based class indexes for each element. 02309 // predicate(a,b) returns true if the two sequence elements certainly belong to the same class. 02310 // 02311 // The algorithm is described in "Introduction to Algorithms" 02312 // by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets" 02313 template<typename _Tp, class _EqPredicate> int 02314 partition( const vector<_Tp>& _vec, vector<int>& labels, 02315 _EqPredicate predicate=_EqPredicate()) 02316 { 02317 int i, j, N = (int)_vec.size(); 02318 const _Tp* vec = &_vec[0]; 02319 02320 const int PARENT=0; 02321 const int RANK=1; 02322 02323 vector<int> _nodes(N*2); 02324 int (*nodes)[2] = (int(*)[2])&_nodes[0]; 02325 02326 // The first O(N) pass: create N single-vertex trees 02327 for(i = 0; i < N; i++) 02328 { 02329 nodes[i][PARENT]=-1; 02330 nodes[i][RANK] = 0; 02331 } 02332 02333 // The main O(N^2) pass: merge connected components 02334 for( i = 0; i < N; i++ ) 02335 { 02336 int root = i; 02337 02338 // find root 02339 while( nodes[root][PARENT] >= 0 ) 02340 root = nodes[root][PARENT]; 02341 02342 for( j = 0; j < N; j++ ) 02343 { 02344 if( i == j || !predicate(vec[i], vec[j])) 02345 continue; 02346 int root2 = j; 02347 02348 while( nodes[root2][PARENT] >= 0 ) 02349 root2 = nodes[root2][PARENT]; 02350 02351 if( root2 != root ) 02352 { 02353 // unite both trees 02354 int rank = nodes[root][RANK], rank2 = nodes[root2][RANK]; 02355 if( rank > rank2 ) 02356 nodes[root2][PARENT] = root; 02357 else 02358 { 02359 nodes[root][PARENT] = root2; 02360 nodes[root2][RANK] += rank == rank2; 02361 root = root2; 02362 } 02363 assert( nodes[root][PARENT] < 0 ); 02364 02365 int k = j, parent; 02366 02367 // compress the path from node2 to root 02368 while( (parent = nodes[k][PARENT]) >= 0 ) 02369 { 02370 nodes[k][PARENT] = root; 02371 k = parent; 02372 } 02373 02374 // compress the path from node to root 02375 k = i; 02376 while( (parent = nodes[k][PARENT]) >= 0 ) 02377 { 02378 nodes[k][PARENT] = root; 02379 k = parent; 02380 } 02381 } 02382 } 02383 } 02384 02385 // Final O(N) pass: enumerate classes 02386 labels.resize(N); 02387 int nclasses = 0; 02388 02389 for( i = 0; i < N; i++ ) 02390 { 02391 int root = i; 02392 while( nodes[root][PARENT] >= 0 ) 02393 root = nodes[root][PARENT]; 02394 // re-use the rank as the class label 02395 if( nodes[root][RANK] >= 0 ) 02396 nodes[root][RANK] = ~nclasses++; 02397 labels[i] = ~nodes[root][RANK]; 02398 } 02399 02400 return nclasses; 02401 } 02402 02404 02405 template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {} 02406 template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq) 02407 { 02408 CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp)); 02409 } 02410 02411 template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage, 02412 int headerSize ) 02413 { 02414 CV_Assert(headerSize >= (int)sizeof(CvSeq)); 02415 seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage); 02416 } 02417 02418 template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx) 02419 { return *(_Tp*)cvGetSeqElem(seq, idx); } 02420 02421 template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const 02422 { return *(_Tp*)cvGetSeqElem(seq, idx); } 02423 02424 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const 02425 { return SeqIterator<_Tp>(*this); } 02426 02427 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const 02428 { return SeqIterator<_Tp>(*this, true); } 02429 02430 template<typename _Tp> inline size_t Seq<_Tp>::size() const 02431 { return seq ? seq->total : 0; } 02432 02433 template<typename _Tp> inline int Seq<_Tp>::type() const 02434 { return seq ? CV_MAT_TYPE(seq->flags) : 0; } 02435 02436 template<typename _Tp> inline int Seq<_Tp>::depth() const 02437 { return seq ? CV_MAT_DEPTH(seq->flags) : 0; } 02438 02439 template<typename _Tp> inline int Seq<_Tp>::channels() const 02440 { return seq ? CV_MAT_CN(seq->flags) : 0; } 02441 02442 template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const 02443 { return seq ? seq->elem_size : 0; } 02444 02445 template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const 02446 { return cvSeqElemIdx(seq, &elem); } 02447 02448 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem) 02449 { cvSeqPush(seq, &elem); } 02450 02451 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem) 02452 { cvSeqPushFront(seq, &elem); } 02453 02454 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count) 02455 { cvSeqPushMulti(seq, elem, (int)count, 0); } 02456 02457 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count) 02458 { cvSeqPushMulti(seq, elem, (int)count, 1); } 02459 02460 template<typename _Tp> inline _Tp& Seq<_Tp>::back() 02461 { return *(_Tp*)cvGetSeqElem(seq, -1); } 02462 02463 template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const 02464 { return *(const _Tp*)cvGetSeqElem(seq, -1); } 02465 02466 template<typename _Tp> inline _Tp& Seq<_Tp>::front() 02467 { return *(_Tp*)cvGetSeqElem(seq, 0); } 02468 02469 template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const 02470 { return *(const _Tp*)cvGetSeqElem(seq, 0); } 02471 02472 template<typename _Tp> inline bool Seq<_Tp>::empty() const 02473 { return !seq || seq->total == 0; } 02474 02475 template<typename _Tp> inline void Seq<_Tp>::clear() 02476 { if(seq) cvClearSeq(seq); } 02477 02478 template<typename _Tp> inline void Seq<_Tp>::pop_back() 02479 { cvSeqPop(seq); } 02480 02481 template<typename _Tp> inline void Seq<_Tp>::pop_front() 02482 { cvSeqPopFront(seq); } 02483 02484 template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count) 02485 { cvSeqPopMulti(seq, elem, (int)count, 0); } 02486 02487 template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count) 02488 { cvSeqPopMulti(seq, elem, (int)count, 1); } 02489 02490 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem) 02491 { cvSeqInsert(seq, idx, &elem); } 02492 02493 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count) 02494 { 02495 CvMat m = cvMat(1, count, DataType<_Tp>::type, elems); 02496 cvSeqInsertSlice(seq, idx, &m); 02497 } 02498 02499 template<typename _Tp> inline void Seq<_Tp>::remove(int idx) 02500 { cvSeqRemove(seq, idx); } 02501 02502 template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r) 02503 { cvSeqRemoveSlice(seq, r); } 02504 02505 template<typename _Tp> inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const 02506 { 02507 size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start; 02508 vec.resize(len); 02509 if( seq && len ) 02510 cvCvtSeqToArray(seq, &vec[0], range); 02511 } 02512 02513 template<typename _Tp> inline Seq<_Tp>::operator vector<_Tp>() const 02514 { 02515 vector<_Tp> vec; 02516 copyTo(vec); 02517 return vec; 02518 } 02519 02520 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator() 02521 { memset(this, 0, sizeof(*this)); } 02522 02523 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd) 02524 { 02525 cvStartReadSeq(seq.seq, this); 02526 index = seekEnd ? seq.seq->total : 0; 02527 } 02528 02529 template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos) 02530 { 02531 cvSetSeqReaderPos(this, (int)pos, false); 02532 index = pos; 02533 } 02534 02535 template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const 02536 { return index; } 02537 02538 template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *() 02539 { return *(_Tp*)ptr; } 02540 02541 template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const 02542 { return *(const _Tp*)ptr; } 02543 02544 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++() 02545 { 02546 CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this); 02547 if( ++index >= seq->total*2 ) 02548 index = 0; 02549 return *this; 02550 } 02551 02552 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const 02553 { 02554 SeqIterator<_Tp> it = *this; 02555 ++*this; 02556 return it; 02557 } 02558 02559 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --() 02560 { 02561 CV_PREV_SEQ_ELEM(sizeof(_Tp), *this); 02562 if( --index < 0 ) 02563 index = seq->total*2-1; 02564 return *this; 02565 } 02566 02567 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const 02568 { 02569 SeqIterator<_Tp> it = *this; 02570 --*this; 02571 return it; 02572 } 02573 02574 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta) 02575 { 02576 cvSetSeqReaderPos(this, delta, 1); 02577 index += delta; 02578 int n = seq->total*2; 02579 if( index < 0 ) 02580 index += n; 02581 if( index >= n ) 02582 index -= n; 02583 return *this; 02584 } 02585 02586 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta) 02587 { 02588 return (*this += -delta); 02589 } 02590 02591 template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a, 02592 const SeqIterator<_Tp>& b) 02593 { 02594 ptrdiff_t delta = a.index - b.index, n = a.seq->total; 02595 if( std::abs(static_cast<long>(delta)) > n ) 02596 delta += delta < 0 ? n : -n; 02597 return delta; 02598 } 02599 02600 template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a, 02601 const SeqIterator<_Tp>& b) 02602 { 02603 return a.seq == b.seq && a.index == b.index; 02604 } 02605 02606 template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a, 02607 const SeqIterator<_Tp>& b) 02608 { 02609 return !(a == b); 02610 } 02611 02612 } 02613 02614 #endif // __cplusplus 02615 #endif