1/*M/////////////////////////////////////////////////////////////////////////////////////// 2// 3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4// 5// By downloading, copying, installing or using the software you agree to this license. 6// If you do not agree to this license, do not download, install, 7// copy or use the software. 8// 9// 10// License Agreement 11// For Open Source Computer Vision Library 12// 13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 14// Copyright (C) 2009, Willow Garage Inc., all rights reserved. 15// Copyright (C) 2013, OpenCV Foundation, all rights reserved. 16// Third party copyrights are property of their respective owners. 17// 18// Redistribution and use in source and binary forms, with or without modification, 19// are permitted provided that the following conditions are met: 20// 21// * Redistribution's of source code must retain the above copyright notice, 22// this list of conditions and the following disclaimer. 23// 24// * Redistribution's in binary form must reproduce the above copyright notice, 25// this list of conditions and the following disclaimer in the documentation 26// and/or other materials provided with the distribution. 27// 28// * The name of the copyright holders may not be used to endorse or promote products 29// derived from this software without specific prior written permission. 30// 31// This software is provided by the copyright holders and contributors "as is" and 32// any express or implied warranties, including, but not limited to, the implied 33// warranties of merchantability and fitness for a particular purpose are disclaimed. 34// In no event shall the Intel Corporation or contributors be liable for any direct, 35// indirect, incidental, special, exemplary, or consequential damages 36// (including, but not limited to, procurement of substitute goods or services; 37// loss of use, data, or profits; or business interruption) however caused 38// and on any theory of liability, whether in contract, strict liability, 39// or tort (including negligence or otherwise) arising in any way out of 40// the use of this software, even if advised of the possibility of such damage. 41// 42//M*/ 43 44#ifndef __OPENCV_CORE_MATX_HPP__ 45#define __OPENCV_CORE_MATX_HPP__ 46 47#ifndef __cplusplus 48# error matx.hpp header must be compiled as C++ 49#endif 50 51#include "opencv2/core/cvdef.h" 52#include "opencv2/core/base.hpp" 53#include "opencv2/core/traits.hpp" 54 55namespace cv 56{ 57 58//! @addtogroup core_basic 59//! @{ 60 61////////////////////////////// Small Matrix /////////////////////////// 62 63//! @cond IGNORED 64struct CV_EXPORTS Matx_AddOp {}; 65struct CV_EXPORTS Matx_SubOp {}; 66struct CV_EXPORTS Matx_ScaleOp {}; 67struct CV_EXPORTS Matx_MulOp {}; 68struct CV_EXPORTS Matx_DivOp {}; 69struct CV_EXPORTS Matx_MatMulOp {}; 70struct CV_EXPORTS Matx_TOp {}; 71//! @endcond 72 73/** @brief Template class for small matrices whose type and size are known at compilation time 74 75If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the 76M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are 77available. To do an operation on Matx that is not implemented, you can easily convert the matrix to 78Mat and backwards: 79@code 80 Matx33f m(1, 2, 3, 81 4, 5, 6, 82 7, 8, 9); 83 cout << sum(Mat(m*m.t())) << endl; 84 @endcode 85 */ 86template<typename _Tp, int m, int n> class Matx 87{ 88public: 89 enum { depth = DataType<_Tp>::depth, 90 rows = m, 91 cols = n, 92 channels = rows*cols, 93 type = CV_MAKETYPE(depth, channels), 94 shortdim = (m < n ? m : n) 95 }; 96 97 typedef _Tp value_type; 98 typedef Matx<_Tp, m, n> mat_type; 99 typedef Matx<_Tp, shortdim, 1> diag_type; 100 101 //! default constructor 102 Matx(); 103 104 Matx(_Tp v0); //!< 1x1 matrix 105 Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix 106 Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix 107 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix 108 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix 109 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix 110 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix 111 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix 112 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix 113 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 114 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 115 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 116 _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix 117 Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 118 _Tp v4, _Tp v5, _Tp v6, _Tp v7, 119 _Tp v8, _Tp v9, _Tp v10, _Tp v11, 120 _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix 121 explicit Matx(const _Tp* vals); //!< initialize from a plain array 122 123 static Matx all(_Tp alpha); 124 static Matx zeros(); 125 static Matx ones(); 126 static Matx eye(); 127 static Matx diag(const diag_type& d); 128 static Matx randu(_Tp a, _Tp b); 129 static Matx randn(_Tp a, _Tp b); 130 131 //! dot product computed with the default precision 132 _Tp dot(const Matx<_Tp, m, n>& v) const; 133 134 //! dot product computed in double-precision arithmetics 135 double ddot(const Matx<_Tp, m, n>& v) const; 136 137 //! conversion to another data type 138 template<typename T2> operator Matx<T2, m, n>() const; 139 140 //! change the matrix shape 141 template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const; 142 143 //! extract part of the matrix 144 template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const; 145 146 //! extract the matrix row 147 Matx<_Tp, 1, n> row(int i) const; 148 149 //! extract the matrix column 150 Matx<_Tp, m, 1> col(int i) const; 151 152 //! extract the matrix diagonal 153 diag_type diag() const; 154 155 //! transpose the matrix 156 Matx<_Tp, n, m> t() const; 157 158 //! invert the matrix 159 Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const; 160 161 //! solve linear system 162 template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const; 163 Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const; 164 165 //! multiply two matrices element-wise 166 Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const; 167 168 //! divide two matrices element-wise 169 Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const; 170 171 //! element access 172 const _Tp& operator ()(int i, int j) const; 173 _Tp& operator ()(int i, int j); 174 175 //! 1D element access 176 const _Tp& operator ()(int i) const; 177 _Tp& operator ()(int i); 178 179 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp); 180 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp); 181 template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp); 182 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp); 183 Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp); 184 template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp); 185 Matx(const Matx<_Tp, n, m>& a, Matx_TOp); 186 187 _Tp val[m*n]; //< matrix elements 188}; 189 190typedef Matx<float, 1, 2> Matx12f; 191typedef Matx<double, 1, 2> Matx12d; 192typedef Matx<float, 1, 3> Matx13f; 193typedef Matx<double, 1, 3> Matx13d; 194typedef Matx<float, 1, 4> Matx14f; 195typedef Matx<double, 1, 4> Matx14d; 196typedef Matx<float, 1, 6> Matx16f; 197typedef Matx<double, 1, 6> Matx16d; 198 199typedef Matx<float, 2, 1> Matx21f; 200typedef Matx<double, 2, 1> Matx21d; 201typedef Matx<float, 3, 1> Matx31f; 202typedef Matx<double, 3, 1> Matx31d; 203typedef Matx<float, 4, 1> Matx41f; 204typedef Matx<double, 4, 1> Matx41d; 205typedef Matx<float, 6, 1> Matx61f; 206typedef Matx<double, 6, 1> Matx61d; 207 208typedef Matx<float, 2, 2> Matx22f; 209typedef Matx<double, 2, 2> Matx22d; 210typedef Matx<float, 2, 3> Matx23f; 211typedef Matx<double, 2, 3> Matx23d; 212typedef Matx<float, 3, 2> Matx32f; 213typedef Matx<double, 3, 2> Matx32d; 214 215typedef Matx<float, 3, 3> Matx33f; 216typedef Matx<double, 3, 3> Matx33d; 217 218typedef Matx<float, 3, 4> Matx34f; 219typedef Matx<double, 3, 4> Matx34d; 220typedef Matx<float, 4, 3> Matx43f; 221typedef Matx<double, 4, 3> Matx43d; 222 223typedef Matx<float, 4, 4> Matx44f; 224typedef Matx<double, 4, 4> Matx44d; 225typedef Matx<float, 6, 6> Matx66f; 226typedef Matx<double, 6, 6> Matx66d; 227 228/*! 229 traits 230*/ 231template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> > 232{ 233public: 234 typedef Matx<_Tp, m, n> value_type; 235 typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type; 236 typedef _Tp channel_type; 237 typedef value_type vec_type; 238 239 enum { generic_type = 0, 240 depth = DataType<channel_type>::depth, 241 channels = m * n, 242 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8), 243 type = CV_MAKETYPE(depth, channels) 244 }; 245}; 246 247/** @brief Comma-separated Matrix Initializer 248*/ 249template<typename _Tp, int m, int n> class MatxCommaInitializer 250{ 251public: 252 MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); 253 template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); 254 Matx<_Tp, m, n> operator *() const; 255 256 Matx<_Tp, m, n>* dst; 257 int idx; 258}; 259 260/* 261 Utility methods 262*/ 263template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a); 264template<typename _Tp, int m, int n> static double trace(const Matx<_Tp, m, n>& a); 265template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M); 266template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M, int normType); 267 268 269 270/////////////////////// Vec (used as element of multi-channel images ///////////////////// 271 272/** @brief Template class for short numerical vectors, a partial case of Matx 273 274This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you 275can perform basic arithmetical operations, access individual elements using [] operator etc. The 276vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which 277elements are dynamically allocated in the heap. 278 279The template takes 2 parameters: 280@tparam _Tp element type 281@tparam cn the number of elements 282 283In addition to the universal notation like Vec<float, 3>, you can use shorter aliases 284for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>. 285 286It is possible to convert Vec\<T,2\> to/from Point_, Vec\<T,3\> to/from Point3_ , and Vec\<T,4\> 287to CvScalar or Scalar_. Use operator[] to access the elements of Vec. 288 289All the expected vector operations are also implemented: 290- v1 = v2 + v3 291- v1 = v2 - v3 292- v1 = v2 \* scale 293- v1 = scale \* v2 294- v1 = -v2 295- v1 += v2 and other augmenting operations 296- v1 == v2, v1 != v2 297- norm(v1) (euclidean norm) 298The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details. 299*/ 300template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> 301{ 302public: 303 typedef _Tp value_type; 304 enum { depth = Matx<_Tp, cn, 1>::depth, 305 channels = cn, 306 type = CV_MAKETYPE(depth, channels) 307 }; 308 309 //! default constructor 310 Vec(); 311 312 Vec(_Tp v0); //!< 1-element vector constructor 313 Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor 314 Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor 315 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor 316 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor 317 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor 318 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor 319 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor 320 Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor 321 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 322 explicit Vec(const _Tp* values); 323 324 Vec(const Vec<_Tp, cn>& v); 325 326 static Vec all(_Tp alpha); 327 328 //! per-element multiplication 329 Vec mul(const Vec<_Tp, cn>& v) const; 330 331 //! conjugation (makes sense for complex numbers and quaternions) 332 Vec conj() const; 333 334 /*! 335 cross product of the two 3D vectors. 336 337 For other dimensionalities the exception is raised 338 */ 339 Vec cross(const Vec& v) const; 340 //! conversion to another data type 341 template<typename T2> operator Vec<T2, cn>() const; 342 343 /*! element access */ 344 const _Tp& operator [](int i) const; 345 _Tp& operator[](int i); 346 const _Tp& operator ()(int i) const; 347 _Tp& operator ()(int i); 348 349 Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp); 350 Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp); 351 template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp); 352}; 353 354/** @name Shorter aliases for the most popular specializations of Vec<T,n> 355 @{ 356*/ 357typedef Vec<uchar, 2> Vec2b; 358typedef Vec<uchar, 3> Vec3b; 359typedef Vec<uchar, 4> Vec4b; 360 361typedef Vec<short, 2> Vec2s; 362typedef Vec<short, 3> Vec3s; 363typedef Vec<short, 4> Vec4s; 364 365typedef Vec<ushort, 2> Vec2w; 366typedef Vec<ushort, 3> Vec3w; 367typedef Vec<ushort, 4> Vec4w; 368 369typedef Vec<int, 2> Vec2i; 370typedef Vec<int, 3> Vec3i; 371typedef Vec<int, 4> Vec4i; 372typedef Vec<int, 6> Vec6i; 373typedef Vec<int, 8> Vec8i; 374 375typedef Vec<float, 2> Vec2f; 376typedef Vec<float, 3> Vec3f; 377typedef Vec<float, 4> Vec4f; 378typedef Vec<float, 6> Vec6f; 379 380typedef Vec<double, 2> Vec2d; 381typedef Vec<double, 3> Vec3d; 382typedef Vec<double, 4> Vec4d; 383typedef Vec<double, 6> Vec6d; 384/** @} */ 385 386/*! 387 traits 388*/ 389template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> > 390{ 391public: 392 typedef Vec<_Tp, cn> value_type; 393 typedef Vec<typename DataType<_Tp>::work_type, cn> work_type; 394 typedef _Tp channel_type; 395 typedef value_type vec_type; 396 397 enum { generic_type = 0, 398 depth = DataType<channel_type>::depth, 399 channels = cn, 400 fmt = DataType<channel_type>::fmt + ((channels - 1) << 8), 401 type = CV_MAKETYPE(depth, channels) 402 }; 403}; 404 405/** @brief Comma-separated Vec Initializer 406*/ 407template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> 408{ 409public: 410 VecCommaInitializer(Vec<_Tp, m>* _vec); 411 template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val); 412 Vec<_Tp, m> operator *() const; 413}; 414 415template<typename _Tp, int cn> static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v); 416 417//! @} core_basic 418 419//! @cond IGNORED 420 421///////////////////////////////////// helper classes ///////////////////////////////////// 422namespace internal 423{ 424 425template<typename _Tp, int m> struct Matx_DetOp 426{ 427 double operator ()(const Matx<_Tp, m, m>& a) const 428 { 429 Matx<_Tp, m, m> temp = a; 430 double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); 431 if( p == 0 ) 432 return p; 433 for( int i = 0; i < m; i++ ) 434 p *= temp(i, i); 435 return 1./p; 436 } 437}; 438 439template<typename _Tp> struct Matx_DetOp<_Tp, 1> 440{ 441 double operator ()(const Matx<_Tp, 1, 1>& a) const 442 { 443 return a(0,0); 444 } 445}; 446 447template<typename _Tp> struct Matx_DetOp<_Tp, 2> 448{ 449 double operator ()(const Matx<_Tp, 2, 2>& a) const 450 { 451 return a(0,0)*a(1,1) - a(0,1)*a(1,0); 452 } 453}; 454 455template<typename _Tp> struct Matx_DetOp<_Tp, 3> 456{ 457 double operator ()(const Matx<_Tp, 3, 3>& a) const 458 { 459 return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - 460 a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + 461 a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); 462 } 463}; 464 465template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) 466{ 467 return Vec<_Tp, 2>(v[0], -v[1]); 468} 469 470template<typename _Tp> Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v) 471{ 472 return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); 473} 474 475} // internal 476 477 478 479////////////////////////////////// Matx Implementation /////////////////////////////////// 480 481template<typename _Tp, int m, int n> inline 482Matx<_Tp, m, n>::Matx() 483{ 484 for(int i = 0; i < channels; i++) val[i] = _Tp(0); 485} 486 487template<typename _Tp, int m, int n> inline 488Matx<_Tp, m, n>::Matx(_Tp v0) 489{ 490 val[0] = v0; 491 for(int i = 1; i < channels; i++) val[i] = _Tp(0); 492} 493 494template<typename _Tp, int m, int n> inline 495Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) 496{ 497 CV_StaticAssert(channels >= 2, "Matx should have at least 2 elaments."); 498 val[0] = v0; val[1] = v1; 499 for(int i = 2; i < channels; i++) val[i] = _Tp(0); 500} 501 502template<typename _Tp, int m, int n> inline 503Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) 504{ 505 CV_StaticAssert(channels >= 3, "Matx should have at least 3 elaments."); 506 val[0] = v0; val[1] = v1; val[2] = v2; 507 for(int i = 3; i < channels; i++) val[i] = _Tp(0); 508} 509 510template<typename _Tp, int m, int n> inline 511Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 512{ 513 CV_StaticAssert(channels >= 4, "Matx should have at least 4 elaments."); 514 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 515 for(int i = 4; i < channels; i++) val[i] = _Tp(0); 516} 517 518template<typename _Tp, int m, int n> inline 519Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 520{ 521 CV_StaticAssert(channels >= 5, "Matx should have at least 5 elaments."); 522 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; 523 for(int i = 5; i < channels; i++) val[i] = _Tp(0); 524} 525 526template<typename _Tp, int m, int n> inline 527Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) 528{ 529 CV_StaticAssert(channels >= 6, "Matx should have at least 6 elaments."); 530 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 531 val[4] = v4; val[5] = v5; 532 for(int i = 6; i < channels; i++) val[i] = _Tp(0); 533} 534 535template<typename _Tp, int m, int n> inline 536Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) 537{ 538 CV_StaticAssert(channels >= 7, "Matx should have at least 7 elaments."); 539 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 540 val[4] = v4; val[5] = v5; val[6] = v6; 541 for(int i = 7; i < channels; i++) val[i] = _Tp(0); 542} 543 544template<typename _Tp, int m, int n> inline 545Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) 546{ 547 CV_StaticAssert(channels >= 8, "Matx should have at least 8 elaments."); 548 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 549 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 550 for(int i = 8; i < channels; i++) val[i] = _Tp(0); 551} 552 553template<typename _Tp, int m, int n> inline 554Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) 555{ 556 CV_StaticAssert(channels >= 9, "Matx should have at least 9 elaments."); 557 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 558 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 559 val[8] = v8; 560 for(int i = 9; i < channels; i++) val[i] = _Tp(0); 561} 562 563template<typename _Tp, int m, int n> inline 564Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) 565{ 566 CV_StaticAssert(channels >= 10, "Matx should have at least 10 elaments."); 567 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 568 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 569 val[8] = v8; val[9] = v9; 570 for(int i = 10; i < channels; i++) val[i] = _Tp(0); 571} 572 573 574template<typename _Tp, int m, int n> inline 575Matx<_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) 576{ 577 CV_StaticAssert(channels == 12, "Matx should have at least 12 elaments."); 578 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 579 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 580 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; 581} 582 583template<typename _Tp, int m, int n> inline 584Matx<_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) 585{ 586 CV_StaticAssert(channels == 16, "Matx should have at least 16 elaments."); 587 val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 588 val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; 589 val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; 590 val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; 591} 592 593template<typename _Tp, int m, int n> inline 594Matx<_Tp, m, n>::Matx(const _Tp* values) 595{ 596 for( int i = 0; i < channels; i++ ) val[i] = values[i]; 597} 598 599template<typename _Tp, int m, int n> inline 600Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) 601{ 602 Matx<_Tp, m, n> M; 603 for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; 604 return M; 605} 606 607template<typename _Tp, int m, int n> inline 608Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() 609{ 610 return all(0); 611} 612 613template<typename _Tp, int m, int n> inline 614Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() 615{ 616 return all(1); 617} 618 619template<typename _Tp, int m, int n> inline 620Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() 621{ 622 Matx<_Tp,m,n> M; 623 for(int i = 0; i < shortdim; i++) 624 M(i,i) = 1; 625 return M; 626} 627 628template<typename _Tp, int m, int n> inline 629_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const 630{ 631 _Tp s = 0; 632 for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i]; 633 return s; 634} 635 636template<typename _Tp, int m, int n> inline 637double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const 638{ 639 double s = 0; 640 for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i]; 641 return s; 642} 643 644template<typename _Tp, int m, int n> inline 645Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) 646{ 647 Matx<_Tp,m,n> M; 648 for(int i = 0; i < shortdim; i++) 649 M(i,i) = d(i, 0); 650 return M; 651} 652 653template<typename _Tp, int m, int n> template<typename T2> 654inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const 655{ 656 Matx<T2, m, n> M; 657 for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]); 658 return M; 659} 660 661template<typename _Tp, int m, int n> template<int m1, int n1> inline 662Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const 663{ 664 CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements"); 665 return (const Matx<_Tp, m1, n1>&)*this; 666} 667 668template<typename _Tp, int m, int n> 669template<int m1, int n1> inline 670Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const 671{ 672 CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n); 673 Matx<_Tp, m1, n1> s; 674 for( int di = 0; di < m1; di++ ) 675 for( int dj = 0; dj < n1; dj++ ) 676 s(di, dj) = (*this)(i+di, j+dj); 677 return s; 678} 679 680template<typename _Tp, int m, int n> inline 681Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const 682{ 683 CV_DbgAssert((unsigned)i < (unsigned)m); 684 return Matx<_Tp, 1, n>(&val[i*n]); 685} 686 687template<typename _Tp, int m, int n> inline 688Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const 689{ 690 CV_DbgAssert((unsigned)j < (unsigned)n); 691 Matx<_Tp, m, 1> v; 692 for( int i = 0; i < m; i++ ) 693 v.val[i] = val[i*n + j]; 694 return v; 695} 696 697template<typename _Tp, int m, int n> inline 698typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const 699{ 700 diag_type d; 701 for( int i = 0; i < shortdim; i++ ) 702 d.val[i] = val[i*n + i]; 703 return d; 704} 705 706template<typename _Tp, int m, int n> inline 707const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const 708{ 709 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); 710 return this->val[i*n + j]; 711} 712 713template<typename _Tp, int m, int n> inline 714_Tp& Matx<_Tp, m, n>::operator ()(int i, int j) 715{ 716 CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); 717 return val[i*n + j]; 718} 719 720template<typename _Tp, int m, int n> inline 721const _Tp& Matx<_Tp, m, n>::operator ()(int i) const 722{ 723 CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); 724 CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); 725 return val[i]; 726} 727 728template<typename _Tp, int m, int n> inline 729_Tp& Matx<_Tp, m, n>::operator ()(int i) 730{ 731 CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); 732 CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); 733 return val[i]; 734} 735 736template<typename _Tp, int m, int n> inline 737Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) 738{ 739 for( int i = 0; i < channels; i++ ) 740 val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); 741} 742 743template<typename _Tp, int m, int n> inline 744Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) 745{ 746 for( int i = 0; i < channels; i++ ) 747 val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); 748} 749 750template<typename _Tp, int m, int n> template<typename _T2> inline 751Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) 752{ 753 for( int i = 0; i < channels; i++ ) 754 val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 755} 756 757template<typename _Tp, int m, int n> inline 758Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) 759{ 760 for( int i = 0; i < channels; i++ ) 761 val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); 762} 763 764template<typename _Tp, int m, int n> inline 765Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp) 766{ 767 for( int i = 0; i < channels; i++ ) 768 val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]); 769} 770 771template<typename _Tp, int m, int n> template<int l> inline 772Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) 773{ 774 for( int i = 0; i < m; i++ ) 775 for( int j = 0; j < n; j++ ) 776 { 777 _Tp s = 0; 778 for( int k = 0; k < l; k++ ) 779 s += a(i, k) * b(k, j); 780 val[i*n + j] = s; 781 } 782} 783 784template<typename _Tp, int m, int n> inline 785Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) 786{ 787 for( int i = 0; i < m; i++ ) 788 for( int j = 0; j < n; j++ ) 789 val[i*n + j] = a(j, i); 790} 791 792template<typename _Tp, int m, int n> inline 793Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const 794{ 795 return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); 796} 797 798template<typename _Tp, int m, int n> inline 799Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const 800{ 801 return Matx<_Tp, m, n>(*this, a, Matx_DivOp()); 802} 803 804template<typename _Tp, int m, int n> inline 805Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const 806{ 807 return Matx<_Tp, n, m>(*this, Matx_TOp()); 808} 809 810template<typename _Tp, int m, int n> inline 811Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const 812{ 813 Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method); 814 return (Vec<_Tp, n>&)(x); 815} 816 817template<typename _Tp, int m> static inline 818double determinant(const Matx<_Tp, m, m>& a) 819{ 820 return cv::internal::Matx_DetOp<_Tp, m>()(a); 821} 822 823template<typename _Tp, int m, int n> static inline 824double trace(const Matx<_Tp, m, n>& a) 825{ 826 _Tp s = 0; 827 for( int i = 0; i < std::min(m, n); i++ ) 828 s += a(i,i); 829 return s; 830} 831 832template<typename _Tp, int m, int n> static inline 833double norm(const Matx<_Tp, m, n>& M) 834{ 835 return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); 836} 837 838template<typename _Tp, int m, int n> static inline 839double norm(const Matx<_Tp, m, n>& M, int normType) 840{ 841 return normType == NORM_INF ? (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n) : 842 normType == NORM_L1 ? (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n) : 843 std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); 844} 845 846 847 848//////////////////////////////// matx comma initializer ////////////////////////////////// 849 850template<typename _Tp, typename _T2, int m, int n> static inline 851MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) 852{ 853 MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); 854 return (commaInitializer, val); 855} 856 857template<typename _Tp, int m, int n> inline 858MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) 859 : dst(_mtx), idx(0) 860{} 861 862template<typename _Tp, int m, int n> template<typename _T2> inline 863MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) 864{ 865 CV_DbgAssert( idx < m*n ); 866 dst->val[idx++] = saturate_cast<_Tp>(value); 867 return *this; 868} 869 870template<typename _Tp, int m, int n> inline 871Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const 872{ 873 CV_DbgAssert( idx == n*m ); 874 return *dst; 875} 876 877 878 879/////////////////////////////////// Vec Implementation /////////////////////////////////// 880 881template<typename _Tp, int cn> inline 882Vec<_Tp, cn>::Vec() {} 883 884template<typename _Tp, int cn> inline 885Vec<_Tp, cn>::Vec(_Tp v0) 886 : Matx<_Tp, cn, 1>(v0) {} 887 888template<typename _Tp, int cn> inline 889Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) 890 : Matx<_Tp, cn, 1>(v0, v1) {} 891 892template<typename _Tp, int cn> inline 893Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) 894 : Matx<_Tp, cn, 1>(v0, v1, v2) {} 895 896template<typename _Tp, int cn> inline 897Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 898 : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} 899 900template<typename _Tp, int cn> inline 901Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 902 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} 903 904template<typename _Tp, int cn> inline 905Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) 906 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {} 907 908template<typename _Tp, int cn> inline 909Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) 910 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {} 911 912template<typename _Tp, int cn> inline 913Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) 914 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {} 915 916template<typename _Tp, int cn> inline 917Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) 918 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {} 919 920template<typename _Tp, int cn> inline 921Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) 922 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {} 923 924template<typename _Tp, int cn> inline 925Vec<_Tp, cn>::Vec(const _Tp* values) 926 : Matx<_Tp, cn, 1>(values) {} 927 928template<typename _Tp, int cn> inline 929Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) 930 : Matx<_Tp, cn, 1>(m.val) {} 931 932template<typename _Tp, int cn> inline 933Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) 934 : Matx<_Tp, cn, 1>(a, b, op) {} 935 936template<typename _Tp, int cn> inline 937Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) 938 : Matx<_Tp, cn, 1>(a, b, op) {} 939 940template<typename _Tp, int cn> template<typename _T2> inline 941Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) 942 : Matx<_Tp, cn, 1>(a, alpha, op) {} 943 944template<typename _Tp, int cn> inline 945Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) 946{ 947 Vec v; 948 for( int i = 0; i < cn; i++ ) v.val[i] = alpha; 949 return v; 950} 951 952template<typename _Tp, int cn> inline 953Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const 954{ 955 Vec<_Tp, cn> w; 956 for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); 957 return w; 958} 959 960template<> inline 961Vec<float, 2> Vec<float, 2>::conj() const 962{ 963 return cv::internal::conjugate(*this); 964} 965 966template<> inline 967Vec<double, 2> Vec<double, 2>::conj() const 968{ 969 return cv::internal::conjugate(*this); 970} 971 972template<> inline 973Vec<float, 4> Vec<float, 4>::conj() const 974{ 975 return cv::internal::conjugate(*this); 976} 977 978template<> inline 979Vec<double, 4> Vec<double, 4>::conj() const 980{ 981 return cv::internal::conjugate(*this); 982} 983 984template<typename _Tp, int cn> inline 985Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const 986{ 987 CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined"); 988 return Vec<_Tp, cn>(); 989} 990 991template<> inline 992Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const 993{ 994 return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1], 995 val[2]*v.val[0] - val[0]*v.val[2], 996 val[0]*v.val[1] - val[1]*v.val[0]); 997} 998 999template<> inline 1000Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const 1001{ 1002 return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1], 1003 val[2]*v.val[0] - val[0]*v.val[2], 1004 val[0]*v.val[1] - val[1]*v.val[0]); 1005} 1006 1007template<typename _Tp, int cn> template<typename T2> inline 1008Vec<_Tp, cn>::operator Vec<T2, cn>() const 1009{ 1010 Vec<T2, cn> v; 1011 for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]); 1012 return v; 1013} 1014 1015template<typename _Tp, int cn> inline 1016const _Tp& Vec<_Tp, cn>::operator [](int i) const 1017{ 1018 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1019 return this->val[i]; 1020} 1021 1022template<typename _Tp, int cn> inline 1023_Tp& Vec<_Tp, cn>::operator [](int i) 1024{ 1025 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1026 return this->val[i]; 1027} 1028 1029template<typename _Tp, int cn> inline 1030const _Tp& Vec<_Tp, cn>::operator ()(int i) const 1031{ 1032 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1033 return this->val[i]; 1034} 1035 1036template<typename _Tp, int cn> inline 1037_Tp& Vec<_Tp, cn>::operator ()(int i) 1038{ 1039 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1040 return this->val[i]; 1041} 1042 1043template<typename _Tp, int cn> inline 1044Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) 1045{ 1046 double nv = norm(v); 1047 return v * (nv ? 1./nv : 0.); 1048} 1049 1050 1051 1052//////////////////////////////// matx comma initializer ////////////////////////////////// 1053 1054 1055template<typename _Tp, typename _T2, int cn> static inline 1056VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) 1057{ 1058 VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); 1059 return (commaInitializer, val); 1060} 1061 1062template<typename _Tp, int cn> inline 1063VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) 1064 : MatxCommaInitializer<_Tp, cn, 1>(_vec) 1065{} 1066 1067template<typename _Tp, int cn> template<typename _T2> inline 1068VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) 1069{ 1070 CV_DbgAssert( this->idx < cn ); 1071 this->dst->val[this->idx++] = saturate_cast<_Tp>(value); 1072 return *this; 1073} 1074 1075template<typename _Tp, int cn> inline 1076Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const 1077{ 1078 CV_DbgAssert( this->idx == cn ); 1079 return *this->dst; 1080} 1081 1082//! @endcond 1083 1084///////////////////////////// Matx out-of-class operators //////////////////////////////// 1085 1086//! @relates cv::Matx 1087//! @{ 1088 1089template<typename _Tp1, typename _Tp2, int m, int n> static inline 1090Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) 1091{ 1092 for( int i = 0; i < m*n; i++ ) 1093 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); 1094 return a; 1095} 1096 1097template<typename _Tp1, typename _Tp2, int m, int n> static inline 1098Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) 1099{ 1100 for( int i = 0; i < m*n; i++ ) 1101 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); 1102 return a; 1103} 1104 1105template<typename _Tp, int m, int n> static inline 1106Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 1107{ 1108 return Matx<_Tp, m, n>(a, b, Matx_AddOp()); 1109} 1110 1111template<typename _Tp, int m, int n> static inline 1112Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 1113{ 1114 return Matx<_Tp, m, n>(a, b, Matx_SubOp()); 1115} 1116 1117template<typename _Tp, int m, int n> static inline 1118Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) 1119{ 1120 for( int i = 0; i < m*n; i++ ) 1121 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 1122 return a; 1123} 1124 1125template<typename _Tp, int m, int n> static inline 1126Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) 1127{ 1128 for( int i = 0; i < m*n; i++ ) 1129 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 1130 return a; 1131} 1132 1133template<typename _Tp, int m, int n> static inline 1134Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) 1135{ 1136 for( int i = 0; i < m*n; i++ ) 1137 a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); 1138 return a; 1139} 1140 1141template<typename _Tp, int m, int n> static inline 1142Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) 1143{ 1144 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1145} 1146 1147template<typename _Tp, int m, int n> static inline 1148Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) 1149{ 1150 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1151} 1152 1153template<typename _Tp, int m, int n> static inline 1154Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) 1155{ 1156 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1157} 1158 1159template<typename _Tp, int m, int n> static inline 1160Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) 1161{ 1162 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1163} 1164 1165template<typename _Tp, int m, int n> static inline 1166Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) 1167{ 1168 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1169} 1170 1171template<typename _Tp, int m, int n> static inline 1172Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) 1173{ 1174 return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); 1175} 1176 1177template<typename _Tp, int m, int n> static inline 1178Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) 1179{ 1180 return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); 1181} 1182 1183template<typename _Tp, int m, int n, int l> static inline 1184Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) 1185{ 1186 return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); 1187} 1188 1189template<typename _Tp, int m, int n> static inline 1190Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) 1191{ 1192 Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); 1193 return (const Vec<_Tp, m>&)(c); 1194} 1195 1196template<typename _Tp, int m, int n> static inline 1197bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 1198{ 1199 for( int i = 0; i < m*n; i++ ) 1200 if( a.val[i] != b.val[i] ) return false; 1201 return true; 1202} 1203 1204template<typename _Tp, int m, int n> static inline 1205bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) 1206{ 1207 return !(a == b); 1208} 1209 1210//! @} 1211 1212////////////////////////////// Vec out-of-class operators //////////////////////////////// 1213 1214//! @relates cv::Vec 1215//! @{ 1216 1217template<typename _Tp1, typename _Tp2, int cn> static inline 1218Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 1219{ 1220 for( int i = 0; i < cn; i++ ) 1221 a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); 1222 return a; 1223} 1224 1225template<typename _Tp1, typename _Tp2, int cn> static inline 1226Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) 1227{ 1228 for( int i = 0; i < cn; i++ ) 1229 a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); 1230 return a; 1231} 1232 1233template<typename _Tp, int cn> static inline 1234Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 1235{ 1236 return Vec<_Tp, cn>(a, b, Matx_AddOp()); 1237} 1238 1239template<typename _Tp, int cn> static inline 1240Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) 1241{ 1242 return Vec<_Tp, cn>(a, b, Matx_SubOp()); 1243} 1244 1245template<typename _Tp, int cn> static inline 1246Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) 1247{ 1248 for( int i = 0; i < cn; i++ ) 1249 a[i] = saturate_cast<_Tp>(a[i]*alpha); 1250 return a; 1251} 1252 1253template<typename _Tp, int cn> static inline 1254Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) 1255{ 1256 for( int i = 0; i < cn; i++ ) 1257 a[i] = saturate_cast<_Tp>(a[i]*alpha); 1258 return a; 1259} 1260 1261template<typename _Tp, int cn> static inline 1262Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) 1263{ 1264 for( int i = 0; i < cn; i++ ) 1265 a[i] = saturate_cast<_Tp>(a[i]*alpha); 1266 return a; 1267} 1268 1269template<typename _Tp, int cn> static inline 1270Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) 1271{ 1272 double ialpha = 1./alpha; 1273 for( int i = 0; i < cn; i++ ) 1274 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 1275 return a; 1276} 1277 1278template<typename _Tp, int cn> static inline 1279Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) 1280{ 1281 float ialpha = 1.f/alpha; 1282 for( int i = 0; i < cn; i++ ) 1283 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 1284 return a; 1285} 1286 1287template<typename _Tp, int cn> static inline 1288Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) 1289{ 1290 double ialpha = 1./alpha; 1291 for( int i = 0; i < cn; i++ ) 1292 a[i] = saturate_cast<_Tp>(a[i]*ialpha); 1293 return a; 1294} 1295 1296template<typename _Tp, int cn> static inline 1297Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) 1298{ 1299 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1300} 1301 1302template<typename _Tp, int cn> static inline 1303Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) 1304{ 1305 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1306} 1307 1308template<typename _Tp, int cn> static inline 1309Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) 1310{ 1311 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1312} 1313 1314template<typename _Tp, int cn> static inline 1315Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) 1316{ 1317 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1318} 1319 1320template<typename _Tp, int cn> static inline 1321Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) 1322{ 1323 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1324} 1325 1326template<typename _Tp, int cn> static inline 1327Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) 1328{ 1329 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1330} 1331 1332template<typename _Tp, int cn> static inline 1333Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) 1334{ 1335 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 1336} 1337 1338template<typename _Tp, int cn> static inline 1339Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) 1340{ 1341 return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); 1342} 1343 1344template<typename _Tp, int cn> static inline 1345Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) 1346{ 1347 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 1348} 1349 1350template<typename _Tp, int cn> static inline 1351Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) 1352{ 1353 Vec<_Tp,cn> t; 1354 for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); 1355 return t; 1356} 1357 1358template<typename _Tp> inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) 1359{ 1360 return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), 1361 saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), 1362 saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), 1363 saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); 1364} 1365 1366template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) 1367{ 1368 v1 = v1 * v2; 1369 return v1; 1370} 1371 1372//! @} 1373 1374} // cv 1375 1376#endif // __OPENCV_CORE_MATX_HPP__ 1377