#endif
}
-struct CascadeClassifierInvoker
+class CascadeClassifierInvoker : public ParallelLoopBody
{
+public:
CascadeClassifierInvoker( CascadeClassifier& _cc, Size _sz1, int _stripSize, int _yStep, double _factor,
- ConcurrentRectVector& _vec, vector<int>& _levels, vector<double>& _weights, bool outputLevels, const Mat& _mask)
+ vector<Rect>& _vec, vector<int>& _levels, vector<double>& _weights, bool outputLevels, const Mat& _mask, Mutex* _mtx)
{
classifier = &_cc;
processingRectSize = _sz1;
yStep = _yStep;
scalingFactor = _factor;
rectangles = &_vec;
- rejectLevels = outputLevels ? &_levels : 0;
- levelWeights = outputLevels ? &_weights : 0;
- mask=_mask;
+ rejectLevels = outputLevels ? &_levels : 0;
+ levelWeights = outputLevels ? &_weights : 0;
+ mask = _mask;
+ mtx = _mtx;
}
- void operator()(const BlockedRange& range) const
+ void operator()(const Range& range) const
{
Ptr<FeatureEvaluator> evaluator = classifier->featureEvaluator->clone();
Size winSize(cvRound(classifier->data.origWinSize.width * scalingFactor), cvRound(classifier->data.origWinSize.height * scalingFactor));
- int y1 = range.begin() * stripSize;
- int y2 = min(range.end() * stripSize, processingRectSize.height);
+ int y1 = range.start * stripSize;
+ int y2 = min(range.end * stripSize, processingRectSize.height);
for( int y = y1; y < y2; y += yStep )
{
for( int x = 0; x < processingRectSize.width; x += yStep )
result = -(int)classifier->data.stages.size();
if( classifier->data.stages.size() + result < 4 )
{
+ mtx->lock();
rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor), winSize.width, winSize.height));
+ mtx->unlock();
rejectLevels->push_back(-result);
levelWeights->push_back(gypWeight);
}
}
else if( result > 0 )
+ {
+ mtx->lock();
rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor),
winSize.width, winSize.height));
+ mtx->unlock();
+ }
if( result == 0 )
x += yStep;
}
}
CascadeClassifier* classifier;
- ConcurrentRectVector* rectangles;
+ vector<Rect>* rectangles;
Size processingRectSize;
int stripSize, yStep;
double scalingFactor;
vector<int> *rejectLevels;
vector<double> *levelWeights;
Mat mask;
+ Mutex* mtx;
};
struct getRect { Rect operator ()(const CvAvgComp& e) const { return e.rect; } };
currentMask=maskGenerator->generateMask(image);
}
- ConcurrentRectVector concurrentCandidates;
+ vector<Rect> candidatesVector;
vector<int> rejectLevels;
vector<double> levelWeights;
+ Mutex mtx;
if( outputRejectLevels )
{
- parallel_for(BlockedRange(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,
- concurrentCandidates, rejectLevels, levelWeights, true, currentMask));
+ parallel_for_(Range(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,
+ candidatesVector, rejectLevels, levelWeights, true, currentMask, &mtx));
levels.insert( levels.end(), rejectLevels.begin(), rejectLevels.end() );
weights.insert( weights.end(), levelWeights.begin(), levelWeights.end() );
}
else
{
- parallel_for(BlockedRange(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,
- concurrentCandidates, rejectLevels, levelWeights, false, currentMask));
+ parallel_for_(Range(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,
+ candidatesVector, rejectLevels, levelWeights, false, currentMask, &mtx));
}
- candidates.insert( candidates.end(), concurrentCandidates.begin(), concurrentCandidates.end() );
+ candidates.insert( candidates.end(), candidatesVector.begin(), candidatesVector.end() );
#if defined (LOG_CASCADE_STATISTIC)
logger.write();
detect(img, hits, weightsV, hitThreshold, winStride, padding, locations);
}
-struct HOGInvoker
+class HOGInvoker : public ParallelLoopBody
{
+public:
HOGInvoker( const HOGDescriptor* _hog, const Mat& _img,
double _hitThreshold, Size _winStride, Size _padding,
- const double* _levelScale, ConcurrentRectVector* _vec,
- ConcurrentDoubleVector* _weights=0, ConcurrentDoubleVector* _scales=0 )
+ const double* _levelScale, std::vector<Rect> * _vec, Mutex* _mtx,
+ std::vector<double>* _weights=0, std::vector<double>* _scales=0 )
{
hog = _hog;
img = _img;
vec = _vec;
weights = _weights;
scales = _scales;
+ mtx = _mtx;
}
- void operator()( const BlockedRange& range ) const
+ void operator()( const Range& range ) const
{
- int i, i1 = range.begin(), i2 = range.end();
+ int i, i1 = range.start, i2 = range.end;
double minScale = i1 > 0 ? levelScale[i1] : i2 > 1 ? levelScale[i1+1] : std::max(img.cols, img.rows);
Size maxSz(cvCeil(img.cols/minScale), cvCeil(img.rows/minScale));
Mat smallerImgBuf(maxSz, img.type());
resize(img, smallerImg, sz);
hog->detect(smallerImg, locations, hitsWeights, hitThreshold, winStride, padding);
Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));
+
+ mtx->lock();
for( size_t j = 0; j < locations.size(); j++ )
{
vec->push_back(Rect(cvRound(locations[j].x*scale),
cvRound(locations[j].y*scale),
scaledWinSize.width, scaledWinSize.height));
- if (scales) {
+ if (scales)
+ {
scales->push_back(scale);
}
}
-
+ mtx->unlock();
+
if (weights && (!hitsWeights.empty()))
{
+ mtx->lock();
for (size_t j = 0; j < locations.size(); j++)
{
weights->push_back(hitsWeights[j]);
}
- }
+ mtx->unlock();
+ }
}
}
Size winStride;
Size padding;
const double* levelScale;
- ConcurrentRectVector* vec;
- ConcurrentDoubleVector* weights;
- ConcurrentDoubleVector* scales;
+ std::vector<Rect>* vec;
+ std::vector<double>* weights;
+ std::vector<double>* scales;
+ Mutex* mtx;
};
levels = std::max(levels, 1);
levelScale.resize(levels);
- ConcurrentRectVector allCandidates;
- ConcurrentDoubleVector tempScales;
- ConcurrentDoubleVector tempWeights;
- vector<double> foundScales;
-
- parallel_for(BlockedRange(0, (int)levelScale.size()),
- HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &tempWeights, &tempScales));
+ std::vector<Rect> allCandidates;
+ std::vector<double> tempScales;
+ std::vector<double> tempWeights;
+ std::vector<double> foundScales;
+ Mutex mtx;
+
+ parallel_for_(Range(0, (int)levelScale.size()),
+ HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &mtx, &tempWeights, &tempScales));
std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales));
foundLocations.clear();
return vector<float>(detector, detector + sizeof(detector)/sizeof(detector[0]));
}
-struct HOGConfInvoker
+class HOGConfInvoker : public ParallelLoopBody
{
+public:
HOGConfInvoker( const HOGDescriptor* _hog, const Mat& _img,
double _hitThreshold, Size _padding,
std::vector<DetectionROI>* locs,
- ConcurrentRectVector* _vec )
+ std::vector<Rect>* _vec, Mutex* _mtx )
{
hog = _hog;
img = _img;
padding = _padding;
locations = locs;
vec = _vec;
+ mtx = _mtx;
}
- void operator()( const BlockedRange& range ) const
+ void operator()( const Range& range ) const
{
- int i, i1 = range.begin(), i2 = range.end();
+ int i, i1 = range.start, i2 = range.end;
Size maxSz(cvCeil(img.cols/(*locations)[0].scale), cvCeil(img.rows/(*locations)[0].scale));
Mat smallerImgBuf(maxSz, img.type());
hog->detectROI(smallerImg, (*locations)[i].locations, dets, (*locations)[i].confidences, hitThreshold, Size(), padding);
Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));
+ mtx->lock();
for( size_t j = 0; j < dets.size(); j++ )
+ {
vec->push_back(Rect(cvRound(dets[j].x*scale),
cvRound(dets[j].y*scale),
scaledWinSize.width, scaledWinSize.height));
+ }
+ mtx->unlock();
}
}
double hitThreshold;
std::vector<DetectionROI>* locations;
Size padding;
- ConcurrentRectVector* vec;
+ std::vector<Rect>* vec;
+ Mutex* mtx;
};
void HOGDescriptor::detectROI(const cv::Mat& img, const vector<cv::Point> &locations,
double hitThreshold,
int groupThreshold) const
{
- ConcurrentRectVector allCandidates;
+ std::vector<Rect> allCandidates;
+ Mutex mtx;
- parallel_for(BlockedRange(0, (int)locations.size()),
- HOGConfInvoker(this, img, hitThreshold, Size(8, 8), &locations, &allCandidates));
+ parallel_for_(Range(0, (int)locations.size()),
+ HOGConfInvoker(this, img, hitThreshold, Size(8, 8), &locations, &allCandidates, &mtx));
foundLocations.resize(allCandidates.size());
std::copy(allCandidates.begin(), allCandidates.end(), foundLocations.begin());