TBB version of GridAdaptedFeatureDetector

pull/35/head
Andrey Kamaev 12 years ago
parent 8d07e92b2c
commit 9218bdcbb4
  1. 79
      modules/features2d/src/detectors.cpp

@ -213,25 +213,54 @@ static void keepStrongest( int N, vector<KeyPoint>& keypoints )
} }
} }
void GridAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const namespace {
class GridAdaptedFeatureDetectorInvoker
{ {
keypoints.reserve(maxTotalKeypoints); private:
int gridRows_, gridCols_;
int maxPerCell_;
vector<KeyPoint>& keypoints_;
const Mat& image_;
const Mat& mask_;
const Ptr<FeatureDetector>& detector_;
#ifdef HAVE_TBB
tbb::mutex* kptLock_;
#endif
public:
GridAdaptedFeatureDetectorInvoker(const Ptr<FeatureDetector>& detector, const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints, int maxPerCell, int gridRows, int gridCols
#ifdef HAVE_TBB
, tbb::mutex* kptLock
#endif
) : gridRows_(gridRows), gridCols_(gridCols), maxPerCell_(maxPerCell),
keypoints_(keypoints), image_(image), mask_(mask), detector_(detector)
#ifdef HAVE_TBB
, kptLock_(kptLock)
#endif
{
}
int maxPerCell = maxTotalKeypoints / (gridRows * gridCols); void operator() (const BlockedRange& range) const
for( int i = 0; i < gridRows; ++i )
{ {
Range row_range((i*image.rows)/gridRows, ((i+1)*image.rows)/gridRows); for (int i = range.begin(); i < range.end(); ++i)
for( int j = 0; j < gridCols; ++j )
{ {
Range col_range((j*image.cols)/gridCols, ((j+1)*image.cols)/gridCols); int celly = i / gridCols_;
Mat sub_image = image(row_range, col_range); int cellx = i - celly * gridCols_;
Range row_range((celly*image_.rows)/gridRows_, ((celly+1)*image_.rows)/gridRows_);
Range col_range((cellx*image_.cols)/gridCols_, ((cellx+1)*image_.cols)/gridCols_);
Mat sub_image = image_(row_range, col_range);
Mat sub_mask; Mat sub_mask;
if( !mask.empty() ) if (!mask_.empty()) sub_mask = mask_(row_range, col_range);
sub_mask = mask(row_range, col_range);
vector<KeyPoint> sub_keypoints; vector<KeyPoint> sub_keypoints;
detector->detect( sub_image, sub_keypoints, sub_mask ); sub_keypoints.reserve(maxPerCell_);
keepStrongest( maxPerCell, sub_keypoints );
detector_->detect( sub_image, sub_keypoints, sub_mask );
keepStrongest( maxPerCell_, sub_keypoints );
std::vector<cv::KeyPoint>::iterator it = sub_keypoints.begin(), std::vector<cv::KeyPoint>::iterator it = sub_keypoints.begin(),
end = sub_keypoints.end(); end = sub_keypoints.end();
for( ; it != end; ++it ) for( ; it != end; ++it )
@ -239,10 +268,32 @@ void GridAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>&
it->pt.x += col_range.start; it->pt.x += col_range.start;
it->pt.y += row_range.start; it->pt.y += row_range.start;
} }
#ifdef HAVE_TBB
keypoints.insert( keypoints.end(), sub_keypoints.begin(), sub_keypoints.end() ); tbb::mutex::scoped_lock join_keypoints(*kptLock_);
#endif
keypoints_.insert( keypoints_.end(), sub_keypoints.begin(), sub_keypoints.end() );
} }
} }
};
} // namepace
void GridAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const
{
if (image.empty() || maxTotalKeypoints < gridRows * gridCols)
{
keypoints.clear();
return;
}
keypoints.reserve(maxTotalKeypoints);
int maxPerCell = maxTotalKeypoints / (gridRows * gridCols);
#ifdef HAVE_TBB
tbb::mutex kptLock;
cv::parallel_for(cv::BlockedRange(0, gridRows * gridCols),
GridAdaptedFeatureDetectorInvoker(detector, image, mask, keypoints, maxPerCell, gridRows, gridCols, &kptLock));
#else
GridAdaptedFeatureDetectorInvoker(detector, image, mask, keypoints, maxPerCell, gridRows, gridCols)(cv::BlockedRange(0, gridRows * gridCols));
#endif
} }
/* /*

Loading…
Cancel
Save