Skip to content

Commit d0ab595

Browse files
author
678098
committed
batch-oriented mutex locking in parallel haar detect loop body
1 parent 3ea02e4 commit d0ab595

File tree

1 file changed

+80
-17
lines changed

1 file changed

+80
-17
lines changed

modules/objdetect/src/haar.cpp

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,8 @@ cvRunHaarClassifierCascade( const CvHaarClassifierCascade* _cascade,
12811281
namespace cv
12821282
{
12831283

1284+
const size_t PARALLEL_LOOP_BATCH_SIZE = 100;
1285+
12841286
class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
12851287
{
12861288
public:
@@ -1319,6 +1321,10 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
13191321
Size ssz(sum1.cols - 1 - winSize0.width, y2 - y1);
13201322
int x, y, ystep = factor > 2 ? 1 : 2;
13211323

1324+
std::vector<Rect> vecLocal;
1325+
std::vector<int> rejectLevelsLocal;
1326+
std::vector<double> levelWeightsLocal;
1327+
13221328
#ifdef HAVE_IPP
13231329
if(CV_IPP_CHECK_COND && cascade->hid_cascade->ipp_stages )
13241330
{
@@ -1365,10 +1371,17 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
13651371
for( x = 0; x < ssz.width; x += ystep )
13661372
if( mask1row[x] != 0 )
13671373
{
1368-
mtx->lock();
1369-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1370-
winSize.width, winSize.height));
1371-
mtx->unlock();
1374+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1375+
winSize.width, winSize.height));
1376+
1377+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1378+
{
1379+
mtx->lock();
1380+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1381+
mtx->unlock();
1382+
1383+
vecLocal.clear();
1384+
}
13721385
if( --positive == 0 )
13731386
break;
13741387
}
@@ -1389,25 +1402,59 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
13891402
result = -1*cascade->count;
13901403
if( cascade->count + result < 4 )
13911404
{
1392-
mtx->lock();
1393-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1394-
winSize.width, winSize.height));
1395-
rejectLevels->push_back(-result);
1396-
levelWeights->push_back(gypWeight);
1397-
mtx->unlock();
1405+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1406+
winSize.width, winSize.height));
1407+
rejectLevelsLocal.push_back(-result);
1408+
levelWeightsLocal.push_back(gypWeight);
1409+
1410+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1411+
{
1412+
mtx->lock();
1413+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1414+
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
1415+
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
1416+
mtx->unlock();
1417+
1418+
vecLocal.clear();
1419+
rejectLevelsLocal.clear();
1420+
levelWeightsLocal.clear();
1421+
}
13981422
}
13991423
}
14001424
else
14011425
{
14021426
if( result > 0 )
14031427
{
1404-
mtx->lock();
1405-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1406-
winSize.width, winSize.height));
1407-
mtx->unlock();
1428+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1429+
winSize.width, winSize.height));
1430+
1431+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1432+
{
1433+
mtx->lock();
1434+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1435+
mtx->unlock();
1436+
1437+
vecLocal.clear();
1438+
}
14081439
}
14091440
}
14101441
}
1442+
1443+
if (rejectLevelsLocal.size())
1444+
{
1445+
mtx->lock();
1446+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1447+
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
1448+
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
1449+
mtx->unlock();
1450+
}
1451+
else
1452+
if (vecLocal.size())
1453+
{
1454+
mtx->lock();
1455+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1456+
mtx->unlock();
1457+
}
14111458
}
14121459

14131460
const CvHaarClassifierCascade* cascade;
@@ -1450,6 +1497,8 @@ class HaarDetectObjects_ScaleCascade_Invoker : public ParallelLoopBody
14501497
bool doCannyPruning = p0 != 0;
14511498
int sstep = (int)(sumstep/sizeof(p0[0]));
14521499

1500+
std::vector<Rect> vecLocal;
1501+
14531502
for( iy = startY; iy < endY; iy++ )
14541503
{
14551504
int ix, y = cvRound(iy*ystep), ixstep = 1;
@@ -1472,13 +1521,27 @@ class HaarDetectObjects_ScaleCascade_Invoker : public ParallelLoopBody
14721521
int result = cvRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 );
14731522
if( result > 0 )
14741523
{
1475-
mtx->lock();
1476-
vec->push_back(Rect(x, y, winsize.width, winsize.height));
1477-
mtx->unlock();
1524+
vecLocal.push_back(Rect(x, y, winsize.width, winsize.height));
1525+
1526+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1527+
{
1528+
mtx->lock();
1529+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1530+
mtx->unlock();
1531+
1532+
vecLocal.clear();
1533+
}
14781534
}
14791535
ixstep = result != 0 ? 1 : 2;
14801536
}
14811537
}
1538+
1539+
if (vecLocal.size())
1540+
{
1541+
mtx->lock();
1542+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1543+
mtx->unlock();
1544+
}
14821545
}
14831546

14841547
const CvHaarClassifierCascade* cascade;

0 commit comments

Comments
 (0)