operations.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  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. // Copyright (C) 2015, Itseez Inc., all rights reserved.
  17. // Third party copyrights are property of their respective owners.
  18. //
  19. // Redistribution and use in source and binary forms, with or without modification,
  20. // are permitted provided that the following conditions are met:
  21. //
  22. // * Redistribution's of source code must retain the above copyright notice,
  23. // this list of conditions and the following disclaimer.
  24. //
  25. // * Redistribution's in binary form must reproduce the above copyright notice,
  26. // this list of conditions and the following disclaimer in the documentation
  27. // and/or other materials provided with the distribution.
  28. //
  29. // * The name of the copyright holders may not be used to endorse or promote products
  30. // derived from this software without specific prior written permission.
  31. //
  32. // This software is provided by the copyright holders and contributors "as is" and
  33. // any express or implied warranties, including, but not limited to, the implied
  34. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  35. // In no event shall the Intel Corporation or contributors be liable for any direct,
  36. // indirect, incidental, special, exemplary, or consequential damages
  37. // (including, but not limited to, procurement of substitute goods or services;
  38. // loss of use, data, or profits; or business interruption) however caused
  39. // and on any theory of liability, whether in contract, strict liability,
  40. // or tort (including negligence or otherwise) arising in any way out of
  41. // the use of this software, even if advised of the possibility of such damage.
  42. //
  43. //M*/
  44. #ifndef OPENCV_CORE_OPERATIONS_HPP
  45. #define OPENCV_CORE_OPERATIONS_HPP
  46. #ifndef __cplusplus
  47. # error operations.hpp header must be compiled as C++
  48. #endif
  49. #include <cstdio>
  50. //! @cond IGNORED
  51. namespace cv
  52. {
  53. ////////////////////////////// Matx methods depending on core API /////////////////////////////
  54. namespace internal
  55. {
  56. template<typename _Tp, int m, int n> struct Matx_FastInvOp
  57. {
  58. bool operator()(const Matx<_Tp, m, n>& a, Matx<_Tp, n, m>& b, int method) const
  59. {
  60. return invert(a, b, method) != 0;
  61. }
  62. };
  63. template<typename _Tp, int m> struct Matx_FastInvOp<_Tp, m, m>
  64. {
  65. bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
  66. {
  67. if (method == DECOMP_LU || method == DECOMP_CHOLESKY)
  68. {
  69. Matx<_Tp, m, m> temp = a;
  70. // assume that b is all 0's on input => make it a unity matrix
  71. for (int i = 0; i < m; i++)
  72. b(i, i) = (_Tp)1;
  73. if (method == DECOMP_CHOLESKY)
  74. return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m);
  75. return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0;
  76. }
  77. else
  78. {
  79. return invert(a, b, method) != 0;
  80. }
  81. }
  82. };
  83. template<typename _Tp> struct Matx_FastInvOp<_Tp, 2, 2>
  84. {
  85. bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int /*method*/) const
  86. {
  87. _Tp d = (_Tp)determinant(a);
  88. if (d == 0)
  89. return false;
  90. d = 1/d;
  91. b(1,1) = a(0,0)*d;
  92. b(0,0) = a(1,1)*d;
  93. b(0,1) = -a(0,1)*d;
  94. b(1,0) = -a(1,0)*d;
  95. return true;
  96. }
  97. };
  98. template<typename _Tp> struct Matx_FastInvOp<_Tp, 3, 3>
  99. {
  100. bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int /*method*/) const
  101. {
  102. _Tp d = (_Tp)determinant(a);
  103. if (d == 0)
  104. return false;
  105. d = 1/d;
  106. b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d;
  107. b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d;
  108. b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d;
  109. b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d;
  110. b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d;
  111. b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d;
  112. b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d;
  113. b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d;
  114. b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d;
  115. return true;
  116. }
  117. };
  118. template<typename _Tp, int m, int l, int n> struct Matx_FastSolveOp
  119. {
  120. bool operator()(const Matx<_Tp, m, l>& a, const Matx<_Tp, m, n>& b,
  121. Matx<_Tp, l, n>& x, int method) const
  122. {
  123. return cv::solve(a, b, x, method);
  124. }
  125. };
  126. template<typename _Tp, int m, int n> struct Matx_FastSolveOp<_Tp, m, m, n>
  127. {
  128. bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
  129. Matx<_Tp, m, n>& x, int method) const
  130. {
  131. if (method == DECOMP_LU || method == DECOMP_CHOLESKY)
  132. {
  133. Matx<_Tp, m, m> temp = a;
  134. x = b;
  135. if( method == DECOMP_CHOLESKY )
  136. return Cholesky(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n);
  137. return LU(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n) != 0;
  138. }
  139. else
  140. {
  141. return cv::solve(a, b, x, method);
  142. }
  143. }
  144. };
  145. template<typename _Tp> struct Matx_FastSolveOp<_Tp, 2, 2, 1>
  146. {
  147. bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
  148. Matx<_Tp, 2, 1>& x, int) const
  149. {
  150. _Tp d = (_Tp)determinant(a);
  151. if (d == 0)
  152. return false;
  153. d = 1/d;
  154. x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d;
  155. x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d;
  156. return true;
  157. }
  158. };
  159. template<typename _Tp> struct Matx_FastSolveOp<_Tp, 3, 3, 1>
  160. {
  161. bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
  162. Matx<_Tp, 3, 1>& x, int) const
  163. {
  164. _Tp d = (_Tp)determinant(a);
  165. if (d == 0)
  166. return false;
  167. d = 1/d;
  168. x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) -
  169. a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) +
  170. a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2)));
  171. x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) -
  172. b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) +
  173. a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0)));
  174. x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) -
  175. a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) +
  176. b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0)));
  177. return true;
  178. }
  179. };
  180. } // internal
  181. template<typename _Tp, int m, int n> inline
  182. Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b)
  183. {
  184. Matx<_Tp,m,n> M;
  185. cv::randu(M, Scalar(a), Scalar(b));
  186. return M;
  187. }
  188. template<typename _Tp, int m, int n> inline
  189. Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b)
  190. {
  191. Matx<_Tp,m,n> M;
  192. cv::randn(M, Scalar(a), Scalar(b));
  193. return M;
  194. }
  195. template<typename _Tp, int cn> inline
  196. Vec<_Tp, cn> Vec<_Tp, cn>::randu(_Tp a, _Tp b)
  197. {
  198. Vec<_Tp,cn> V;
  199. cv::randu(V, Scalar(a), Scalar(b));
  200. return V;
  201. }
  202. template<typename _Tp, int cn> inline
  203. Vec<_Tp, cn> Vec<_Tp, cn>::randn(_Tp a, _Tp b)
  204. {
  205. Vec<_Tp,cn> V;
  206. cv::randn(V, Scalar(a), Scalar(b));
  207. return V;
  208. }
  209. template<typename _Tp, int m, int n> inline
  210. Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method, bool *p_is_ok /*= NULL*/) const
  211. {
  212. Matx<_Tp, n, m> b;
  213. bool ok = cv::internal::Matx_FastInvOp<_Tp, m, n>()(*this, b, method);
  214. if (p_is_ok) *p_is_ok = ok;
  215. return ok ? b : Matx<_Tp, n, m>::zeros();
  216. }
  217. template<typename _Tp, int m, int n> template<int l> inline
  218. Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const
  219. {
  220. Matx<_Tp, n, l> x;
  221. bool ok = cv::internal::Matx_FastSolveOp<_Tp, m, n, l>()(*this, rhs, x, method);
  222. return ok ? x : Matx<_Tp, n, l>::zeros();
  223. }
  224. ////////////////////////// Augmenting algebraic & logical operations //////////////////////////
  225. #define CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
  226. static inline A& operator op (A& a, const B& b) { cvop; return a; }
  227. #define CV_MAT_AUG_OPERATOR(op, cvop, A, B) \
  228. CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
  229. CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
  230. #define CV_MAT_AUG_OPERATOR_T(op, cvop, A, B) \
  231. template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
  232. template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
  233. #define CV_MAT_AUG_OPERATOR_TN(op, cvop, A) \
  234. template<typename _Tp, int m, int n> static inline A& operator op (A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } \
  235. template<typename _Tp, int m, int n> static inline const A& operator op (const A& a, const Matx<_Tp,m,n>& b) { cvop; return a; }
  236. CV_MAT_AUG_OPERATOR (+=, cv::add(a, b, (const Mat&)a), Mat, Mat)
  237. CV_MAT_AUG_OPERATOR (+=, cv::add(a, b, (const Mat&)a), Mat, Scalar)
  238. CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  239. CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
  240. CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  241. CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a, Mat(b), (const Mat&)a), Mat)
  242. CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  243. CV_MAT_AUG_OPERATOR (-=, cv::subtract(a, b, (const Mat&)a), Mat, Mat)
  244. CV_MAT_AUG_OPERATOR (-=, cv::subtract(a, b, (const Mat&)a), Mat, Scalar)
  245. CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  246. CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
  247. CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  248. CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a, Mat(b), (const Mat&)a), Mat)
  249. CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  250. CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat)
  251. CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat)
  252. CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat_<_Tp>)
  253. CV_MAT_AUG_OPERATOR (*=, a.convertTo(a, -1, b), Mat, double)
  254. CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double)
  255. CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat)
  256. CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat_<_Tp>)
  257. CV_MAT_AUG_OPERATOR (/=, cv::divide(a, b, (const Mat&)a), Mat, Mat)
  258. CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  259. CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  260. CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double)
  261. CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double)
  262. CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), (const Mat&)a), Mat)
  263. CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  264. CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a, b, (const Mat&)a), Mat, Mat)
  265. CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a, b, (const Mat&)a), Mat, Scalar)
  266. CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  267. CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
  268. CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  269. CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), (const Mat&)a), Mat)
  270. CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  271. CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a, b, (const Mat&)a), Mat, Mat)
  272. CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a, b, (const Mat&)a), Mat, Scalar)
  273. CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  274. CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
  275. CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  276. CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), (const Mat&)a), Mat)
  277. CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  278. CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat, Mat)
  279. CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat, Scalar)
  280. CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
  281. CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
  282. CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
  283. CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), (const Mat&)a), Mat)
  284. CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
  285. #undef CV_MAT_AUG_OPERATOR_TN
  286. #undef CV_MAT_AUG_OPERATOR_T
  287. #undef CV_MAT_AUG_OPERATOR
  288. #undef CV_MAT_AUG_OPERATOR1
  289. ///////////////////////////////////////////// SVD /////////////////////////////////////////////
  290. inline SVD::SVD() {}
  291. inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
  292. inline void SVD::solveZ( InputArray m, OutputArray _dst )
  293. {
  294. Mat mtx = m.getMat();
  295. SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
  296. _dst.create(svd.vt.cols, 1, svd.vt.type());
  297. Mat dst = _dst.getMat();
  298. svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
  299. }
  300. template<typename _Tp, int m, int n, int nm> inline void
  301. SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
  302. {
  303. CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
  304. Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
  305. SVD::compute(_a, _w, _u, _vt);
  306. CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
  307. }
  308. template<typename _Tp, int m, int n, int nm> inline void
  309. SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
  310. {
  311. CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
  312. Mat _a(a, false), _w(w, false);
  313. SVD::compute(_a, _w);
  314. CV_Assert(_w.data == (uchar*)&w.val[0]);
  315. }
  316. template<typename _Tp, int m, int n, int nm, int nb> inline void
  317. SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
  318. const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
  319. Matx<_Tp, n, nb>& dst )
  320. {
  321. CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
  322. Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
  323. SVD::backSubst(_w, _u, _vt, _rhs, _dst);
  324. CV_Assert(_dst.data == (uchar*)&dst.val[0]);
  325. }
  326. /////////////////////////////////// Multiply-with-Carry RNG ///////////////////////////////////
  327. inline RNG::RNG() { state = 0xffffffff; }
  328. inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
  329. inline RNG::operator uchar() { return (uchar)next(); }
  330. inline RNG::operator schar() { return (schar)next(); }
  331. inline RNG::operator ushort() { return (ushort)next(); }
  332. inline RNG::operator short() { return (short)next(); }
  333. inline RNG::operator int() { return (int)next(); }
  334. inline RNG::operator unsigned() { return next(); }
  335. inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
  336. inline RNG::operator double() { unsigned t = next(); return (((uint64)t << 32) | next()) * 5.4210108624275221700372640043497e-20; }
  337. inline unsigned RNG::operator ()(unsigned N) { return (unsigned)uniform(0,N); }
  338. inline unsigned RNG::operator ()() { return next(); }
  339. inline int RNG::uniform(int a, int b) { return a == b ? a : (int)(next() % (b - a) + a); }
  340. inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
  341. inline double RNG::uniform(double a, double b) { return ((double)*this)*(b - a) + a; }
  342. inline bool RNG::operator ==(const RNG& other) const { return state == other.state; }
  343. inline unsigned RNG::next()
  344. {
  345. state = (uint64)(unsigned)state* /*CV_RNG_COEFF*/ 4164903690U + (unsigned)(state >> 32);
  346. return (unsigned)state;
  347. }
  348. //! returns the next uniformly-distributed random number of the specified type
  349. template<typename _Tp> static inline _Tp randu()
  350. {
  351. return (_Tp)theRNG();
  352. }
  353. ///////////////////////////////// Formatted string generation /////////////////////////////////
  354. /** @brief Returns a text string formatted using the printf-like expression.
  355. The function acts like sprintf but forms and returns an STL string. It can be used to form an error
  356. message in the Exception constructor.
  357. @param fmt printf-compatible formatting specifiers.
  358. */
  359. CV_EXPORTS String format( const char* fmt, ... );
  360. ///////////////////////////////// Formatted output of cv::Mat /////////////////////////////////
  361. static inline
  362. Ptr<Formatted> format(InputArray mtx, int fmt)
  363. {
  364. return Formatter::get(fmt)->format(mtx.getMat());
  365. }
  366. static inline
  367. int print(Ptr<Formatted> fmtd, FILE* stream = stdout)
  368. {
  369. int written = 0;
  370. fmtd->reset();
  371. for(const char* str = fmtd->next(); str; str = fmtd->next())
  372. written += fputs(str, stream);
  373. return written;
  374. }
  375. static inline
  376. int print(const Mat& mtx, FILE* stream = stdout)
  377. {
  378. return print(Formatter::get()->format(mtx), stream);
  379. }
  380. static inline
  381. int print(const UMat& mtx, FILE* stream = stdout)
  382. {
  383. return print(Formatter::get()->format(mtx.getMat(ACCESS_READ)), stream);
  384. }
  385. template<typename _Tp> static inline
  386. int print(const std::vector<Point_<_Tp> >& vec, FILE* stream = stdout)
  387. {
  388. return print(Formatter::get()->format(Mat(vec)), stream);
  389. }
  390. template<typename _Tp> static inline
  391. int print(const std::vector<Point3_<_Tp> >& vec, FILE* stream = stdout)
  392. {
  393. return print(Formatter::get()->format(Mat(vec)), stream);
  394. }
  395. template<typename _Tp, int m, int n> static inline
  396. int print(const Matx<_Tp, m, n>& matx, FILE* stream = stdout)
  397. {
  398. return print(Formatter::get()->format(cv::Mat(matx)), stream);
  399. }
  400. //! @endcond
  401. /****************************************************************************************\
  402. * Auxiliary algorithms *
  403. \****************************************************************************************/
  404. /** @brief Splits an element set into equivalency classes.
  405. The generic function partition implements an \f$O(N^2)\f$ algorithm for splitting a set of \f$N\f$ elements
  406. into one or more equivalency classes, as described in
  407. <http://en.wikipedia.org/wiki/Disjoint-set_data_structure> . The function returns the number of
  408. equivalency classes.
  409. @param _vec Set of elements stored as a vector.
  410. @param labels Output vector of labels. It contains as many elements as vec. Each label labels[i] is
  411. a 0-based cluster index of `vec[i]`.
  412. @param predicate Equivalence predicate (pointer to a boolean function of two arguments or an
  413. instance of the class that has the method bool operator()(const _Tp& a, const _Tp& b) ). The
  414. predicate returns true when the elements are certainly in the same class, and returns false if they
  415. may or may not be in the same class.
  416. @ingroup core_cluster
  417. */
  418. template<typename _Tp, class _EqPredicate> int
  419. partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
  420. _EqPredicate predicate=_EqPredicate())
  421. {
  422. int i, j, N = (int)_vec.size();
  423. const _Tp* vec = &_vec[0];
  424. const int PARENT=0;
  425. const int RANK=1;
  426. std::vector<int> _nodes(N*2);
  427. int (*nodes)[2] = (int(*)[2])&_nodes[0];
  428. // The first O(N) pass: create N single-vertex trees
  429. for(i = 0; i < N; i++)
  430. {
  431. nodes[i][PARENT]=-1;
  432. nodes[i][RANK] = 0;
  433. }
  434. // The main O(N^2) pass: merge connected components
  435. for( i = 0; i < N; i++ )
  436. {
  437. int root = i;
  438. // find root
  439. while( nodes[root][PARENT] >= 0 )
  440. root = nodes[root][PARENT];
  441. for( j = 0; j < N; j++ )
  442. {
  443. if( i == j || !predicate(vec[i], vec[j]))
  444. continue;
  445. int root2 = j;
  446. while( nodes[root2][PARENT] >= 0 )
  447. root2 = nodes[root2][PARENT];
  448. if( root2 != root )
  449. {
  450. // unite both trees
  451. int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
  452. if( rank > rank2 )
  453. nodes[root2][PARENT] = root;
  454. else
  455. {
  456. nodes[root][PARENT] = root2;
  457. nodes[root2][RANK] += rank == rank2;
  458. root = root2;
  459. }
  460. CV_Assert( nodes[root][PARENT] < 0 );
  461. int k = j, parent;
  462. // compress the path from node2 to root
  463. while( (parent = nodes[k][PARENT]) >= 0 )
  464. {
  465. nodes[k][PARENT] = root;
  466. k = parent;
  467. }
  468. // compress the path from node to root
  469. k = i;
  470. while( (parent = nodes[k][PARENT]) >= 0 )
  471. {
  472. nodes[k][PARENT] = root;
  473. k = parent;
  474. }
  475. }
  476. }
  477. }
  478. // Final O(N) pass: enumerate classes
  479. labels.resize(N);
  480. int nclasses = 0;
  481. for( i = 0; i < N; i++ )
  482. {
  483. int root = i;
  484. while( nodes[root][PARENT] >= 0 )
  485. root = nodes[root][PARENT];
  486. // re-use the rank as the class label
  487. if( nodes[root][RANK] >= 0 )
  488. nodes[root][RANK] = ~nclasses++;
  489. labels[i] = ~nodes[root][RANK];
  490. }
  491. return nclasses;
  492. }
  493. } // cv
  494. #endif