Skip to content

Commit 3562a05

Browse files
committed
Merge pull request opencv#8940 from 678098:nonblocking_haar_detector_parallel_for
2 parents b7ff9dd + d0ab595 commit 3562a05

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
@@ -931,6 +931,8 @@ cvRunHaarClassifierCascade( const CvHaarClassifierCascade* _cascade,
931931
namespace cv
932932
{
933933

934+
const size_t PARALLEL_LOOP_BATCH_SIZE = 100;
935+
934936
class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
935937
{
936938
public:
@@ -969,6 +971,10 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
969971
Size ssz(sum1.cols - 1 - winSize0.width, y2 - y1);
970972
int x, y, ystep = factor > 2 ? 1 : 2;
971973

974+
std::vector<Rect> vecLocal;
975+
std::vector<int> rejectLevelsLocal;
976+
std::vector<double> levelWeightsLocal;
977+
972978
#ifdef HAVE_IPP
973979
if(CV_IPP_CHECK_COND && cascade->hid_cascade->ipp_stages )
974980
{
@@ -1015,10 +1021,17 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
10151021
for( x = 0; x < ssz.width; x += ystep )
10161022
if( mask1row[x] != 0 )
10171023
{
1018-
mtx->lock();
1019-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1020-
winSize.width, winSize.height));
1021-
mtx->unlock();
1024+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1025+
winSize.width, winSize.height));
1026+
1027+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1028+
{
1029+
mtx->lock();
1030+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1031+
mtx->unlock();
1032+
1033+
vecLocal.clear();
1034+
}
10221035
if( --positive == 0 )
10231036
break;
10241037
}
@@ -1039,25 +1052,59 @@ class HaarDetectObjects_ScaleImage_Invoker : public ParallelLoopBody
10391052
result = -1*cascade->count;
10401053
if( cascade->count + result < 4 )
10411054
{
1042-
mtx->lock();
1043-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1044-
winSize.width, winSize.height));
1045-
rejectLevels->push_back(-result);
1046-
levelWeights->push_back(gypWeight);
1047-
mtx->unlock();
1055+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1056+
winSize.width, winSize.height));
1057+
rejectLevelsLocal.push_back(-result);
1058+
levelWeightsLocal.push_back(gypWeight);
1059+
1060+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1061+
{
1062+
mtx->lock();
1063+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1064+
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
1065+
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
1066+
mtx->unlock();
1067+
1068+
vecLocal.clear();
1069+
rejectLevelsLocal.clear();
1070+
levelWeightsLocal.clear();
1071+
}
10481072
}
10491073
}
10501074
else
10511075
{
10521076
if( result > 0 )
10531077
{
1054-
mtx->lock();
1055-
vec->push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1056-
winSize.width, winSize.height));
1057-
mtx->unlock();
1078+
vecLocal.push_back(Rect(cvRound(x*factor), cvRound(y*factor),
1079+
winSize.width, winSize.height));
1080+
1081+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1082+
{
1083+
mtx->lock();
1084+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1085+
mtx->unlock();
1086+
1087+
vecLocal.clear();
1088+
}
10581089
}
10591090
}
10601091
}
1092+
1093+
if (rejectLevelsLocal.size())
1094+
{
1095+
mtx->lock();
1096+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1097+
rejectLevels->insert(rejectLevels->end(), rejectLevelsLocal.begin(), rejectLevelsLocal.end());
1098+
levelWeights->insert(levelWeights->end(), levelWeightsLocal.begin(), levelWeightsLocal.end());
1099+
mtx->unlock();
1100+
}
1101+
else
1102+
if (vecLocal.size())
1103+
{
1104+
mtx->lock();
1105+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1106+
mtx->unlock();
1107+
}
10611108
}
10621109

10631110
const CvHaarClassifierCascade* cascade;
@@ -1100,6 +1147,8 @@ class HaarDetectObjects_ScaleCascade_Invoker : public ParallelLoopBody
11001147
bool doCannyPruning = p0 != 0;
11011148
int sstep = (int)(sumstep/sizeof(p0[0]));
11021149

1150+
std::vector<Rect> vecLocal;
1151+
11031152
for( iy = startY; iy < endY; iy++ )
11041153
{
11051154
int ix, y = cvRound(iy*ystep), ixstep = 1;
@@ -1122,13 +1171,27 @@ class HaarDetectObjects_ScaleCascade_Invoker : public ParallelLoopBody
11221171
int result = cvRunHaarClassifierCascade( cascade, cvPoint(x, y), 0 );
11231172
if( result > 0 )
11241173
{
1125-
mtx->lock();
1126-
vec->push_back(Rect(x, y, winsize.width, winsize.height));
1127-
mtx->unlock();
1174+
vecLocal.push_back(Rect(x, y, winsize.width, winsize.height));
1175+
1176+
if (vecLocal.size() >= PARALLEL_LOOP_BATCH_SIZE)
1177+
{
1178+
mtx->lock();
1179+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1180+
mtx->unlock();
1181+
1182+
vecLocal.clear();
1183+
}
11281184
}
11291185
ixstep = result != 0 ? 1 : 2;
11301186
}
11311187
}
1188+
1189+
if (vecLocal.size())
1190+
{
1191+
mtx->lock();
1192+
vec->insert(vec->end(), vecLocal.begin(), vecLocal.end());
1193+
mtx->unlock();
1194+
}
11321195
}
11331196

11341197
const CvHaarClassifierCascade* cascade;

0 commit comments

Comments
 (0)