Changed parallel_for to parallel_for_ in hog.cpp and cascadedetect.cpp
authorEvgeny Talanin <evgeny.talanin@itseez.com>
Tue, 25 Sep 2012 08:18:33 +0000 (12:18 +0400)
committerEvgeny Talanin <evgeny.talanin@itseez.com>
Tue, 25 Sep 2012 08:18:33 +0000 (12:18 +0400)
modules/objdetect/src/cascadedetect.cpp
modules/objdetect/src/hog.cpp

index 1edf49d..8d4ef69 100644 (file)
@@ -943,10 +943,11 @@ void CascadeClassifier::setFaceDetectionMaskGenerator()
 #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;
@@ -954,19 +955,20 @@ struct CascadeClassifierInvoker
         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 )
@@ -988,14 +990,20 @@ struct CascadeClassifierInvoker
                         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;
             }
@@ -1003,13 +1011,14 @@ struct CascadeClassifierInvoker
     }
 
     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; } };
@@ -1031,22 +1040,23 @@ bool CascadeClassifier::detectSingleScale( const Mat& image, int stripCount, Siz
         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();
index 21bda24..b39f21c 100644 (file)
@@ -939,12 +939,13 @@ void HOGDescriptor::detect(const Mat& img, vector<Point>& hits, double hitThresh
     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;
@@ -955,11 +956,12 @@ struct HOGInvoker
         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());
@@ -977,23 +979,29 @@ struct HOGInvoker
                 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();
+            }
         }
     }
 
@@ -1003,9 +1011,10 @@ struct HOGInvoker
     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;
 };
 
 
@@ -1030,13 +1039,14 @@ void HOGDescriptor::detectMultiScale(
     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();
@@ -2382,12 +2392,13 @@ vector<float> HOGDescriptor::getDaimlerPeopleDetector()
         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;
@@ -2395,11 +2406,12 @@ struct HOGConfInvoker
                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());
@@ -2419,10 +2431,14 @@ struct HOGConfInvoker
 
                        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();
                }
        }
 
@@ -2431,7 +2447,8 @@ struct HOGConfInvoker
        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,
@@ -2516,10 +2533,11 @@ void HOGDescriptor::detectMultiScaleROI(const cv::Mat& img,
                                                            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());