2399 |
2399 |
center[j] = ((float)rng*(1.f+margin*2.f)-margin)*(box[j][1] - box[j][0]) + box[j][0];
|
2400 |
2400 |
}
|
2401 |
2401 |
|
|
2402 |
#ifdef HAVE_TBB
|
|
2403 |
|
|
2404 |
class KMeansPPDistanceComputer
|
|
2405 |
{
|
|
2406 |
float *tdist2;
|
|
2407 |
const float *data;
|
|
2408 |
const float *dist;
|
|
2409 |
const int dims;
|
|
2410 |
const int step;
|
|
2411 |
const int stepci;
|
|
2412 |
|
|
2413 |
public:
|
|
2414 |
|
|
2415 |
KMeansPPDistanceComputer(float *_tdist2,
|
|
2416 |
const float *_data,
|
|
2417 |
const float *_dist,
|
|
2418 |
int _dims,
|
|
2419 |
int _step,
|
|
2420 |
int _stepci)
|
|
2421 |
: tdist2(_tdist2),
|
|
2422 |
data(_data),
|
|
2423 |
dist(_dist),
|
|
2424 |
dims(_dims),
|
|
2425 |
step(_step),
|
|
2426 |
stepci(_stepci)
|
|
2427 |
{
|
|
2428 |
|
|
2429 |
}
|
|
2430 |
|
|
2431 |
void operator()(const cv::BlockedRange& range) const
|
|
2432 |
{
|
|
2433 |
|
|
2434 |
const int begin = range.begin();
|
|
2435 |
const int end = range.end();
|
|
2436 |
|
|
2437 |
for (int i=begin; i<end; ++i) {
|
|
2438 |
tdist2[i] = std::min(normL2Sqr_(data + step*i, data + stepci, dims), dist[i]);
|
|
2439 |
}
|
|
2440 |
}
|
|
2441 |
|
|
2442 |
};
|
|
2443 |
|
|
2444 |
#endif //HAVE_TBB
|
2402 |
2445 |
|
2403 |
2446 |
/*
|
2404 |
2447 |
k-means center initialization using the following algorithm:
|
... | ... | |
2436 |
2479 |
if( (p -= dist[i]) <= 0 )
|
2437 |
2480 |
break;
|
2438 |
2481 |
int ci = i;
|
|
2482 |
#ifndef HAVE_TBB
|
2439 |
2483 |
for( i = 0; i < N; i++ )
|
2440 |
2484 |
{
|
2441 |
2485 |
tdist2[i] = std::min(normL2Sqr_(data + step*i, data + step*ci, dims), dist[i]);
|
2442 |
2486 |
s += tdist2[i];
|
2443 |
2487 |
}
|
|
2488 |
#else
|
|
2489 |
cv::parallel_for(cv::BlockedRange(0, N),
|
|
2490 |
KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci));
|
|
2491 |
|
|
2492 |
for( i = 0; i < N; i++ )
|
|
2493 |
{
|
|
2494 |
s += tdist2[i];
|
|
2495 |
}
|
|
2496 |
#endif //HAVE_TBB
|
2444 |
2497 |
|
2445 |
2498 |
if( s < bestSum )
|
2446 |
2499 |
{
|
... | ... | |
2463 |
2516 |
}
|
2464 |
2517 |
}
|
2465 |
2518 |
|
|
2519 |
|
|
2520 |
#ifdef HAVE_TBB
|
|
2521 |
|
|
2522 |
class KMeansDistanceComputer
|
|
2523 |
{
|
|
2524 |
float *distances;
|
|
2525 |
int *labels;
|
|
2526 |
const cv::Mat& data;
|
|
2527 |
const cv::Mat& centers;
|
|
2528 |
|
|
2529 |
public:
|
|
2530 |
|
|
2531 |
KMeansDistanceComputer(float *_distances,
|
|
2532 |
int *_labels,
|
|
2533 |
const cv::Mat& _data,
|
|
2534 |
const cv::Mat& _centers)
|
|
2535 |
: distances(_distances),
|
|
2536 |
labels(_labels),
|
|
2537 |
data(_data),
|
|
2538 |
centers(_centers)
|
|
2539 |
{
|
|
2540 |
CV_DbgAssert(centers.cols == data.cols);
|
|
2541 |
}
|
|
2542 |
|
|
2543 |
void operator()(const cv::BlockedRange& range) const
|
|
2544 |
{
|
|
2545 |
const int begin = range.begin();
|
|
2546 |
const int end = range.end();
|
|
2547 |
const int K = centers.rows;
|
|
2548 |
const int dims = centers.cols;
|
|
2549 |
|
|
2550 |
const float *sample;
|
|
2551 |
for( int i=begin; i<end; ++i)
|
|
2552 |
{
|
|
2553 |
|
|
2554 |
sample = data.ptr<float>(i);
|
|
2555 |
int k_best = 0;
|
|
2556 |
double min_dist = DBL_MAX;
|
|
2557 |
|
|
2558 |
for( int k = 0; k < K; k++ )
|
|
2559 |
{
|
|
2560 |
const float* center = centers.ptr<float>(k);
|
|
2561 |
const double dist = normL2Sqr_(sample, center, dims);
|
|
2562 |
|
|
2563 |
if( min_dist > dist )
|
|
2564 |
{
|
|
2565 |
min_dist = dist;
|
|
2566 |
k_best = k;
|
|
2567 |
}
|
|
2568 |
}
|
|
2569 |
|
|
2570 |
distances[i] = min_dist;
|
|
2571 |
labels[i] = k_best;
|
|
2572 |
}
|
|
2573 |
|
|
2574 |
}
|
|
2575 |
|
|
2576 |
};
|
|
2577 |
|
|
2578 |
#endif //HAVE_TBB
|
|
2579 |
|
2466 |
2580 |
}
|
2467 |
2581 |
|
2468 |
2582 |
double cv::kmeans( InputArray _data, int K,
|
... | ... | |
2508 |
2622 |
vector<Vec2f> _box(dims);
|
2509 |
2623 |
Vec2f* box = &_box[0];
|
2510 |
2624 |
|
|
2625 |
#ifdef HAVE_TBB
|
|
2626 |
cv::Mat dists(N, 1, CV_32F);
|
|
2627 |
#endif //HAVE_TBB
|
|
2628 |
|
2511 |
2629 |
double best_compactness = DBL_MAX, compactness = 0;
|
2512 |
2630 |
RNG& rng = theRNG();
|
2513 |
2631 |
int a, iter, i, j, k;
|
... | ... | |
2682 |
2800 |
break;
|
2683 |
2801 |
|
2684 |
2802 |
// assign labels
|
|
2803 |
#ifndef HAVE_TBB
|
2685 |
2804 |
compactness = 0;
|
2686 |
2805 |
for( i = 0; i < N; i++ )
|
2687 |
2806 |
{
|
... | ... | |
2704 |
2823 |
compactness += min_dist;
|
2705 |
2824 |
labels[i] = k_best;
|
2706 |
2825 |
}
|
|
2826 |
#else
|
|
2827 |
float* dist = dists.ptr<float>(0);
|
|
2828 |
cv::parallel_for(cv::BlockedRange(0, N),
|
|
2829 |
KMeansDistanceComputer(dist, labels, data, centers));
|
|
2830 |
compactness = 0;
|
|
2831 |
for( i = 0; i < N; i++ )
|
|
2832 |
{
|
|
2833 |
compactness += dist[i];
|
|
2834 |
}
|
|
2835 |
|
|
2836 |
#endif //HAVE_TBB
|
2707 |
2837 |
}
|
2708 |
2838 |
|
2709 |
2839 |
if( compactness < best_compactness )
|