Merge pull request #8940 from 678098:nonblocking_haar_detector_parallel_for

This commit is contained in:
Vadim Pisarevsky 2017-10-10 13:51:39 +00:00
commit 3562a05d90

View File

@ -931,6 +931,8 @@ cvRunHaarClassifierCascade( const CvHaarClassifierCascade* _cascade,
namespace cv namespace cv
{ {
const size_t PARALLEL_LOOP_BATCH_SIZE = 100;
class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
{ {
public: public:
@ -969,6 +971,10 @@ public:
Size ssz(sum1.cols - 1 - winSize0.width, y2 - y1); Size ssz(sum1.cols - 1 - winSize0.width, y2 - y1);
int x, y, ystep = factor > 2 ? 1 : 2; int x, y, ystep = factor > 2 ? 1 : 2;
std::vector<Rect> vecLocal;
std::vector<int> rejectLevelsLocal;
std::vector<double> levelWeightsLocal;
#ifdef HAVE_IPP #ifdef HAVE_IPP
if(CV_IPP_CHECK_COND && cascade->hid_cascade->ipp_stages ) if(CV_IPP_CHECK_COND && cascade->hid_cascade->ipp_stages )
{ {
@ -1015,10 +1021,17 @@ public:
for( x = 0; x < ssz.width; x += ystep ) for( x = 0; x < ssz.width; x += ystep )
if( mask1row[x] != 0 ) if( mask1row[x] != 0 )
{ {
mtx->lock(); vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
winSize.width, winSize.height)); winSize.width, winSize.height));
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
mtx->unlock(); mtx->unlock();
vecLocal.clear();
}
if( --positive == 0 ) if( --positive == 0 )
break; break;
} }
@ -1039,24 +1052,58 @@ public:
result = -1*cascade->count; result = -1*cascade->count;
if( cascade->count + result < 4 ) if( cascade->count + result < 4 )
{ {
mtx->lock(); vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
winSize.width, winSize.height)); winSize.width, winSize.height));
rejectLevels->push_back(-result); rejectLevelsLocal.push_back(-result);
levelWeights->push_back(gypWeight); levelWeightsLocal.push_back(gypWeight);
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
mtx->unlock(); mtx->unlock();
vecLocal.clear();
rejectLevelsLocal.clear();
levelWeightsLocal.clear();
}
} }
} }
else else
{ {
if( result > 0 ) if( result > 0 )
{ {
mtx->lock(); vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
winSize.width, winSize.height)); winSize.width, winSize.height));
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
mtx->unlock();
vecLocal.clear();
}
}
}
}
if (rejectLevelsLocal.size())
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
mtx->unlock(); mtx->unlock();
} }
} else
if (vecLocal.size())
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
mtx->unlock();
} }
} }
@ -1100,6 +1147,8 @@ public:
bool doCannyPruning = p0 != 0; bool doCannyPruning = p0 != 0;
int sstep = (int)(sumstep/sizeof(p0[0])); int sstep = (int)(sumstep/sizeof(p0[0]));
std::vector<Rect> vecLocal;
for( iy = startY; iy < endY; iy++ ) for( iy = startY; iy < endY; iy++ )
{ {
int ix, y = cvRound(iy*ystep), ixstep = 1; int ix, y = cvRound(iy*ystep), ixstep = 1;
@ -1121,14 +1170,28 @@ public:
int result = cvRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 ); int result = cvRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 );
if( result > 0 ) if( result > 0 )
{
vecLocal.push_back(Rect(x, y, winsize.width, winsize.height));
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
{ {
mtx->lock(); mtx->lock();
vec->push_back(Rect(x, y, winsize.width, winsize.height)); vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
mtx->unlock(); mtx->unlock();
vecLocal.clear();
}
} }
ixstep = result != 0 ? 1 : 2; ixstep = result != 0 ? 1 : 2;
} }
} }
if (vecLocal.size())
{
mtx->lock();
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
mtx->unlock();
}
} }
const CvHaarClassifierCascade* cascade; const CvHaarClassifierCascade* cascade;