- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# /usr/obj/OpenCV-2.2.0/OpenCV-2.2.0/modules/core/include/opencv2/core/operations.hpp

Go to the documentation of this file.

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

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines