Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
matx.hpp
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 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 00016 // Third party copyrights are property of their respective owners. 00017 // 00018 // Redistribution and use in source and binary forms, with or without modification, 00019 // are permitted provided that the following conditions are met: 00020 // 00021 // * Redistribution's of source code must retain the above copyright notice, 00022 // this list of conditions and the following disclaimer. 00023 // 00024 // * Redistribution's in binary form must reproduce the above copyright notice, 00025 // this list of conditions and the following disclaimer in the documentation 00026 // and/or other materials provided with the distribution. 00027 // 00028 // * The name of the copyright holders may not be used to endorse or promote products 00029 // derived from this software without specific prior written permission. 00030 // 00031 // This software is provided by the copyright holders and contributors "as is" and 00032 // any express or implied warranties, including, but not limited to, the implied 00033 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00034 // In no event shall the Intel Corporation or contributors be liable for any direct, 00035 // indirect, incidental, special, exemplary, or consequential damages 00036 // (including, but not limited to, procurement of substitute goods or services; 00037 // loss of use, data, or profits; or business interruption) however caused 00038 // and on any theory of liability, whether in contract, strict liability, 00039 // or tort (including negligence or otherwise) arising in any way out of 00040 // the use of this software, even if advised of the possibility of such damage. 00041 // 00042 //M*/ 00043 00044 #ifndef __OPENCV_CORE_MATX_HPP__ 00045 #define __OPENCV_CORE_MATX_HPP__ 00046 00047 #ifndef __cplusplus 00048 # error matx.hpp header must be compiled as C++ 00049 #endif 00050 00051 #include "opencv2/core/cvdef.h" 00052 #include "opencv2/core/base.hpp" 00053 #include "opencv2/core/traits.hpp" 00054 #include "opencv2/core/saturate.hpp" 00055 00056 namespace cv 00057 { 00058 00059 //! @addtogroup core_basic 00060 //! @{ 00061 00062 ////////////////////////////// Small Matrix /////////////////////////// 00063 00064 //! @cond IGNORED 00065 struct CV_EXPORTS Matx_AddOp {}; 00066 struct CV_EXPORTS Matx_SubOp {}; 00067 struct CV_EXPORTS Matx_ScaleOp {}; 00068 struct CV_EXPORTS Matx_MulOp {}; 00069 struct CV_EXPORTS Matx_DivOp {}; 00070 struct CV_EXPORTS Matx_MatMulOp {}; 00071 struct CV_EXPORTS Matx_TOp {}; 00072 //! @endcond 00073 00074 /** @brief Template class for small matrices whose type and size are known at compilation time 00075 00076 If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the 00077 M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are 00078 available. To do an operation on Matx that is not implemented, you can easily convert the matrix to 00079 Mat and backwards: 00080 @code 00081 Matx33f m(1, 2, 3, 00082 4, 5, 6, 00083 7, 8, 9); 00084 cout << sum(Mat(m*m.t())) << endl; 00085 @endcode 00086 */ 00087 template<typename _Tp, int m, int n> class Matx 00088 { 00089 public: 00090 enum { depth = DataType<_Tp>::depth, 00091 rows = m, 00092 cols = n, 00093 channels = rows*cols, 00094 type = CV_MAKETYPE(depth, channels), 00095 shortdim = (m < n ? m : n) 00096 }; 00097 00098 typedef _Tp value_type; 00099 typedef Matx<_Tp, m, n> mat_type; 00100 typedef Matx<_Tp, shortdim, 1> diag_type; 00101 00102 //! default constructor 00103 Matx(); 00104 00105 Matx(_Tp v0); //!< 1x1 matrix 00106 Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix 00107 Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix 00108 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix 00109 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix 00110 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix 00111 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix 00112 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix 00113 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix 00114 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix 00115 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00116 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 00117 _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix 00118 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00119 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 00120 _Tp v8, _Tp v9, _Tp v10, _Tp v11, 00121 _Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix 00122 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 00123 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 00124 _Tp v8, _Tp v9, _Tp v10, _Tp v11, 00125 _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix 00126 explicit Matx(const _Tp* vals); //!< initialize from a plain array 00127 00128 static Matx all(_Tp alpha); 00129 static Matx zeros(); 00130 static Matx ones(); 00131 static Matx eye(); 00132 static Matx diag(const diag_type& d); 00133 static Matx randu(_Tp a, _Tp b); 00134 static Matx randn(_Tp a, _Tp b); 00135 00136 //! dot product computed with the default precision 00137 _Tp dot(const Matx<_Tp, m, n>& v) const; 00138 00139 //! dot product computed in double-precision arithmetics 00140 double ddot(const Matx<_Tp, m, n>& v) const; 00141 00142 //! conversion to another data type 00143 template<typename T2> operator Matx<T2, m, n>() const; 00144 00145 //! change the matrix shape 00146 template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const; 00147 00148 //! extract part of the matrix 00149 template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const; 00150 00151 //! extract the matrix row 00152 Matx<_Tp, 1, n> row(int i) const; 00153 00154 //! extract the matrix column 00155 Matx<_Tp, m, 1> col(int i) const; 00156 00157 //! extract the matrix diagonal 00158 diag_type diag() const; 00159 00160 //! transpose the matrix 00161 Matx<_Tp, n, m> t() const; 00162 00163 //! invert the matrix 00164 Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const; 00165 00166 //! solve linear system 00167 template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const; 00168 Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const; 00169 00170 //! multiply two matrices element-wise 00171 Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const; 00172 00173 //! divide two matrices element-wise 00174 Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const; 00175 00176 //! element access 00177 const _Tp& operator ()(int i, int j) const; 00178 _Tp& operator ()(int i, int j); 00179 00180 //! 1D element access 00181 const _Tp& operator ()(int i) const; 00182 _Tp& operator ()(int i); 00183 00184 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp); 00185 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp); 00186 template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp); 00187 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp); 00188 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp); 00189 template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp); 00190 Matx(const Matx<_Tp, n, m>& a, Matx_TOp); 00191 00192 _Tp val[m*n]; //< matrix elements 00193 }; 00194 00195 typedef Matx<float, 1, 2> Matx12f; 00196 typedef Matx<double, 1, 2> Matx12d; 00197 typedef Matx<float, 1, 3> Matx13f; 00198 typedef Matx<double, 1, 3> Matx13d; 00199 typedef Matx<float, 1, 4> Matx14f; 00200 typedef Matx<double, 1, 4> Matx14d; 00201 typedef Matx<float, 1, 6> Matx16f; 00202 typedef Matx<double, 1, 6> Matx16d; 00203 00204 typedef Matx<float, 2, 1> Matx21f; 00205 typedef Matx<double, 2, 1> Matx21d; 00206 typedef Matx<float, 3, 1> Matx31f; 00207 typedef Matx<double, 3, 1> Matx31d; 00208 typedef Matx<float, 4, 1> Matx41f; 00209 typedef Matx<double, 4, 1> Matx41d; 00210 typedef Matx<float, 6, 1> Matx61f; 00211 typedef Matx<double, 6, 1> Matx61d; 00212 00213 typedef Matx<float, 2, 2> Matx22f; 00214 typedef Matx<double, 2, 2> Matx22d; 00215 typedef Matx<float, 2, 3> Matx23f; 00216 typedef Matx<double, 2, 3> Matx23d; 00217 typedef Matx<float, 3, 2> Matx32f; 00218 typedef Matx<double, 3, 2> Matx32d; 00219 00220 typedef Matx<float, 3, 3> Matx33f; 00221 typedef Matx<double, 3, 3> Matx33d; 00222 00223 typedef Matx<float, 3, 4> Matx34f; 00224 typedef Matx<double, 3, 4> Matx34d; 00225 typedef Matx<float, 4, 3> Matx43f; 00226 typedef Matx<double, 4, 3> Matx43d; 00227 00228 typedef Matx<float, 4, 4> Matx44f; 00229 typedef Matx<double, 4, 4> Matx44d; 00230 typedef Matx<float, 6, 6> Matx66f; 00231 typedef Matx<double, 6, 6> Matx66d; 00232 00233 /*! 00234 traits 00235 */ 00236 template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> > 00237 { 00238 public: 00239 typedef Matx<_Tp, m, n> value_type; 00240 typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type; 00241 typedef _Tp channel_type; 00242 typedef value_type vec_type; 00243 00244 enum { generic_type = 0, 00245 depth = DataType<channel_type>::depth, 00246 channels = m * n, 00247 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8), 00248 type = CV_MAKETYPE(depth, channels) 00249 }; 00250 }; 00251 00252 /** @brief Comma-separated Matrix Initializer 00253 */ 00254 template<typename _Tp, int m, int n> class MatxCommaInitializer 00255 { 00256 public: 00257 MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); 00258 template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); 00259 Matx<_Tp, m, n> operator *() const; 00260 00261 Matx<_Tp, m, n>* dst; 00262 int idx; 00263 }; 00264 00265 /* 00266 Utility methods 00267 */ 00268 template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a); 00269 template<typename _Tp, int m, int n> static double trace(const Matx<_Tp, m, n>& a); 00270 template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M); 00271 template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M, int normType); 00272 00273 00274 00275 /////////////////////// Vec (used as element of multi-channel images ///////////////////// 00276 00277 /** @brief Template class for short numerical vectors, a partial case of Matx 00278 00279 This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you 00280 can perform basic arithmetical operations, access individual elements using [] operator etc. The 00281 vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which 00282 elements are dynamically allocated in the heap. 00283 00284 The template takes 2 parameters: 00285 @tparam _Tp element type 00286 @tparam cn the number of elements 00287 00288 In addition to the universal notation like Vec<float, 3>, you can use shorter aliases 00289 for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>. 00290 00291 It is possible to convert Vec<T,2> to/from Point_, Vec<T,3> to/from Point3_ , and Vec<T,4> 00292 to CvScalar or Scalar_. Use operator[] to access the elements of Vec. 00293 00294 All the expected vector operations are also implemented: 00295 - v1 = v2 + v3 00296 - v1 = v2 - v3 00297 - v1 = v2 \* scale 00298 - v1 = scale \* v2 00299 - v1 = -v2 00300 - v1 += v2 and other augmenting operations 00301 - v1 == v2, v1 != v2 00302 - norm(v1) (euclidean norm) 00303 The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details. 00304 */ 00305 template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> 00306 { 00307 public: 00308 typedef _Tp value_type; 00309 enum { depth = Matx<_Tp, cn, 1>::depth, 00310 channels = cn, 00311 type = CV_MAKETYPE(depth, channels) 00312 }; 00313 00314 //! default constructor 00315 Vec(); 00316 00317 Vec(_Tp v0); //!< 1-element vector constructor 00318 Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor 00319 Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor 00320 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor 00321 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor 00322 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor 00323 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor 00324 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor 00325 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor 00326 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor 00327 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor 00328 explicit Vec(const _Tp* values); 00329 00330 Vec(const Vec<_Tp, cn>& v); 00331 00332 static Vec all(_Tp alpha); 00333 00334 //! per-element multiplication 00335 Vec mul(const Vec<_Tp, cn>& v) const; 00336 00337 //! conjugation (makes sense for complex numbers and quaternions) 00338 Vec conj() const; 00339 00340 /*! 00341 cross product of the two 3D vectors. 00342 00343 For other dimensionalities the exception is raised 00344 */ 00345 Vec cross(const Vec& v) const; 00346 //! conversion to another data type 00347 template<typename T2> operator Vec<T2, cn>() const; 00348 00349 /*! element access */ 00350 const _Tp& operator [](int i) const; 00351 _Tp& operator[](int i); 00352 const _Tp& operator ()(int i) const; 00353 _Tp& operator ()(int i); 00354 00355 Vec(const Matx<_Tp, cn, 1> & a, const Matx<_Tp, cn, 1> & b, Matx_AddOp); 00356 Vec(const Matx<_Tp, cn, 1> & a, const Matx<_Tp, cn, 1> & b, Matx_SubOp); 00357 template<typename _T2> Vec(const Matx<_Tp, cn, 1> & a, _T2 alpha, Matx_ScaleOp); 00358 }; 00359 00360 /** @name Shorter aliases for the most popular specializations of Vec<T,n> 00361 @{ 00362 */ 00363 typedef Vec<uchar, 2> Vec2b; 00364 typedef Vec<uchar, 3> Vec3b; 00365 typedef Vec<uchar, 4> Vec4b; 00366 00367 typedef Vec<short, 2> Vec2s; 00368 typedef Vec<short, 3> Vec3s; 00369 typedef Vec<short, 4> Vec4s; 00370 00371 typedef Vec<ushort, 2> Vec2w; 00372 typedef Vec<ushort, 3> Vec3w; 00373 typedef Vec<ushort, 4> Vec4w; 00374 00375 typedef Vec<int, 2> Vec2i; 00376 typedef Vec<int, 3> Vec3i; 00377 typedef Vec<int, 4> Vec4i ; 00378 typedef Vec<int, 6> Vec6i; 00379 typedef Vec<int, 8> Vec8i; 00380 00381 typedef Vec<float, 2> Vec2f; 00382 typedef Vec<float, 3> Vec3f; 00383 typedef Vec<float, 4> Vec4f; 00384 typedef Vec<float, 6> Vec6f; 00385 00386 typedef Vec<double, 2> Vec2d; 00387 typedef Vec<double, 3> Vec3d; 00388 typedef Vec<double, 4> Vec4d ; 00389 typedef Vec<double, 6> Vec6d; 00390 /** @} */ 00391 00392 /*! 00393 traits 00394 */ 00395 template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> > 00396 { 00397 public: 00398 typedef Vec<_Tp, cn> value_type; 00399 typedef Vec<typename DataType<_Tp>::work_type, cn> work_type; 00400 typedef _Tp channel_type; 00401 typedef value_type vec_type; 00402 00403 enum { generic_type = 0, 00404 depth = DataType<channel_type>::depth, 00405 channels = cn, 00406 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8), 00407 type = CV_MAKETYPE(depth, channels) 00408 }; 00409 }; 00410 00411 /** @brief Comma-separated Vec Initializer 00412 */ 00413 template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> 00414 { 00415 public: 00416 VecCommaInitializer(Vec<_Tp, m>* _vec); 00417 template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val); 00418 Vec<_Tp, m> operator *() const; 00419 }; 00420 00421 template<typename _Tp, int cn> static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v); 00422 00423 //! @} core_basic 00424 00425 //! @cond IGNORED 00426 00427 ///////////////////////////////////// helper classes ///////////////////////////////////// 00428 namespace internal 00429 { 00430 00431 template<typename _Tp, int m> struct Matx_DetOp 00432 { 00433 double operator ()(const Matx<_Tp, m, m>& a) const 00434 { 00435 Matx<_Tp, m, m> temp = a; 00436 double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); 00437 if( p == 0 ) 00438 return p; 00439 for( int i = 0; i < m; i++ ) 00440 p *= temp(i, i); 00441 return 1./p; 00442 } 00443 }; 00444 00445 template<typename _Tp> struct Matx_DetOp<_Tp, 1> 00446 { 00447 double operator ()(const Matx<_Tp, 1, 1>& a) const 00448 { 00449 return a(0,0); 00450 } 00451 }; 00452 00453 template<typename _Tp> struct Matx_DetOp<_Tp, 2> 00454 { 00455 double operator ()(const Matx<_Tp, 2, 2>& a) const 00456 { 00457 return a(0,0)*a(1,1) - a(0,1)*a(1,0); 00458 } 00459 }; 00460 00461 template<typename _Tp> struct Matx_DetOp<_Tp, 3> 00462 { 00463 double operator ()(const Matx<_Tp, 3, 3>& a) const 00464 { 00465 return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - 00466 a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + 00467 a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); 00468 } 00469 }; 00470 00471 template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) 00472 { 00473 return Vec<_Tp, 2>(v[0], -v[1]); 00474 } 00475 00476 template<typename _Tp> Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v) 00477 { 00478 return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); 00479 } 00480 00481 } // internal 00482 00483 00484 00485 ////////////////////////////////// Matx Implementation /////////////////////////////////// 00486 00487 template<typename _Tp, int m, int n> inline 00488 Matx<_Tp, m, n>::Matx() 00489 { 00490 for(int i = 0; i < channels; i++) val[i] = _Tp(0); 00491 } 00492 00493 template<typename _Tp, int m, int n> inline 00494 Matx<_Tp, m, n>::Matx(_Tp v0) 00495 { 00496 val[0] = v0; 00497 for(int i = 1; i < channels; i++) val[i] = _Tp(0); 00498 } 00499 00500 template<typename _Tp, int m, int n> inline 00501 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) 00502 { 00503 CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements."); 00504 val[0] = v0; val[1] = v1; 00505 for(int i = 2; i < channels; i++) val[i] = _Tp(0); 00506 } 00507 00508 template<typename _Tp, int m, int n> inline 00509 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) 00510 { 00511 CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements."); 00512 val[0] = v0; val[1] = v1; val[2] = v2; 00513 for(int i = 3; i < channels; i++) val[i] = _Tp(0); 00514 } 00515 00516 template<typename _Tp, int m, int n> inline 00517 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 00518 { 00519 CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements."); 00520 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00521 for(int i = 4; i < channels; i++) val[i] = _Tp(0); 00522 } 00523 00524 template<typename _Tp, int m, int n> inline 00525 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 00526 { 00527 CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements."); 00528 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; 00529 for(int i = 5; i < channels; i++) val[i] = _Tp(0); 00530 } 00531 00532 template<typename _Tp, int m, int n> inline 00533 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) 00534 { 00535 CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements."); 00536 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00537 val[4] = v4; val[5] = v5; 00538 for(int i = 6; i < channels; i++) val[i] = _Tp(0); 00539 } 00540 00541 template<typename _Tp, int m, int n> inline 00542 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) 00543 { 00544 CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements."); 00545 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00546 val[4] = v4; val[5] = v5; val[6] = v6; 00547 for(int i = 7; i < channels; i++) val[i] = _Tp(0); 00548 } 00549 00550 template<typename _Tp, int m, int n> inline 00551 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) 00552 { 00553 CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements."); 00554 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00555 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00556 for(int i = 8; i < channels; i++) val[i] = _Tp(0); 00557 } 00558 00559 template<typename _Tp, int m, int n> inline 00560 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) 00561 { 00562 CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements."); 00563 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00564 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00565 val[8] = v8; 00566 for(int i = 9; i < channels; i++) val[i] = _Tp(0); 00567 } 00568 00569 template<typename _Tp, int m, int n> inline 00570 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) 00571 { 00572 CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements."); 00573 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00574 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00575 val[8] = v8; val[9] = v9; 00576 for(int i = 10; i < channels; i++) val[i] = _Tp(0); 00577 } 00578 00579 00580 template<typename _Tp, int m, int n> inline 00581 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11) 00582 { 00583 CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements."); 00584 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00585 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00586 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; 00587 for(int i = 12; i < channels; i++) val[i] = _Tp(0); 00588 } 00589 00590 template<typename _Tp, int m, int n> inline 00591 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) 00592 { 00593 CV_StaticAssert(channels == 14, "Matx should have at least 14 elements."); 00594 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00595 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00596 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; 00597 val[12] = v12; val[13] = v13; 00598 } 00599 00600 00601 template<typename _Tp, int m, int n> inline 00602 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15) 00603 { 00604 CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements."); 00605 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 00606 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 00607 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; 00608 val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; 00609 for(int i = 16; i < channels; i++) val[i] = _Tp(0); 00610 } 00611 00612 template<typename _Tp, int m, int n> inline 00613 Matx<_Tp, m, n>::Matx(const _Tp* values) 00614 { 00615 for( int i = 0; i < channels; i++ ) val[i] = values[i]; 00616 } 00617 00618 template<typename _Tp, int m, int n> inline 00619 Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) 00620 { 00621 Matx<_Tp, m, n> M; 00622 for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; 00623 return M; 00624 } 00625 00626 template<typename _Tp, int m, int n> inline 00627 Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() 00628 { 00629 return all(0); 00630 } 00631 00632 template<typename _Tp, int m, int n> inline 00633 Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() 00634 { 00635 return all(1); 00636 } 00637 00638 template<typename _Tp, int m, int n> inline 00639 Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() 00640 { 00641 Matx<_Tp,m,n> M; 00642 for(int i = 0; i < shortdim; i++) 00643 M(i,i) = 1; 00644 return M; 00645 } 00646 00647 template<typename _Tp, int m, int n> inline 00648 _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const 00649 { 00650 _Tp s = 0; 00651 for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i]; 00652 return s; 00653 } 00654 00655 template<typename _Tp, int m, int n> inline 00656 double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const 00657 { 00658 double s = 0; 00659 for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i]; 00660 return s; 00661 } 00662 00663 template<typename _Tp, int m, int n> inline 00664 Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) 00665 { 00666 Matx<_Tp,m,n> M; 00667 for(int i = 0; i < shortdim; i++) 00668 M(i,i) = d(i, 0); 00669 return M; 00670 } 00671 00672 template<typename _Tp, int m, int n> template<typename T2> 00673 inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const 00674 { 00675 Matx<T2, m, n> M; 00676 for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]); 00677 return M; 00678 } 00679 00680 template<typename _Tp, int m, int n> template<int m1, int n1> inline 00681 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const 00682 { 00683 CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements"); 00684 return (const Matx<_Tp, m1, n1>&)*this; 00685 } 00686 00687 template<typename _Tp, int m, int n> 00688 template<int m1, int n1> inline 00689 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const 00690 { 00691 CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n); 00692 Matx<_Tp, m1, n1> s; 00693 for( int di = 0; di < m1; di++ ) 00694 for( int dj = 0; dj < n1; dj++ ) 00695 s(di, dj) = (*this)(i+di, j+dj); 00696 return s; 00697 } 00698 00699 template<typename _Tp, int m, int n> inline 00700 Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const 00701 { 00702 CV_DbgAssert((unsigned)i < (unsigned)m); 00703 return Matx<_Tp, 1, n>(&val[i*n]); 00704 } 00705 00706 template<typename _Tp, int m, int n> inline 00707 Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const 00708 { 00709 CV_DbgAssert((unsigned)j < (unsigned)n); 00710 Matx<_Tp, m, 1> v; 00711 for( int i = 0; i < m; i++ ) 00712 v.val[i] = val[i*n + j]; 00713 return v; 00714 } 00715 00716 template<typename _Tp, int m, int n> inline 00717 typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const 00718 { 00719 diag_type d; 00720 for( int i = 0; i < shortdim; i++ ) 00721 d.val[i] = val[i*n + i]; 00722 return d; 00723 } 00724 00725 template<typename _Tp, int m, int n> inline 00726 const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const 00727 { 00728 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); 00729 return this->val[i*n + j]; 00730 } 00731 00732 template<typename _Tp, int m, int n> inline 00733 _Tp& Matx<_Tp, m, n>::operator ()(int i, int j) 00734 { 00735 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); 00736 return val[i*n + j]; 00737 } 00738 00739 template<typename _Tp, int m, int n> inline 00740 const _Tp& Matx<_Tp, m, n>::operator ()(int i) const 00741 { 00742 CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); 00743 CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); 00744 return val[i]; 00745 } 00746 00747 template<typename _Tp, int m, int n> inline 00748 _Tp& Matx<_Tp, m, n>::operator ()(int i) 00749 { 00750 CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); 00751 CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); 00752 return val[i]; 00753 } 00754 00755 template<typename _Tp, int m, int n> inline 00756 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) 00757 { 00758 for( int i = 0; i < channels; i++ ) 00759 val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); 00760 } 00761 00762 template<typename _Tp, int m, int n> inline 00763 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) 00764 { 00765 for( int i = 0; i < channels; i++ ) 00766 val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); 00767 } 00768 00769 template<typename _Tp, int m, int n> template<typename _T2> inline 00770 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) 00771 { 00772 for( int i = 0; i < channels; i++ ) 00773 val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 00774 } 00775 00776 template<typename _Tp, int m, int n> inline 00777 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) 00778 { 00779 for( int i = 0; i < channels; i++ ) 00780 val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); 00781 } 00782 00783 template<typename _Tp, int m, int n> inline 00784 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp) 00785 { 00786 for( int i = 0; i < channels; i++ ) 00787 val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]); 00788 } 00789 00790 template<typename _Tp, int m, int n> template<int l> inline 00791 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) 00792 { 00793 for( int i = 0; i < m; i++ ) 00794 for( int j = 0; j < n; j++ ) 00795 { 00796 _Tp s = 0; 00797 for( int k = 0; k < l; k++ ) 00798 s += a(i, k) * b(k, j); 00799 val[i*n + j] = s; 00800 } 00801 } 00802 00803 template<typename _Tp, int m, int n> inline 00804 Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) 00805 { 00806 for( int i = 0; i < m; i++ ) 00807 for( int j = 0; j < n; j++ ) 00808 val[i*n + j] = a(j, i); 00809 } 00810 00811 template<typename _Tp, int m, int n> inline 00812 Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const 00813 { 00814 return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); 00815 } 00816 00817 template<typename _Tp, int m, int n> inline 00818 Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const 00819 { 00820 return Matx<_Tp, m, n>(*this, a, Matx_DivOp()); 00821 } 00822 00823 template<typename _Tp, int m, int n> inline 00824 Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const 00825 { 00826 return Matx<_Tp, n, m>(*this, Matx_TOp()); 00827 } 00828 00829 template<typename _Tp, int m, int n> inline 00830 Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const 00831 { 00832 Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method); 00833 return (Vec<_Tp, n>&)(x); 00834 } 00835 00836 template<typename _Tp, int m> static inline 00837 double determinant(const Matx<_Tp, m, m>& a) 00838 { 00839 return cv::internal::Matx_DetOp<_Tp, m>()(a); 00840 } 00841 00842 template<typename _Tp, int m, int n> static inline 00843 double trace(const Matx<_Tp, m, n>& a) 00844 { 00845 _Tp s = 0; 00846 for( int i = 0; i < std::min(m, n); i++ ) 00847 s += a(i,i); 00848 return s; 00849 } 00850 00851 template<typename _Tp, int m, int n> static inline 00852 double norm(const Matx<_Tp, m, n>& M) 00853 { 00854 return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); 00855 } 00856 00857 template<typename _Tp, int m, int n> static inline 00858 double norm(const Matx<_Tp, m, n>& M, int normType) 00859 { 00860 switch(normType) { 00861 case NORM_INF: 00862 return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); 00863 case NORM_L1: 00864 return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); 00865 case NORM_L2SQR: 00866 return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); 00867 default: 00868 case NORM_L2: 00869 return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); 00870 } 00871 } 00872 00873 00874 00875 //////////////////////////////// matx comma initializer ////////////////////////////////// 00876 00877 template<typename _Tp, typename _T2, int m, int n> static inline 00878 MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) 00879 { 00880 MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); 00881 return (commaInitializer, val); 00882 } 00883 00884 template<typename _Tp, int m, int n> inline 00885 MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) 00886 : dst(_mtx), idx(0) 00887 {} 00888 00889 template<typename _Tp, int m, int n> template<typename _T2> inline 00890 MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) 00891 { 00892 CV_DbgAssert( idx < m*n ); 00893 dst->val[idx++] = saturate_cast<_Tp>(value); 00894 return *this; 00895 } 00896 00897 template<typename _Tp, int m, int n> inline 00898 Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const 00899 { 00900 CV_DbgAssert( idx == n*m ); 00901 return *dst; 00902 } 00903 00904 00905 00906 /////////////////////////////////// Vec Implementation /////////////////////////////////// 00907 00908 template<typename _Tp, int cn> inline 00909 Vec<_Tp, cn>::Vec() {} 00910 00911 template<typename _Tp, int cn> inline 00912 Vec<_Tp, cn>::Vec(_Tp v0) 00913 : Matx<_Tp, cn, 1>(v0) {} 00914 00915 template<typename _Tp, int cn> inline 00916 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) 00917 : Matx<_Tp, cn, 1>(v0, v1) {} 00918 00919 template<typename _Tp, int cn> inline 00920 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) 00921 : Matx<_Tp, cn, 1>(v0, v1, v2) {} 00922 00923 template<typename _Tp, int cn> inline 00924 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 00925 : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} 00926 00927 template<typename _Tp, int cn> inline 00928 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 00929 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} 00930 00931 template<typename _Tp, int cn> inline 00932 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) 00933 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {} 00934 00935 template<typename _Tp, int cn> inline 00936 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) 00937 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {} 00938 00939 template<typename _Tp, int cn> inline 00940 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) 00941 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {} 00942 00943 template<typename _Tp, int cn> inline 00944 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) 00945 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {} 00946 00947 template<typename _Tp, int cn> inline 00948 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) 00949 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {} 00950 00951 template<typename _Tp, int cn> inline 00952 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) 00953 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {} 00954 00955 template<typename _Tp, int cn> inline 00956 Vec<_Tp, cn>::Vec(const _Tp* values) 00957 : Matx<_Tp, cn, 1>(values) {} 00958 00959 template<typename _Tp, int cn> inline 00960 Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) 00961 : Matx<_Tp, cn, 1>(m.val) {} 00962 00963 template<typename _Tp, int cn> inline 00964 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) 00965 : Matx<_Tp, cn, 1>(a, b, op) {} 00966 00967 template<typename _Tp, int cn> inline 00968 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) 00969 : Matx<_Tp, cn, 1>(a, b, op) {} 00970 00971 template<typename _Tp, int cn> template<typename _T2> inline 00972 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) 00973 : Matx<_Tp, cn, 1>(a, alpha, op) {} 00974 00975 template<typename _Tp, int cn> inline 00976 Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) 00977 { 00978 Vec v; 00979 for( int i = 0; i < cn; i++ ) v.val[i] = alpha; 00980 return v; 00981 } 00982 00983 template<typename _Tp, int cn> inline 00984 Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const 00985 { 00986 Vec<_Tp, cn> w; 00987 for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); 00988 return w; 00989 } 00990 00991 template<> inline 00992 Vec<float, 2> Vec<float, 2>::conj() const 00993 { 00994 return cv::internal::conjugate(*this); 00995 } 00996 00997 template<> inline 00998 Vec<double, 2> Vec<double, 2>::conj() const 00999 { 01000 return cv::internal::conjugate(*this); 01001 } 01002 01003 template<> inline 01004 Vec<float, 4> Vec<float, 4>::conj() const 01005 { 01006 return cv::internal::conjugate(*this); 01007 } 01008 01009 template<> inline 01010 Vec<double, 4> Vec<double, 4>::conj() const 01011 { 01012 return cv::internal::conjugate(*this); 01013 } 01014 01015 template<typename _Tp, int cn> inline 01016 Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const 01017 { 01018 CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined"); 01019 return Vec<_Tp, cn>(); 01020 } 01021 01022 template<> inline 01023 Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const 01024 { 01025 return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1], 01026 val[2]*v.val[0] - val[0]*v.val[2], 01027 val[0]*v.val[1] - val[1]*v.val[0]); 01028 } 01029 01030 template<> inline 01031 Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const 01032 { 01033 return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1], 01034 val[2]*v.val[0] - val[0]*v.val[2], 01035 val[0]*v.val[1] - val[1]*v.val[0]); 01036 } 01037 01038 template<typename _Tp, int cn> template<typename T2> inline 01039 Vec<_Tp, cn>::operator Vec<T2, cn>() const 01040 { 01041 Vec<T2, cn> v; 01042 for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]); 01043 return v; 01044 } 01045 01046 template<typename _Tp, int cn> inline 01047 const _Tp& Vec<_Tp, cn>::operator [](int i) const 01048 { 01049 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 01050 return this->val[i]; 01051 } 01052 01053 template<typename _Tp, int cn> inline 01054 _Tp& Vec<_Tp, cn>::operator [](int i) 01055 { 01056 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 01057 return this->val[i]; 01058 } 01059 01060 template<typename _Tp, int cn> inline 01061 const _Tp& Vec<_Tp, cn>::operator ()(int i) const 01062 { 01063 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 01064 return this->val[i]; 01065 } 01066 01067 template<typename _Tp, int cn> inline 01068 _Tp& Vec<_Tp, cn>::operator ()(int i) 01069 { 01070 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 01071 return this->val[i]; 01072 } 01073 01074 template<typename _Tp, int cn> inline 01075 Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) 01076 { 01077 double nv = norm(v); 01078 return v * (nv ? 1./nv : 0.); 01079 } 01080 01081 01082 01083 //////////////////////////////// matx comma initializer ////////////////////////////////// 01084 01085 01086 template<typename _Tp, typename _T2, int cn> static inline 01087 VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) 01088 { 01089 VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); 01090 return (commaInitializer, val); 01091 } 01092 01093 template<typename _Tp, int cn> inline 01094 VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) 01095 : MatxCommaInitializer<_Tp, cn, 1>(_vec) 01096 {} 01097 01098 template<typename _Tp, int cn> template<typename _T2> inline 01099 VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) 01100 { 01101 CV_DbgAssert( this->idx < cn ); 01102 this->dst->val[this->idx++] = saturate_cast<_Tp>(value); 01103 return *this; 01104 } 01105 01106 template<typename _Tp, int cn> inline 01107 Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const 01108 { 01109 CV_DbgAssert( this->idx == cn ); 01110 return *this->dst; 01111 } 01112 01113 //! @endcond 01114 01115 ///////////////////////////// Matx out-of-class operators //////////////////////////////// 01116 01117 //! @relates cv::Matx 01118 //! @{ 01119 01120 template<typename _Tp1, typename _Tp2, int m, int n> static inline 01121 Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) 01122 { 01123 for( int i = 0; i < m*n; i++ ) 01124 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); 01125 return a; 01126 } 01127 01128 template<typename _Tp1, typename _Tp2, int m, int n> static inline 01129 Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) 01130 { 01131 for( int i = 0; i < m*n; i++ ) 01132 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); 01133 return a; 01134 } 01135 01136 template<typename _Tp, int m, int n> static inline 01137 Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 01138 { 01139 return Matx<_Tp, m, n>(a, b, Matx_AddOp()); 01140 } 01141 01142 template<typename _Tp, int m, int n> static inline 01143 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 01144 { 01145 return Matx<_Tp, m, n>(a, b, Matx_SubOp()); 01146 } 01147 01148 template<typename _Tp, int m, int n> static inline 01149 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) 01150 { 01151 for( int i = 0; i < m*n; i++ ) 01152 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 01153 return a; 01154 } 01155 01156 template<typename _Tp, int m, int n> static inline 01157 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) 01158 { 01159 for( int i = 0; i < m*n; i++ ) 01160 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 01161 return a; 01162 } 01163 01164 template<typename _Tp, int m, int n> static inline 01165 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) 01166 { 01167 for( int i = 0; i < m*n; i++ ) 01168 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 01169 return a; 01170 } 01171 01172 template<typename _Tp, int m, int n> static inline 01173 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) 01174 { 01175 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01176 } 01177 01178 template<typename _Tp, int m, int n> static inline 01179 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) 01180 { 01181 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01182 } 01183 01184 template<typename _Tp, int m, int n> static inline 01185 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) 01186 { 01187 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01188 } 01189 01190 template<typename _Tp, int m, int n> static inline 01191 Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) 01192 { 01193 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01194 } 01195 01196 template<typename _Tp, int m, int n> static inline 01197 Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) 01198 { 01199 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01200 } 01201 01202 template<typename _Tp, int m, int n> static inline 01203 Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) 01204 { 01205 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 01206 } 01207 01208 template<typename _Tp, int m, int n> static inline 01209 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) 01210 { 01211 return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); 01212 } 01213 01214 template<typename _Tp, int m, int n, int l> static inline 01215 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) 01216 { 01217 return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); 01218 } 01219 01220 template<typename _Tp, int m, int n> static inline 01221 Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) 01222 { 01223 Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); 01224 return (const Vec<_Tp, m>&)(c); 01225 } 01226 01227 template<typename _Tp, int m, int n> static inline 01228 bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 01229 { 01230 for( int i = 0; i < m*n; i++ ) 01231 if( a.val[i] != b.val[i] ) return false; 01232 return true; 01233 } 01234 01235 template<typename _Tp, int m, int n> static inline 01236 bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 01237 { 01238 return !(a == b); 01239 } 01240 01241 //! @} 01242 01243 ////////////////////////////// Vec out-of-class operators //////////////////////////////// 01244 01245 //! @relates cv::Vec 01246 //! @{ 01247 01248 template<typename _Tp1, typename _Tp2, int cn> static inline 01249 Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 01250 { 01251 for( int i = 0; i < cn; i++ ) 01252 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); 01253 return a; 01254 } 01255 01256 template<typename _Tp1, typename _Tp2, int cn> static inline 01257 Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 01258 { 01259 for( int i = 0; i < cn; i++ ) 01260 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); 01261 return a; 01262 } 01263 01264 template<typename _Tp, int cn> static inline 01265 Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 01266 { 01267 return Vec<_Tp, cn>(a, b, Matx_AddOp()); 01268 } 01269 01270 template<typename _Tp, int cn> static inline 01271 Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 01272 { 01273 return Vec<_Tp, cn>(a, b, Matx_SubOp()); 01274 } 01275 01276 template<typename _Tp, int cn> static inline 01277 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) 01278 { 01279 for( int i = 0; i < cn; i++ ) 01280 a[i] = saturate_cast<_Tp>(a[i]*alpha); 01281 return a; 01282 } 01283 01284 template<typename _Tp, int cn> static inline 01285 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) 01286 { 01287 for( int i = 0; i < cn; i++ ) 01288 a[i] = saturate_cast<_Tp>(a[i]*alpha); 01289 return a; 01290 } 01291 01292 template<typename _Tp, int cn> static inline 01293 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) 01294 { 01295 for( int i = 0; i < cn; i++ ) 01296 a[i] = saturate_cast<_Tp>(a[i]*alpha); 01297 return a; 01298 } 01299 01300 template<typename _Tp, int cn> static inline 01301 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) 01302 { 01303 double ialpha = 1./alpha; 01304 for( int i = 0; i < cn; i++ ) 01305 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 01306 return a; 01307 } 01308 01309 template<typename _Tp, int cn> static inline 01310 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) 01311 { 01312 float ialpha = 1.f/alpha; 01313 for( int i = 0; i < cn; i++ ) 01314 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 01315 return a; 01316 } 01317 01318 template<typename _Tp, int cn> static inline 01319 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) 01320 { 01321 double ialpha = 1./alpha; 01322 for( int i = 0; i < cn; i++ ) 01323 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 01324 return a; 01325 } 01326 01327 template<typename _Tp, int cn> static inline 01328 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) 01329 { 01330 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01331 } 01332 01333 template<typename _Tp, int cn> static inline 01334 Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) 01335 { 01336 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01337 } 01338 01339 template<typename _Tp, int cn> static inline 01340 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) 01341 { 01342 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01343 } 01344 01345 template<typename _Tp, int cn> static inline 01346 Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) 01347 { 01348 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01349 } 01350 01351 template<typename _Tp, int cn> static inline 01352 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) 01353 { 01354 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01355 } 01356 01357 template<typename _Tp, int cn> static inline 01358 Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) 01359 { 01360 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 01361 } 01362 01363 template<typename _Tp, int cn> static inline 01364 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) 01365 { 01366 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 01367 } 01368 01369 template<typename _Tp, int cn> static inline 01370 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) 01371 { 01372 return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); 01373 } 01374 01375 template<typename _Tp, int cn> static inline 01376 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) 01377 { 01378 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 01379 } 01380 01381 template<typename _Tp, int cn> static inline 01382 Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) 01383 { 01384 Vec<_Tp,cn> t; 01385 for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); 01386 return t; 01387 } 01388 01389 template<typename _Tp> inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) 01390 { 01391 return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), 01392 saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), 01393 saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), 01394 saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); 01395 } 01396 01397 template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) 01398 { 01399 v1 = v1 * v2; 01400 return v1; 01401 } 01402 01403 //! @} 01404 01405 } // cv 01406 01407 #endif // __OPENCV_CORE_MATX_HPP__ 01408
Generated on Tue Jul 12 2022 14:47:25 by
