matx.inl.hpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #ifndef OPENCV_CORE_MATX_INL_HPP
  5. #define OPENCV_CORE_MATX_INL_HPP
  6. #ifndef __cplusplus
  7. # error matx.inl.hpp header must be compiled as C++
  8. #endif
  9. #include "opencv2/core/matx.hpp"
  10. namespace cv
  11. {
  12. //==============================================================================
  13. // Helpers
  14. namespace internal
  15. {
  16. template<typename _Tp, int m> struct Matx_DetOp
  17. {
  18. double operator ()(const Matx<_Tp, m, m>& a) const
  19. {
  20. Matx<_Tp, m, m> temp = a;
  21. double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0);
  22. if( p == 0 )
  23. return p;
  24. for( int i = 0; i < m; i++ )
  25. p *= temp(i, i);
  26. return p;
  27. }
  28. };
  29. template<typename _Tp> struct Matx_DetOp<_Tp, 1>
  30. {
  31. double operator ()(const Matx<_Tp, 1, 1>& a) const
  32. {
  33. return a(0,0);
  34. }
  35. };
  36. template<typename _Tp> struct Matx_DetOp<_Tp, 2>
  37. {
  38. double operator ()(const Matx<_Tp, 2, 2>& a) const
  39. {
  40. return a(0,0)*a(1,1) - a(0,1)*a(1,0);
  41. }
  42. };
  43. template<typename _Tp> struct Matx_DetOp<_Tp, 3>
  44. {
  45. double operator ()(const Matx<_Tp, 3, 3>& a) const
  46. {
  47. return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
  48. a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
  49. a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
  50. }
  51. };
  52. template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v)
  53. {
  54. return Vec<_Tp, 2>(v[0], -v[1]);
  55. }
  56. template<typename _Tp> Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v)
  57. {
  58. return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]);
  59. }
  60. } // internal::
  61. //==============================================================================
  62. // Matx
  63. template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> >
  64. {
  65. public:
  66. typedef Matx<_Tp, m, n> value_type;
  67. typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type;
  68. typedef _Tp channel_type;
  69. typedef value_type vec_type;
  70. enum { generic_type = 0,
  71. channels = m * n,
  72. fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
  73. #ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
  74. ,depth = DataType<channel_type>::depth
  75. ,type = CV_MAKETYPE(depth, channels)
  76. #endif
  77. };
  78. };
  79. namespace traits {
  80. template<typename _Tp, int m, int n>
  81. struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; };
  82. template<typename _Tp, int m, int n>
  83. struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; };
  84. } // namespace
  85. //! @brief Comma-separated Matrix Initializer
  86. template<typename _Tp, int m, int n> class MatxCommaInitializer
  87. {
  88. public:
  89. MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
  90. template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
  91. Matx<_Tp, m, n> operator *() const;
  92. Matx<_Tp, m, n>* dst;
  93. int idx;
  94. };
  95. template<typename _Tp, typename _T2, int m, int n> static inline
  96. MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
  97. {
  98. MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
  99. return (commaInitializer, val);
  100. }
  101. template<typename _Tp, int m, int n> inline
  102. MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
  103. : dst(_mtx), idx(0)
  104. {}
  105. template<typename _Tp, int m, int n> template<typename _T2> inline
  106. MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
  107. {
  108. CV_DbgAssert( idx < m*n );
  109. dst->val[idx++] = saturate_cast<_Tp>(value);
  110. return *this;
  111. }
  112. template<typename _Tp, int m, int n> inline
  113. Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
  114. {
  115. CV_DbgAssert( idx == n*m );
  116. return *dst;
  117. }
  118. ////////////////////////////////// Matx Implementation ///////////////////////////////////
  119. template<typename _Tp, int m, int n> inline
  120. Matx<_Tp, m, n>::Matx()
  121. {
  122. for(int i = 0; i < channels; i++) val[i] = _Tp(0);
  123. }
  124. template<typename _Tp, int m, int n> inline
  125. Matx<_Tp, m, n>::Matx(_Tp v0)
  126. {
  127. val[0] = v0;
  128. for(int i = 1; i < channels; i++) val[i] = _Tp(0);
  129. }
  130. template<typename _Tp, int m, int n> inline
  131. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
  132. {
  133. CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements.");
  134. val[0] = v0; val[1] = v1;
  135. for(int i = 2; i < channels; i++) val[i] = _Tp(0);
  136. }
  137. template<typename _Tp, int m, int n> inline
  138. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
  139. {
  140. CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements.");
  141. val[0] = v0; val[1] = v1; val[2] = v2;
  142. for(int i = 3; i < channels; i++) val[i] = _Tp(0);
  143. }
  144. template<typename _Tp, int m, int n> inline
  145. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
  146. {
  147. CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements.");
  148. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  149. for(int i = 4; i < channels; i++) val[i] = _Tp(0);
  150. }
  151. template<typename _Tp, int m, int n> inline
  152. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
  153. {
  154. CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements.");
  155. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
  156. for(int i = 5; i < channels; i++) val[i] = _Tp(0);
  157. }
  158. template<typename _Tp, int m, int n> inline
  159. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
  160. {
  161. CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements.");
  162. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  163. val[4] = v4; val[5] = v5;
  164. for(int i = 6; i < channels; i++) val[i] = _Tp(0);
  165. }
  166. template<typename _Tp, int m, int n> inline
  167. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
  168. {
  169. CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements.");
  170. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  171. val[4] = v4; val[5] = v5; val[6] = v6;
  172. for(int i = 7; i < channels; i++) val[i] = _Tp(0);
  173. }
  174. template<typename _Tp, int m, int n> inline
  175. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
  176. {
  177. CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements.");
  178. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  179. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  180. for(int i = 8; i < channels; i++) val[i] = _Tp(0);
  181. }
  182. template<typename _Tp, int m, int n> inline
  183. Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
  184. {
  185. CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements.");
  186. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  187. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  188. val[8] = v8;
  189. for(int i = 9; i < channels; i++) val[i] = _Tp(0);
  190. }
  191. template<typename _Tp, int m, int n> inline
  192. 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)
  193. {
  194. CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements.");
  195. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  196. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  197. val[8] = v8; val[9] = v9;
  198. for(int i = 10; i < channels; i++) val[i] = _Tp(0);
  199. }
  200. template<typename _Tp, int m, int n> inline
  201. 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)
  202. {
  203. CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements.");
  204. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  205. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  206. val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
  207. for(int i = 12; i < channels; i++) val[i] = _Tp(0);
  208. }
  209. template<typename _Tp, int m, int n> inline
  210. 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)
  211. {
  212. CV_StaticAssert(channels >= 14, "Matx should have at least 14 elements.");
  213. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  214. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  215. val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
  216. val[12] = v12; val[13] = v13;
  217. for (int i = 14; i < channels; i++) val[i] = _Tp(0);
  218. }
  219. template<typename _Tp, int m, int n> inline
  220. 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)
  221. {
  222. CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements.");
  223. val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
  224. val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
  225. val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
  226. val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
  227. for(int i = 16; i < channels; i++) val[i] = _Tp(0);
  228. }
  229. // WARNING: unreachable code using Ninja
  230. #if defined _MSC_VER && _MSC_VER >= 1920
  231. #pragma warning(push)
  232. #pragma warning(disable: 4702)
  233. #endif
  234. template<typename _Tp, int m, int n> inline
  235. Matx<_Tp, m, n>::Matx(const _Tp* values)
  236. {
  237. for( int i = 0; i < channels; i++ ) val[i] = values[i];
  238. }
  239. #if defined _MSC_VER && _MSC_VER >= 1920
  240. #pragma warning(pop)
  241. #endif
  242. template<typename _Tp, int m, int n> inline
  243. Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list)
  244. {
  245. CV_DbgAssert(list.size() == channels);
  246. int i = 0;
  247. for(const auto& elem : list)
  248. {
  249. val[i++] = elem;
  250. }
  251. }
  252. template<typename _Tp, int m, int n> inline
  253. Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
  254. {
  255. Matx<_Tp, m, n> M;
  256. for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
  257. return M;
  258. }
  259. template<typename _Tp, int m, int n> inline
  260. Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
  261. {
  262. return all(0);
  263. }
  264. template<typename _Tp, int m, int n> inline
  265. Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
  266. {
  267. return all(1);
  268. }
  269. template<typename _Tp, int m, int n> inline
  270. Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
  271. {
  272. Matx<_Tp,m,n> M;
  273. for(int i = 0; i < shortdim; i++)
  274. M(i,i) = 1;
  275. return M;
  276. }
  277. template<typename _Tp, int m, int n> inline
  278. _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
  279. {
  280. _Tp s = 0;
  281. for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i];
  282. return s;
  283. }
  284. template<typename _Tp, int m, int n> inline
  285. double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
  286. {
  287. double s = 0;
  288. for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i];
  289. return s;
  290. }
  291. template<typename _Tp, int m, int n> inline
  292. Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d)
  293. {
  294. Matx<_Tp,m,n> M;
  295. for(int i = 0; i < shortdim; i++)
  296. M(i,i) = d(i, 0);
  297. return M;
  298. }
  299. template<typename _Tp, int m, int n> template<typename T2>
  300. inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
  301. {
  302. Matx<T2, m, n> M;
  303. for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
  304. return M;
  305. }
  306. template<typename _Tp, int m, int n> template<int m1, int n1> inline
  307. Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
  308. {
  309. CV_StaticAssert(m1*n1 == m*n, "Input and destination matrices must have the same number of elements");
  310. return (const Matx<_Tp, m1, n1>&)*this;
  311. }
  312. template<typename _Tp, int m, int n>
  313. template<int m1, int n1> inline
  314. Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const
  315. {
  316. CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n);
  317. Matx<_Tp, m1, n1> s;
  318. for( int di = 0; di < m1; di++ )
  319. for( int dj = 0; dj < n1; dj++ )
  320. s(di, dj) = (*this)(base_row+di, base_col+dj);
  321. return s;
  322. }
  323. template<typename _Tp, int m, int n> inline
  324. Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
  325. {
  326. CV_DbgAssert((unsigned)i < (unsigned)m);
  327. return Matx<_Tp, 1, n>(&val[i*n]);
  328. }
  329. template<typename _Tp, int m, int n> inline
  330. Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
  331. {
  332. CV_DbgAssert((unsigned)j < (unsigned)n);
  333. Matx<_Tp, m, 1> v;
  334. for( int i = 0; i < m; i++ )
  335. v.val[i] = val[i*n + j];
  336. return v;
  337. }
  338. template<typename _Tp, int m, int n> inline
  339. typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
  340. {
  341. diag_type d;
  342. for( int i = 0; i < shortdim; i++ )
  343. d.val[i] = val[i*n + i];
  344. return d;
  345. }
  346. template<typename _Tp, int m, int n> inline
  347. const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const
  348. {
  349. CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
  350. return this->val[row_idx*n + col_idx];
  351. }
  352. template<typename _Tp, int m, int n> inline
  353. _Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx)
  354. {
  355. CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
  356. return val[row_idx*n + col_idx];
  357. }
  358. template<typename _Tp, int m, int n> inline
  359. const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
  360. {
  361. CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
  362. CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
  363. return val[i];
  364. }
  365. template<typename _Tp, int m, int n> inline
  366. _Tp& Matx<_Tp, m, n>::operator ()(int i)
  367. {
  368. CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
  369. CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
  370. return val[i];
  371. }
  372. template<typename _Tp, int m, int n> inline
  373. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
  374. {
  375. for( int i = 0; i < channels; i++ )
  376. val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
  377. }
  378. template<typename _Tp, int m, int n> inline
  379. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
  380. {
  381. for( int i = 0; i < channels; i++ )
  382. val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
  383. }
  384. template<typename _Tp, int m, int n> template<typename _T2> inline
  385. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
  386. {
  387. for( int i = 0; i < channels; i++ )
  388. val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
  389. }
  390. template<typename _Tp, int m, int n> inline
  391. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
  392. {
  393. for( int i = 0; i < channels; i++ )
  394. val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
  395. }
  396. template<typename _Tp, int m, int n> inline
  397. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp)
  398. {
  399. for( int i = 0; i < channels; i++ )
  400. val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]);
  401. }
  402. template<typename _Tp, int m, int n> template<int l> inline
  403. Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
  404. {
  405. for( int i = 0; i < m; i++ )
  406. for( int j = 0; j < n; j++ )
  407. {
  408. _Tp s = 0;
  409. for( int k = 0; k < l; k++ )
  410. s += a(i, k) * b(k, j);
  411. val[i*n + j] = s;
  412. }
  413. }
  414. template<typename _Tp, int m, int n> inline
  415. Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
  416. {
  417. for( int i = 0; i < m; i++ )
  418. for( int j = 0; j < n; j++ )
  419. val[i*n + j] = a(j, i);
  420. }
  421. template<typename _Tp, int m, int n> inline
  422. Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
  423. {
  424. return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
  425. }
  426. template<typename _Tp, int m, int n> inline
  427. Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const
  428. {
  429. return Matx<_Tp, m, n>(*this, a, Matx_DivOp());
  430. }
  431. template<typename _Tp, int m, int n> inline
  432. Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
  433. {
  434. return Matx<_Tp, n, m>(*this, Matx_TOp());
  435. }
  436. template<typename _Tp, int m, int n> inline
  437. Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const
  438. {
  439. Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method);
  440. return (Vec<_Tp, n>&)(x);
  441. }
  442. template<typename _Tp, int m> static inline
  443. double determinant(const Matx<_Tp, m, m>& a)
  444. {
  445. return cv::internal::Matx_DetOp<_Tp, m>()(a);
  446. }
  447. template<typename _Tp, int m, int n> static inline
  448. double trace(const Matx<_Tp, m, n>& a)
  449. {
  450. _Tp s = 0;
  451. for( int i = 0; i < std::min(m, n); i++ )
  452. s += a(i,i);
  453. return s;
  454. }
  455. template<typename _Tp, int m, int n> static inline
  456. double norm(const Matx<_Tp, m, n>& M)
  457. {
  458. return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n));
  459. }
  460. template<typename _Tp, int m, int n> static inline
  461. double norm(const Matx<_Tp, m, n>& M, int normType)
  462. {
  463. switch(normType) {
  464. case NORM_INF:
  465. return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
  466. case NORM_L1:
  467. return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
  468. case NORM_L2SQR:
  469. return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
  470. default:
  471. case NORM_L2:
  472. return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n));
  473. }
  474. }
  475. template<typename _Tp1, typename _Tp2, int m, int n> static inline
  476. Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
  477. {
  478. for( int i = 0; i < m*n; i++ )
  479. a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
  480. return a;
  481. }
  482. template<typename _Tp1, typename _Tp2, int m, int n> static inline
  483. Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
  484. {
  485. for( int i = 0; i < m*n; i++ )
  486. a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
  487. return a;
  488. }
  489. template<typename _Tp, int m, int n> static inline
  490. Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
  491. {
  492. return Matx<_Tp, m, n>(a, b, Matx_AddOp());
  493. }
  494. template<typename _Tp, int m, int n> static inline
  495. Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
  496. {
  497. return Matx<_Tp, m, n>(a, b, Matx_SubOp());
  498. }
  499. template<typename _Tp, int m, int n> static inline
  500. Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
  501. {
  502. for( int i = 0; i < m*n; i++ )
  503. a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
  504. return a;
  505. }
  506. template<typename _Tp, int m, int n> static inline
  507. Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
  508. {
  509. for( int i = 0; i < m*n; i++ )
  510. a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
  511. return a;
  512. }
  513. template<typename _Tp, int m, int n> static inline
  514. Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
  515. {
  516. for( int i = 0; i < m*n; i++ )
  517. a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
  518. return a;
  519. }
  520. template<typename _Tp, int m, int n> static inline
  521. Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
  522. {
  523. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  524. }
  525. template<typename _Tp, int m, int n> static inline
  526. Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
  527. {
  528. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  529. }
  530. template<typename _Tp, int m, int n> static inline
  531. Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
  532. {
  533. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  534. }
  535. template<typename _Tp, int m, int n> static inline
  536. Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
  537. {
  538. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  539. }
  540. template<typename _Tp, int m, int n> static inline
  541. Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
  542. {
  543. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  544. }
  545. template<typename _Tp, int m, int n> static inline
  546. Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
  547. {
  548. return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
  549. }
  550. template<typename _Tp, int m, int n> static inline
  551. Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, float alpha)
  552. {
  553. for( int i = 0; i < m*n; i++ )
  554. a.val[i] = a.val[i] / alpha;
  555. return a;
  556. }
  557. template<typename _Tp, int m, int n> static inline
  558. Matx<_Tp, m, n>& operator /= (Matx<_Tp, m, n>& a, double alpha)
  559. {
  560. for( int i = 0; i < m*n; i++ )
  561. a.val[i] = a.val[i] / alpha;
  562. return a;
  563. }
  564. template<typename _Tp, int m, int n> static inline
  565. Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, float alpha)
  566. {
  567. return Matx<_Tp, m, n>(a, 1.f/alpha, Matx_ScaleOp());
  568. }
  569. template<typename _Tp, int m, int n> static inline
  570. Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n>& a, double alpha)
  571. {
  572. return Matx<_Tp, m, n>(a, 1./alpha, Matx_ScaleOp());
  573. }
  574. template<typename _Tp, int m, int n> static inline
  575. Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
  576. {
  577. return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
  578. }
  579. template<typename _Tp, int m, int n, int l> static inline
  580. Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
  581. {
  582. return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
  583. }
  584. template<typename _Tp, int m, int n> static inline
  585. Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b)
  586. {
  587. Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp());
  588. return (const Vec<_Tp, m>&)(c);
  589. }
  590. template<typename _Tp, int m, int n> static inline
  591. bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
  592. {
  593. for( int i = 0; i < m*n; i++ )
  594. if( a.val[i] != b.val[i] ) return false;
  595. return true;
  596. }
  597. template<typename _Tp, int m, int n> static inline
  598. bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
  599. {
  600. return !(a == b);
  601. }
  602. //==============================================================================
  603. // Vec
  604. template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> >
  605. {
  606. public:
  607. typedef Vec<_Tp, cn> value_type;
  608. typedef Vec<typename DataType<_Tp>::work_type, cn> work_type;
  609. typedef _Tp channel_type;
  610. typedef value_type vec_type;
  611. enum { generic_type = 0,
  612. channels = cn,
  613. fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
  614. #ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
  615. depth = DataType<channel_type>::depth,
  616. type = CV_MAKETYPE(depth, channels),
  617. #endif
  618. _dummy_enum_finalizer = 0
  619. };
  620. };
  621. namespace traits {
  622. template<typename _Tp, int cn>
  623. struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; };
  624. template<typename _Tp, int cn>
  625. struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; };
  626. } // namespace
  627. /** @brief Comma-separated Vec Initializer
  628. */
  629. template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
  630. {
  631. public:
  632. VecCommaInitializer(Vec<_Tp, m>* _vec);
  633. template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val);
  634. Vec<_Tp, m> operator *() const;
  635. };
  636. template<typename _Tp, typename _T2, int cn> static inline
  637. VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
  638. {
  639. VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
  640. return (commaInitializer, val);
  641. }
  642. template<typename _Tp, int cn> inline
  643. VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
  644. : MatxCommaInitializer<_Tp, cn, 1>(_vec)
  645. {}
  646. template<typename _Tp, int cn> template<typename _T2> inline
  647. VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
  648. {
  649. CV_DbgAssert( this->idx < cn );
  650. this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
  651. return *this;
  652. }
  653. template<typename _Tp, int cn> inline
  654. Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
  655. {
  656. CV_DbgAssert( this->idx == cn );
  657. return *this->dst;
  658. }
  659. template<typename _Tp, int cn> inline
  660. Vec<_Tp, cn>::Vec() {}
  661. template<typename _Tp, int cn> inline
  662. Vec<_Tp, cn>::Vec(_Tp v0)
  663. : Matx<_Tp, cn, 1>(v0) {}
  664. template<typename _Tp, int cn> inline
  665. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
  666. : Matx<_Tp, cn, 1>(v0, v1) {}
  667. template<typename _Tp, int cn> inline
  668. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
  669. : Matx<_Tp, cn, 1>(v0, v1, v2) {}
  670. template<typename _Tp, int cn> inline
  671. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
  672. : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {}
  673. template<typename _Tp, int cn> inline
  674. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
  675. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {}
  676. template<typename _Tp, int cn> inline
  677. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
  678. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {}
  679. template<typename _Tp, int cn> inline
  680. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
  681. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {}
  682. template<typename _Tp, int cn> inline
  683. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
  684. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {}
  685. template<typename _Tp, int cn> inline
  686. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
  687. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {}
  688. template<typename _Tp, int cn> inline
  689. Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
  690. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {}
  691. template<typename _Tp, int cn> inline
  692. 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)
  693. : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {}
  694. template<typename _Tp, int cn> inline
  695. Vec<_Tp, cn>::Vec(const _Tp* values)
  696. : Matx<_Tp, cn, 1>(values) {}
  697. template<typename _Tp, int cn> inline
  698. Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list)
  699. : Matx<_Tp, cn, 1>(list) {}
  700. template<typename _Tp, int cn> inline
  701. Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
  702. : Matx<_Tp, cn, 1>(m.val) {}
  703. template<typename _Tp, int cn> inline
  704. Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op)
  705. : Matx<_Tp, cn, 1>(a, b, op) {}
  706. template<typename _Tp, int cn> inline
  707. Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op)
  708. : Matx<_Tp, cn, 1>(a, b, op) {}
  709. template<typename _Tp, int cn> template<typename _T2> inline
  710. Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op)
  711. : Matx<_Tp, cn, 1>(a, alpha, op) {}
  712. template<typename _Tp, int cn> inline
  713. Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
  714. {
  715. Vec v;
  716. for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
  717. return v;
  718. }
  719. template<typename _Tp, int cn> inline
  720. Vec<_Tp, cn> Vec<_Tp, cn>::ones()
  721. {
  722. return Vec::all(1);
  723. }
  724. template<typename _Tp, int cn> inline
  725. Vec<_Tp, cn> Vec<_Tp, cn>::zeros()
  726. {
  727. return Vec::all(0);
  728. }
  729. template<typename _Tp, int cn> inline
  730. Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
  731. {
  732. Vec<_Tp, cn> w;
  733. for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
  734. return w;
  735. }
  736. template<> inline
  737. Vec<float, 2> Vec<float, 2>::conj() const
  738. {
  739. return cv::internal::conjugate(*this);
  740. }
  741. template<> inline
  742. Vec<double, 2> Vec<double, 2>::conj() const
  743. {
  744. return cv::internal::conjugate(*this);
  745. }
  746. template<> inline
  747. Vec<float, 4> Vec<float, 4>::conj() const
  748. {
  749. return cv::internal::conjugate(*this);
  750. }
  751. template<> inline
  752. Vec<double, 4> Vec<double, 4>::conj() const
  753. {
  754. return cv::internal::conjugate(*this);
  755. }
  756. template<typename _Tp, int cn> inline
  757. Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const
  758. {
  759. CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined");
  760. return Vec<_Tp, cn>();
  761. }
  762. template<> inline
  763. Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
  764. {
  765. return Vec<float,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
  766. this->val[2]*v.val[0] - this->val[0]*v.val[2],
  767. this->val[0]*v.val[1] - this->val[1]*v.val[0]);
  768. }
  769. template<> inline
  770. Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
  771. {
  772. return Vec<double,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
  773. this->val[2]*v.val[0] - this->val[0]*v.val[2],
  774. this->val[0]*v.val[1] - this->val[1]*v.val[0]);
  775. }
  776. template<typename _Tp, int cn> template<typename T2> inline
  777. Vec<_Tp, cn>::operator Vec<T2, cn>() const
  778. {
  779. Vec<T2, cn> v;
  780. for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
  781. return v;
  782. }
  783. template<typename _Tp, int cn> inline
  784. const _Tp& Vec<_Tp, cn>::operator [](int i) const
  785. {
  786. CV_DbgAssert( (unsigned)i < (unsigned)cn );
  787. return this->val[i];
  788. }
  789. template<typename _Tp, int cn> inline
  790. _Tp& Vec<_Tp, cn>::operator [](int i)
  791. {
  792. CV_DbgAssert( (unsigned)i < (unsigned)cn );
  793. return this->val[i];
  794. }
  795. template<typename _Tp, int cn> inline
  796. const _Tp& Vec<_Tp, cn>::operator ()(int i) const
  797. {
  798. CV_DbgAssert( (unsigned)i < (unsigned)cn );
  799. return this->val[i];
  800. }
  801. template<typename _Tp, int cn> inline
  802. _Tp& Vec<_Tp, cn>::operator ()(int i)
  803. {
  804. CV_DbgAssert( (unsigned)i < (unsigned)cn );
  805. return this->val[i];
  806. }
  807. template<typename _Tp, int cn> inline
  808. Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
  809. {
  810. double nv = norm(v);
  811. return v * (nv ? 1./nv : 0.);
  812. }
  813. template<typename _Tp1, typename _Tp2, int cn> static inline
  814. Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
  815. {
  816. for( int i = 0; i < cn; i++ )
  817. a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
  818. return a;
  819. }
  820. template<typename _Tp1, typename _Tp2, int cn> static inline
  821. Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
  822. {
  823. for( int i = 0; i < cn; i++ )
  824. a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
  825. return a;
  826. }
  827. template<typename _Tp, int cn> static inline
  828. Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
  829. {
  830. return Vec<_Tp, cn>(a, b, Matx_AddOp());
  831. }
  832. template<typename _Tp, int cn> static inline
  833. Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
  834. {
  835. return Vec<_Tp, cn>(a, b, Matx_SubOp());
  836. }
  837. template<typename _Tp, int cn> static inline
  838. Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
  839. {
  840. for( int i = 0; i < cn; i++ )
  841. a[i] = saturate_cast<_Tp>(a[i]*alpha);
  842. return a;
  843. }
  844. template<typename _Tp, int cn> static inline
  845. Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
  846. {
  847. for( int i = 0; i < cn; i++ )
  848. a[i] = saturate_cast<_Tp>(a[i]*alpha);
  849. return a;
  850. }
  851. template<typename _Tp, int cn> static inline
  852. Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
  853. {
  854. for( int i = 0; i < cn; i++ )
  855. a[i] = saturate_cast<_Tp>(a[i]*alpha);
  856. return a;
  857. }
  858. template<typename _Tp, int cn> static inline
  859. Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha)
  860. {
  861. double ialpha = 1./alpha;
  862. for( int i = 0; i < cn; i++ )
  863. a[i] = saturate_cast<_Tp>(a[i]*ialpha);
  864. return a;
  865. }
  866. template<typename _Tp, int cn> static inline
  867. Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha)
  868. {
  869. float ialpha = 1.f/alpha;
  870. for( int i = 0; i < cn; i++ )
  871. a[i] = saturate_cast<_Tp>(a[i]*ialpha);
  872. return a;
  873. }
  874. template<typename _Tp, int cn> static inline
  875. Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha)
  876. {
  877. double ialpha = 1./alpha;
  878. for( int i = 0; i < cn; i++ )
  879. a[i] = saturate_cast<_Tp>(a[i]*ialpha);
  880. return a;
  881. }
  882. template<typename _Tp, int cn> static inline
  883. Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha)
  884. {
  885. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  886. }
  887. template<typename _Tp, int cn> static inline
  888. Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a)
  889. {
  890. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  891. }
  892. template<typename _Tp, int cn> static inline
  893. Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha)
  894. {
  895. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  896. }
  897. template<typename _Tp, int cn> static inline
  898. Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a)
  899. {
  900. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  901. }
  902. template<typename _Tp, int cn> static inline
  903. Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha)
  904. {
  905. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  906. }
  907. template<typename _Tp, int cn> static inline
  908. Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a)
  909. {
  910. return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
  911. }
  912. template<typename _Tp, int cn> static inline
  913. Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha)
  914. {
  915. return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
  916. }
  917. template<typename _Tp, int cn> static inline
  918. Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha)
  919. {
  920. return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp());
  921. }
  922. template<typename _Tp, int cn> static inline
  923. Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha)
  924. {
  925. return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
  926. }
  927. template<typename _Tp, int cn> static inline
  928. Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a)
  929. {
  930. Vec<_Tp,cn> t;
  931. for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
  932. return t;
  933. }
  934. template<typename _Tp> inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
  935. {
  936. return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]),
  937. saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]),
  938. saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]),
  939. saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0]));
  940. }
  941. template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
  942. {
  943. v1 = v1 * v2;
  944. return v1;
  945. }
  946. } // cv::
  947. #endif // OPENCV_CORE_MATX_INL_HPP