openCV library for Renesas RZ/A

Dependents:   RZ_A2M_Mbed_samples

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?

UserRevisionLine numberNew 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