From: Vadim Pisarevsky Date: Fri, 7 Nov 2014 15:14:39 +0000 (+0300) Subject: moved cv::partition from private.hpp to operations.hpp, to expose the function to... X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~2839^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d58cadc1ea9e25a0332fcb883225dab89cc1a835;p=platform%2Fupstream%2Fopencv.git moved cv::partition from private.hpp to operations.hpp, to expose the function to users --- diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index d2f49d7..d230901 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -526,6 +526,105 @@ void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, Ptr<_Tp>& v } +/****************************************************************************************\ +* Auxiliary algorithms * +\****************************************************************************************/ + +// This function splits the input sequence or set into one or more equivalence classes and +// returns the vector of labels - 0-based class indexes for each element. +// predicate(a,b) returns true if the two sequence elements certainly belong to the same class. +// +// The algorithm is described in "Introduction to Algorithms" +// by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets" +template int +partition( const std::vector<_Tp>& _vec, std::vector& labels, + _EqPredicate predicate=_EqPredicate()) +{ + int i, j, N = (int)_vec.size(); + const _Tp* vec = &_vec[0]; + + const int PARENT=0; + const int RANK=1; + + std::vector _nodes(N*2); + int (*nodes)[2] = (int(*)[2])&_nodes[0]; + + // The first O(N) pass: create N single-vertex trees + for(i = 0; i < N; i++) + { + nodes[i][PARENT]=-1; + nodes[i][RANK] = 0; + } + + // The main O(N^2) pass: merge connected components + for( i = 0; i < N; i++ ) + { + int root = i; + + // find root + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + + for( j = 0; j < N; j++ ) + { + if( i == j || !predicate(vec[i], vec[j])) + continue; + int root2 = j; + + while( nodes[root2][PARENT] >= 0 ) + root2 = nodes[root2][PARENT]; + + if( root2 != root ) + { + // unite both trees + int rank = nodes[root][RANK], rank2 = nodes[root2][RANK]; + if( rank > rank2 ) + nodes[root2][PARENT] = root; + else + { + nodes[root][PARENT] = root2; + nodes[root2][RANK] += rank == rank2; + root = root2; + } + CV_Assert( nodes[root][PARENT] < 0 ); + + int k = j, parent; + + // compress the path from node2 to root + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + + // compress the path from node to root + k = i; + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + } + } + } + + // Final O(N) pass: enumerate classes + labels.resize(N); + int nclasses = 0; + + for( i = 0; i < N; i++ ) + { + int root = i; + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + // re-use the rank as the class label + if( nodes[root][RANK] >= 0 ) + nodes[root][RANK] = ~nclasses++; + labels[i] = ~nodes[root][RANK]; + } + + return nclasses; +} } // cv diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index e4a232a..d04b65e 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -301,111 +301,4 @@ typedef enum CvStatus } CvStatus; - - -/****************************************************************************************\ -* Auxiliary algorithms * -\****************************************************************************************/ - -namespace cv -{ - -// This function splits the input sequence or set into one or more equivalence classes and -// returns the vector of labels - 0-based class indexes for each element. -// predicate(a,b) returns true if the two sequence elements certainly belong to the same class. -// -// The algorithm is described in "Introduction to Algorithms" -// by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets" -template int -partition( const std::vector<_Tp>& _vec, std::vector& labels, - _EqPredicate predicate=_EqPredicate()) -{ - int i, j, N = (int)_vec.size(); - const _Tp* vec = &_vec[0]; - - const int PARENT=0; - const int RANK=1; - - std::vector _nodes(N*2); - int (*nodes)[2] = (int(*)[2])&_nodes[0]; - - // The first O(N) pass: create N single-vertex trees - for(i = 0; i < N; i++) - { - nodes[i][PARENT]=-1; - nodes[i][RANK] = 0; - } - - // The main O(N^2) pass: merge connected components - for( i = 0; i < N; i++ ) - { - int root = i; - - // find root - while( nodes[root][PARENT] >= 0 ) - root = nodes[root][PARENT]; - - for( j = 0; j < N; j++ ) - { - if( i == j || !predicate(vec[i], vec[j])) - continue; - int root2 = j; - - while( nodes[root2][PARENT] >= 0 ) - root2 = nodes[root2][PARENT]; - - if( root2 != root ) - { - // unite both trees - int rank = nodes[root][RANK], rank2 = nodes[root2][RANK]; - if( rank > rank2 ) - nodes[root2][PARENT] = root; - else - { - nodes[root][PARENT] = root2; - nodes[root2][RANK] += rank == rank2; - root = root2; - } - CV_Assert( nodes[root][PARENT] < 0 ); - - int k = j, parent; - - // compress the path from node2 to root - while( (parent = nodes[k][PARENT]) >= 0 ) - { - nodes[k][PARENT] = root; - k = parent; - } - - // compress the path from node to root - k = i; - while( (parent = nodes[k][PARENT]) >= 0 ) - { - nodes[k][PARENT] = root; - k = parent; - } - } - } - } - - // Final O(N) pass: enumerate classes - labels.resize(N); - int nclasses = 0; - - for( i = 0; i < N; i++ ) - { - int root = i; - while( nodes[root][PARENT] >= 0 ) - root = nodes[root][PARENT]; - // re-use the rank as the class label - if( nodes[root][RANK] >= 0 ) - nodes[root][RANK] = ~nclasses++; - labels[i] = ~nodes[root][RANK]; - } - - return nclasses; -} - -} // namespace cv - #endif // __OPENCV_CORE_PRIVATE_HPP__