Index: modules/core/src/matrix.cpp =================================================================== --- modules/core/src/matrix.cpp (revision 6258) +++ modules/core/src/matrix.cpp (working copy) @@ -2259,6 +2259,66 @@ } } +#ifdef HAVE_TBB + +class KMeansDistanceComputer +{ + float *distances; + int *labels; + const cv::Mat& data; + const cv::Mat& centers; + +public: + + KMeansDistanceComputer(float *_distances, + int *_labels, + const cv::Mat& _data, + const cv::Mat& _centers) + : distances(_distances), + labels(_labels), + data(_data), + centers(_centers) + { + CV_DbgAssert(centers.cols == data.cols); + } + + void operator()(const cv::BlockedRange& range) const + { + const int begin = range.begin(); + const int end = range.end(); + const int K = centers.rows; + const int dims = centers.cols; + + const float *sample; + for( int i=begin; i(i); + int k_best = 0; + double min_dist = DBL_MAX; + + for( int k = 0; k < K; k++ ) + { + const float* center = centers.ptr(k); + const double dist = distance(sample, center, dims); + + if( min_dist > dist ) + { + min_dist = dist; + k_best = k; + } + } + + distances[i] = min_dist; + labels[i] = k_best; + } + + } + +}; + +#endif //HAVE_TBB + } double cv::kmeans( InputArray _data, int K, @@ -2338,6 +2398,10 @@ } } +#ifdef HAVE_TBB + cv::Mat dists(N, 1, CV_32F); +#endif //HAVE_TBB + for( a = 0; a < attempts; a++ ) { double max_center_shift = DBL_MAX; @@ -2422,6 +2486,7 @@ } // assign labels +#ifndef HAVE_TBB compactness = 0; for( i = 0; i < N; i++ ) { @@ -2444,6 +2509,17 @@ compactness += min_dist; labels[i] = k_best; } +#else + float* dist = dists.ptr(0); + cv::parallel_for(cv::BlockedRange(0, N), + KMeansDistanceComputer(dist, labels, data, centers)); + compactness = 0; + for( i = 0; i < N; i++ ) + { + compactness += dist[i]; + } + +#endif //HAVE_TBB } if( compactness < best_compactness )