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 55 namespace cv 56 { 57 58 //! @addtogroup core_basic 59 //! @{ 60 61 ////////////////////////////// Small Matrix /////////////////////////// 62 63 //! @cond IGNORED 64 struct CV_EXPORTS Matx_AddOp {}; 65 struct CV_EXPORTS Matx_SubOp {}; 66 struct CV_EXPORTS Matx_ScaleOp {}; 67 struct CV_EXPORTS Matx_MulOp {}; 68 struct CV_EXPORTS Matx_DivOp {}; 69 struct CV_EXPORTS Matx_MatMulOp {}; 70 struct CV_EXPORTS Matx_TOp {}; 71 //! @endcond 72 73 /** @brief Template class for small matrices whose type and size are known at compilation time 74 75 If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the 76 M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are 77 available. To do an operation on Matx that is not implemented, you can easily convert the matrix to 78 Mat 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 */ 86 template<typename _Tp, int m, int n> class Matx 87 { 88 public: 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 190 typedef Matx<float, 1, 2> Matx12f; 191 typedef Matx<double, 1, 2> Matx12d; 192 typedef Matx<float, 1, 3> Matx13f; 193 typedef Matx<double, 1, 3> Matx13d; 194 typedef Matx<float, 1, 4> Matx14f; 195 typedef Matx<double, 1, 4> Matx14d; 196 typedef Matx<float, 1, 6> Matx16f; 197 typedef Matx<double, 1, 6> Matx16d; 198 199 typedef Matx<float, 2, 1> Matx21f; 200 typedef Matx<double, 2, 1> Matx21d; 201 typedef Matx<float, 3, 1> Matx31f; 202 typedef Matx<double, 3, 1> Matx31d; 203 typedef Matx<float, 4, 1> Matx41f; 204 typedef Matx<double, 4, 1> Matx41d; 205 typedef Matx<float, 6, 1> Matx61f; 206 typedef Matx<double, 6, 1> Matx61d; 207 208 typedef Matx<float, 2, 2> Matx22f; 209 typedef Matx<double, 2, 2> Matx22d; 210 typedef Matx<float, 2, 3> Matx23f; 211 typedef Matx<double, 2, 3> Matx23d; 212 typedef Matx<float, 3, 2> Matx32f; 213 typedef Matx<double, 3, 2> Matx32d; 214 215 typedef Matx<float, 3, 3> Matx33f; 216 typedef Matx<double, 3, 3> Matx33d; 217 218 typedef Matx<float, 3, 4> Matx34f; 219 typedef Matx<double, 3, 4> Matx34d; 220 typedef Matx<float, 4, 3> Matx43f; 221 typedef Matx<double, 4, 3> Matx43d; 222 223 typedef Matx<float, 4, 4> Matx44f; 224 typedef Matx<double, 4, 4> Matx44d; 225 typedef Matx<float, 6, 6> Matx66f; 226 typedef Matx<double, 6, 6> Matx66d; 227 228 /*! 229 traits 230 */ 231 template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> > 232 { 233 public: 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 */ 249 template<typename _Tp, int m, int n> class MatxCommaInitializer 250 { 251 public: 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 */ 263 template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a); 264 template<typename _Tp, int m, int n> static double trace(const Matx<_Tp, m, n>& a); 265 template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M); 266 template<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 274 This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you 275 can perform basic arithmetical operations, access individual elements using [] operator etc. The 276 vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which 277 elements are dynamically allocated in the heap. 278 279 The template takes 2 parameters: 280 @tparam _Tp element type 281 @tparam cn the number of elements 282 283 In addition to the universal notation like Vec<float, 3>, you can use shorter aliases 284 for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>. 285 286 It is possible to convert Vec\<T,2\> to/from Point_, Vec\<T,3\> to/from Point3_ , and Vec\<T,4\> 287 to CvScalar or Scalar_. Use operator[] to access the elements of Vec. 288 289 All 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) 298 The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details. 299 */ 300 template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> 301 { 302 public: 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 */ 357 typedef Vec<uchar, 2> Vec2b; 358 typedef Vec<uchar, 3> Vec3b; 359 typedef Vec<uchar, 4> Vec4b; 360 361 typedef Vec<short, 2> Vec2s; 362 typedef Vec<short, 3> Vec3s; 363 typedef Vec<short, 4> Vec4s; 364 365 typedef Vec<ushort, 2> Vec2w; 366 typedef Vec<ushort, 3> Vec3w; 367 typedef Vec<ushort, 4> Vec4w; 368 369 typedef Vec<int, 2> Vec2i; 370 typedef Vec<int, 3> Vec3i; 371 typedef Vec<int, 4> Vec4i; 372 typedef Vec<int, 6> Vec6i; 373 typedef Vec<int, 8> Vec8i; 374 375 typedef Vec<float, 2> Vec2f; 376 typedef Vec<float, 3> Vec3f; 377 typedef Vec<float, 4> Vec4f; 378 typedef Vec<float, 6> Vec6f; 379 380 typedef Vec<double, 2> Vec2d; 381 typedef Vec<double, 3> Vec3d; 382 typedef Vec<double, 4> Vec4d; 383 typedef Vec<double, 6> Vec6d; 384 /** @} */ 385 386 /*! 387 traits 388 */ 389 template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> > 390 { 391 public: 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 */ 407 template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> 408 { 409 public: 410 VecCommaInitializer(Vec<_Tp, m>* _vec); 411 template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val); 412 Vec<_Tp, m> operator *() const; 413 }; 414 415 template<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 ///////////////////////////////////// 422 namespace internal 423 { 424 425 template<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 439 template<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 447 template<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 455 template<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 465 template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) 466 { 467 return Vec<_Tp, 2>(v[0], -v[1]); 468 } 469 470 template<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 481 template<typename _Tp, int m, int n> inline 482 Matx<_Tp, m, n>::Matx() 483 { 484 for(int i = 0; i < channels; i++) val[i] = _Tp(0); 485 } 486 487 template<typename _Tp, int m, int n> inline 488 Matx<_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 494 template<typename _Tp, int m, int n> inline 495 Matx<_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 502 template<typename _Tp, int m, int n> inline 503 Matx<_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 510 template<typename _Tp, int m, int n> inline 511 Matx<_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 518 template<typename _Tp, int m, int n> inline 519 Matx<_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 526 template<typename _Tp, int m, int n> inline 527 Matx<_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 535 template<typename _Tp, int m, int n> inline 536 Matx<_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 544 template<typename _Tp, int m, int n> inline 545 Matx<_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 553 template<typename _Tp, int m, int n> inline 554 Matx<_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 563 template<typename _Tp, int m, int n> inline 564 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) 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 574 template<typename _Tp, int m, int n> inline 575 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) 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 583 template<typename _Tp, int m, int n> inline 584 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) 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 593 template<typename _Tp, int m, int n> inline 594 Matx<_Tp, m, n>::Matx(const _Tp* values) 595 { 596 for( int i = 0; i < channels; i++ ) val[i] = values[i]; 597 } 598 599 template<typename _Tp, int m, int n> inline 600 Matx<_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 607 template<typename _Tp, int m, int n> inline 608 Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() 609 { 610 return all(0); 611 } 612 613 template<typename _Tp, int m, int n> inline 614 Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() 615 { 616 return all(1); 617 } 618 619 template<typename _Tp, int m, int n> inline 620 Matx<_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 628 template<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 636 template<typename _Tp, int m, int n> inline 637 double 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 644 template<typename _Tp, int m, int n> inline 645 Matx<_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 653 template<typename _Tp, int m, int n> template<typename T2> 654 inline 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 661 template<typename _Tp, int m, int n> template<int m1, int n1> inline 662 Matx<_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 668 template<typename _Tp, int m, int n> 669 template<int m1, int n1> inline 670 Matx<_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 680 template<typename _Tp, int m, int n> inline 681 Matx<_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 687 template<typename _Tp, int m, int n> inline 688 Matx<_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 697 template<typename _Tp, int m, int n> inline 698 typename 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 706 template<typename _Tp, int m, int n> inline 707 const _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 713 template<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 720 template<typename _Tp, int m, int n> inline 721 const _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 728 template<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 736 template<typename _Tp, int m, int n> inline 737 Matx<_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 743 template<typename _Tp, int m, int n> inline 744 Matx<_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 750 template<typename _Tp, int m, int n> template<typename _T2> inline 751 Matx<_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 757 template<typename _Tp, int m, int n> inline 758 Matx<_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 764 template<typename _Tp, int m, int n> inline 765 Matx<_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 771 template<typename _Tp, int m, int n> template<int l> inline 772 Matx<_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 784 template<typename _Tp, int m, int n> inline 785 Matx<_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 792 template<typename _Tp, int m, int n> inline 793 Matx<_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 798 template<typename _Tp, int m, int n> inline 799 Matx<_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 804 template<typename _Tp, int m, int n> inline 805 Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const 806 { 807 return Matx<_Tp, n, m>(*this, Matx_TOp()); 808 } 809 810 template<typename _Tp, int m, int n> inline 811 Vec<_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 817 template<typename _Tp, int m> static inline 818 double determinant(const Matx<_Tp, m, m>& a) 819 { 820 return cv::internal::Matx_DetOp<_Tp, m>()(a); 821 } 822 823 template<typename _Tp, int m, int n> static inline 824 double 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 832 template<typename _Tp, int m, int n> static inline 833 double norm(const Matx<_Tp, m, n>& M) 834 { 835 return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); 836 } 837 838 template<typename _Tp, int m, int n> static inline 839 double 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 850 template<typename _Tp, typename _T2, int m, int n> static inline 851 MatxCommaInitializer<_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 857 template<typename _Tp, int m, int n> inline 858 MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) 859 : dst(_mtx), idx(0) 860 {} 861 862 template<typename _Tp, int m, int n> template<typename _T2> inline 863 MatxCommaInitializer<_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 870 template<typename _Tp, int m, int n> inline 871 Matx<_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 881 template<typename _Tp, int cn> inline 882 Vec<_Tp, cn>::Vec() {} 883 884 template<typename _Tp, int cn> inline 885 Vec<_Tp, cn>::Vec(_Tp v0) 886 : Matx<_Tp, cn, 1>(v0) {} 887 888 template<typename _Tp, int cn> inline 889 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) 890 : Matx<_Tp, cn, 1>(v0, v1) {} 891 892 template<typename _Tp, int cn> inline 893 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) 894 : Matx<_Tp, cn, 1>(v0, v1, v2) {} 895 896 template<typename _Tp, int cn> inline 897 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) 898 : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} 899 900 template<typename _Tp, int cn> inline 901 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) 902 : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} 903 904 template<typename _Tp, int cn> inline 905 Vec<_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 908 template<typename _Tp, int cn> inline 909 Vec<_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 912 template<typename _Tp, int cn> inline 913 Vec<_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 916 template<typename _Tp, int cn> inline 917 Vec<_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 920 template<typename _Tp, int cn> inline 921 Vec<_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 924 template<typename _Tp, int cn> inline 925 Vec<_Tp, cn>::Vec(const _Tp* values) 926 : Matx<_Tp, cn, 1>(values) {} 927 928 template<typename _Tp, int cn> inline 929 Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) 930 : Matx<_Tp, cn, 1>(m.val) {} 931 932 template<typename _Tp, int cn> inline 933 Vec<_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 936 template<typename _Tp, int cn> inline 937 Vec<_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 940 template<typename _Tp, int cn> template<typename _T2> inline 941 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) 942 : Matx<_Tp, cn, 1>(a, alpha, op) {} 943 944 template<typename _Tp, int cn> inline 945 Vec<_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 952 template<typename _Tp, int cn> inline 953 Vec<_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 960 template<> inline 961 Vec<float, 2> Vec<float, 2>::conj() const 962 { 963 return cv::internal::conjugate(*this); 964 } 965 966 template<> inline 967 Vec<double, 2> Vec<double, 2>::conj() const 968 { 969 return cv::internal::conjugate(*this); 970 } 971 972 template<> inline 973 Vec<float, 4> Vec<float, 4>::conj() const 974 { 975 return cv::internal::conjugate(*this); 976 } 977 978 template<> inline 979 Vec<double, 4> Vec<double, 4>::conj() const 980 { 981 return cv::internal::conjugate(*this); 982 } 983 984 template<typename _Tp, int cn> inline 985 Vec<_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 991 template<> inline 992 Vec<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 999 template<> inline 1000 Vec<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 1007 template<typename _Tp, int cn> template<typename T2> inline 1008 Vec<_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 1015 template<typename _Tp, int cn> inline 1016 const _Tp& Vec<_Tp, cn>::operator [](int i) const 1017 { 1018 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1019 return this->val[i]; 1020 } 1021 1022 template<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 1029 template<typename _Tp, int cn> inline 1030 const _Tp& Vec<_Tp, cn>::operator ()(int i) const 1031 { 1032 CV_DbgAssert( (unsigned)i < (unsigned)cn ); 1033 return this->val[i]; 1034 } 1035 1036 template<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 1043 template<typename _Tp, int cn> inline 1044 Vec<_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 1055 template<typename _Tp, typename _T2, int cn> static inline 1056 VecCommaInitializer<_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 1062 template<typename _Tp, int cn> inline 1063 VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) 1064 : MatxCommaInitializer<_Tp, cn, 1>(_vec) 1065 {} 1066 1067 template<typename _Tp, int cn> template<typename _T2> inline 1068 VecCommaInitializer<_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 1075 template<typename _Tp, int cn> inline 1076 Vec<_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 1089 template<typename _Tp1, typename _Tp2, int m, int n> static inline 1090 Matx<_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 1097 template<typename _Tp1, typename _Tp2, int m, int n> static inline 1098 Matx<_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 1105 template<typename _Tp, int m, int n> static inline 1106 Matx<_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 1111 template<typename _Tp, int m, int n> static inline 1112 Matx<_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 1117 template<typename _Tp, int m, int n> static inline 1118 Matx<_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 1125 template<typename _Tp, int m, int n> static inline 1126 Matx<_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 1133 template<typename _Tp, int m, int n> static inline 1134 Matx<_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 1141 template<typename _Tp, int m, int n> static inline 1142 Matx<_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 1147 template<typename _Tp, int m, int n> static inline 1148 Matx<_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 1153 template<typename _Tp, int m, int n> static inline 1154 Matx<_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 1159 template<typename _Tp, int m, int n> static inline 1160 Matx<_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 1165 template<typename _Tp, int m, int n> static inline 1166 Matx<_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 1171 template<typename _Tp, int m, int n> static inline 1172 Matx<_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 1177 template<typename _Tp, int m, int n> static inline 1178 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) 1179 { 1180 return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); 1181 } 1182 1183 template<typename _Tp, int m, int n, int l> static inline 1184 Matx<_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 1189 template<typename _Tp, int m, int n> static inline 1190 Vec<_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 1196 template<typename _Tp, int m, int n> static inline 1197 bool 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 1204 template<typename _Tp, int m, int n> static inline 1205 bool 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 1217 template<typename _Tp1, typename _Tp2, int cn> static inline 1218 Vec<_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 1225 template<typename _Tp1, typename _Tp2, int cn> static inline 1226 Vec<_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 1233 template<typename _Tp, int cn> static inline 1234 Vec<_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 1239 template<typename _Tp, int cn> static inline 1240 Vec<_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 1245 template<typename _Tp, int cn> static inline 1246 Vec<_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 1253 template<typename _Tp, int cn> static inline 1254 Vec<_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 1261 template<typename _Tp, int cn> static inline 1262 Vec<_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 1269 template<typename _Tp, int cn> static inline 1270 Vec<_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 1278 template<typename _Tp, int cn> static inline 1279 Vec<_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 1287 template<typename _Tp, int cn> static inline 1288 Vec<_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 1296 template<typename _Tp, int cn> static inline 1297 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) 1298 { 1299 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1300 } 1301 1302 template<typename _Tp, int cn> static inline 1303 Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) 1304 { 1305 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1306 } 1307 1308 template<typename _Tp, int cn> static inline 1309 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) 1310 { 1311 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1312 } 1313 1314 template<typename _Tp, int cn> static inline 1315 Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) 1316 { 1317 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1318 } 1319 1320 template<typename _Tp, int cn> static inline 1321 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) 1322 { 1323 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1324 } 1325 1326 template<typename _Tp, int cn> static inline 1327 Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) 1328 { 1329 return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); 1330 } 1331 1332 template<typename _Tp, int cn> static inline 1333 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) 1334 { 1335 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 1336 } 1337 1338 template<typename _Tp, int cn> static inline 1339 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) 1340 { 1341 return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); 1342 } 1343 1344 template<typename _Tp, int cn> static inline 1345 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) 1346 { 1347 return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); 1348 } 1349 1350 template<typename _Tp, int cn> static inline 1351 Vec<_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 1358 template<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 1366 template<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