| 2640 | } |
| 2641 | |
| 2642 | class KMeansDistanceComputer : public ParallelLoopBody |
| 2643 | { |
| 2644 | public: |
| 2645 | KMeansDistanceComputer( double *_distances, |
| 2646 | int *_labels, |
| 2647 | const Mat& _data, |
| 2648 | const Mat& _centers ) |
| 2649 | : distances(_distances), |
| 2650 | labels(_labels), |
| 2651 | data(_data), |
| 2652 | centers(_centers) |
| 2653 | { |
| 2654 | } |
| 2655 | |
| 2656 | void operator()( const Range& range ) const |
| 2657 | { |
| 2658 | const int begin = range.start; |
| 2659 | const int end = range.end; |
| 2660 | const int K = centers.rows; |
| 2661 | const int dims = centers.cols; |
| 2662 | |
| 2663 | const float *sample; |
| 2664 | for( int i = begin; i<end; ++i) |
| 2665 | { |
| 2666 | sample = data.ptr<float>(i); |
| 2667 | int k_best = 0; |
| 2668 | double min_dist = DBL_MAX; |
| 2669 | |
| 2670 | for( int k = 0; k < K; k++ ) |
| 2671 | { |
| 2672 | const float* center = centers.ptr<float>(k); |
| 2673 | const double dist = normL2Sqr_(sample, center, dims); |
| 2674 | |
| 2675 | if( min_dist > dist ) |
| 2676 | { |
| 2677 | min_dist = dist; |
| 2678 | k_best = k; |
| 2679 | } |
| 2680 | } |
| 2681 | |
| 2682 | distances[i] = min_dist; |
| 2683 | labels[i] = k_best; |
| 2684 | } |
| 2685 | } |
| 2686 | |
| 2687 | private: |
| 2688 | KMeansDistanceComputer& operator=(const KMeansDistanceComputer&); // to quiet MSVC |
| 2689 | |
| 2690 | double *distances; |
| 2691 | int *labels; |
| 2692 | const Mat& data; |
| 2693 | const Mat& centers; |
| 2694 | }; |
| 2695 | |
| 2696 | } |
| 2697 | |