matrix.cpp.patch

patch against the current (17/08/2012) git version. - Boris Mansencal, 2012-08-23 06:41 pm

Download (4.2 kB)

 
b/modules/core/src/matrix.cpp
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 )