![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
opencv on mbed
Embed:
(wiki syntax)
Show/hide line numbers
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 16:42:39 by
![doxygen](doxygen.png)