a bit refactored soft cascade
authormarina.kolpakova <marina.kolpakova@itseez.com>
Mon, 24 Dec 2012 04:15:12 +0000 (08:15 +0400)
committermarina.kolpakova <marina.kolpakova@itseez.com>
Fri, 18 Jan 2013 11:58:47 +0000 (15:58 +0400)
modules/objdetect/src/softcascade.cpp

index f67bd4d..73ae9f9 100644 (file)
@@ -223,7 +223,7 @@ struct cv::SCascade::Fields
     int shrinkage;
 
     std::vector<Octave>  octaves;
-    std::vector<Weak>    stages;
+    std::vector<Weak>    weaks;
     std::vector<Node>    nodes;
     std::vector<float>   leaves;
     std::vector<Feature> features;
@@ -233,47 +233,46 @@ struct cv::SCascade::Fields
     cv::Size frameSize;
 
     typedef std::vector<Octave>::iterator  octIt_t;
+    typedef std::vector<Detection> dvector;
 
-    void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage,
-        std::vector<Detection>& detections) const
+    void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, dvector& detections) const
     {
         float detectionScore = 0.f;
 
         const Octave& octave = *(level.octave);
 
-        int stBegin = octave.index * octave.weaks, stEnd = stBegin + ((octave.index)? 1024 : 416);
+        int stBegin = octave.index * octave.weaks, stEnd = stBegin + octave.weaks;
 
-        int st = stBegin;
-        int offset = (octave.index)? -2: 0;
-        for(; st < stEnd; ++st)
+        for(int st = stBegin; st < stEnd; ++st)
         {
-            const Weak& stage = stages[st];
-            {
-                int nId = st * 3 + offset;
+            const Weak& weak = weaks[st];
 
-                // work with root node
-                const Node& node = nodes[nId];
-                const Feature& feature = features[node.feature + offset];
-                cv::Rect scaledRect(feature.rect);
+            int nId = st * 3;
 
-                float threshold = level.rescale(scaledRect, node.threshold,(int)(feature.channel > 6)) * feature.rarea;
-                float sum = storage.get(feature.channel, scaledRect);
-                int next = (sum >= threshold)? 2 : 1;
+            // work with root node
+            const Node& node = nodes[nId];
+            const Feature& feature = features[node.feature];
 
-                // leaves
-                const Node& leaf = nodes[nId + next];
-                const Feature& fLeaf = features[leaf.feature + offset];
+            cv::Rect scaledRect(feature.rect);
 
-                scaledRect = fLeaf.rect;
-                threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea;
-                sum = storage.get(fLeaf.channel, scaledRect);
+            float threshold = level.rescale(scaledRect, node.threshold, (int)(feature.channel > 6)) * feature.rarea;
+            float sum = storage.get(feature.channel, scaledRect);
+            int next = (sum >= threshold)? 2 : 1;
 
-                int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0);
-                float impact = leaves[(st * 4 + offset) + lShift];
+            // leaves
+            const Node& leaf = nodes[nId + next];
+            const Feature& fLeaf = features[leaf.feature];
 
-                detectionScore += impact;
-            }
-            if (detectionScore <= stage.threshold) return;
+            scaledRect = fLeaf.rect;
+            threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea;
+            sum = storage.get(fLeaf.channel, scaledRect);
+
+            int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0);
+            float impact = leaves[(st * 4) + lShift];
+
+            detectionScore += impact;
+
+            if (detectionScore <= weak.threshold) return;
         }
 
         if (detectionScore > 0)
@@ -346,13 +345,14 @@ struct cv::SCascade::Fields
         static const char *const SC_ORIG_H           = "height";
 
         static const char *const SC_OCTAVES          = "octaves";
-        static const char *const SC_STAGES           = "stages";
+        static const char *const SC_TREES            = "trees";
         static const char *const SC_FEATURES         = "features";
 
-        static const char *const SC_WEEK             = "weakClassifiers";
         static const char *const SC_INTERNAL         = "internalNodes";
         static const char *const SC_LEAF             = "leafValues";
 
+        static const char *const SC_SHRINKAGE        = "shrinkage";
+
         // only Ada Boost supported
         std::string stageTypeStr = (string)root[SC_STAGE_TYPE];
         CV_Assert(stageTypeStr == SC_BOOST);
@@ -364,17 +364,14 @@ struct cv::SCascade::Fields
         origObjWidth  = (int)root[SC_ORIG_W];
         origObjHeight = (int)root[SC_ORIG_H];
 
-        shrinkage = (int)root["shrinkage"];
+        shrinkage = (int)root[SC_SHRINKAGE];
 
         FileNode fn = root[SC_OCTAVES];
         if (fn.empty()) return false;
 
-        FileNodeIterator it = fn.begin(), it_end = fn.end();
-        int feature_offset = 0;
-        int octIndex = 0;
-
         // for each octave
-        for (; it != it_end; ++it)
+        FileNodeIterator it = fn.begin(), it_end = fn.end();
+        for (int octIndex = 0; it != it_end; ++it, ++octIndex)
         {
             FileNode fns = *it;
             Octave octave(octIndex, cv::Size(origObjWidth, origObjHeight), fns);
@@ -384,19 +381,18 @@ struct cv::SCascade::Fields
             FileNode ffs = fns[SC_FEATURES];
             if (ffs.empty()) return false;
 
-            fns = fns["trees"];
+            fns = fns[SC_TREES];
             if (fn.empty()) return false;
 
-            // for each tree (~ decision tree with H = 2)
             FileNodeIterator st = fns.begin(), st_end = fns.end();
             for (; st != st_end; ++st )
             {
-                stages.push_back(Weak(*st));
+                weaks.push_back(Weak(*st));
 
                 fns = (*st)[SC_INTERNAL];
                 FileNodeIterator inIt = fns.begin(), inIt_end = fns.end();
                 for (; inIt != inIt_end;)
-                    nodes.push_back(Node(feature_offset, inIt));
+                    nodes.push_back(Node(features.size(), inIt));
 
                 fns = (*st)[SC_LEAF];
                 inIt = fns.begin(), inIt_end = fns.end();
@@ -408,10 +404,8 @@ struct cv::SCascade::Fields
             st = ffs.begin(), st_end = ffs.end();
             for (; st != st_end; ++st )
                 features.push_back(Feature(*st));
-
-            feature_offset += octave.weaks * 3;
-            ++octIndex;
         }
+
         return true;
     }
 };