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