diff --git a/modules/flann/include/opencv2/flann/kmeans_index.h b/modules/flann/include/opencv2/flann/kmeans_index.h index 74bbf400c3..fe91dddd16 100644 --- a/modules/flann/include/opencv2/flann/kmeans_index.h +++ b/modules/flann/include/opencv2/flann/kmeans_index.h @@ -276,17 +276,15 @@ public: public: KMeansDistanceComputer(Distance _distance, const Matrix& _dataset, const int _branching, const int* _indices, const Matrix& _dcenters, const size_t _veclen, - int* _count, int* _belongs_to, std::vector& _radiuses, bool& _converged) + std::vector &_new_centroids, std::vector &_sq_dists) : distance(_distance) , dataset(_dataset) , branching(_branching) , indices(_indices) , dcenters(_dcenters) , veclen(_veclen) - , count(_count) - , belongs_to(_belongs_to) - , radiuses(_radiuses) - , converged(_converged) + , new_centroids(_new_centroids) + , sq_dists(_sq_dists) { } @@ -297,8 +295,8 @@ public: for( int i = begin; inew_sq_dist) { @@ -306,15 +304,8 @@ public: sq_dist = new_sq_dist; } } - if (sq_dist > radiuses[new_centroid]) { - radiuses[new_centroid] = sq_dist; - } - if (new_centroid != belongs_to[i]) { - CV_XADD(&count[belongs_to[i]], -1); - CV_XADD(&count[new_centroid], 1); - belongs_to[i] = new_centroid; - converged = false; - } + sq_dists[i] = sq_dist; + new_centroids[i] = new_centroid; } } @@ -325,10 +316,8 @@ public: const int* indices; const Matrix& dcenters; const size_t veclen; - int* count; - int* belongs_to; - std::vector& radiuses; - bool& converged; + std::vector &new_centroids; + std::vector &sq_dists; KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; } }; @@ -796,10 +785,27 @@ private: } } + std::vector new_centroids(indices_length); + std::vector sq_dists(indices_length); + // reassign points to clusters - KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, count, belongs_to, radiuses, converged); + KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, new_centroids, sq_dists); parallel_for_(cv::Range(0, (int)indices_length), invoker); + for (int i=0; i < (int)indices_length; ++i) { + DistanceType sq_dist(sq_dists[i]); + int new_centroid(new_centroids[i]); + if (sq_dist > radiuses[new_centroid]) { + radiuses[new_centroid] = sq_dist; + } + if (new_centroid != belongs_to[i]) { + count[belongs_to[i]]--; + count[new_centroid]++; + belongs_to[i] = new_centroid; + converged = false; + } + } + for (int i=0; i