scale pyramid calculations
authormarina.kolpakova <marina.kolpakova@itseez.com>
Thu, 30 Aug 2012 15:48:59 +0000 (19:48 +0400)
committermarina.kolpakova <marina.kolpakova@itseez.com>
Tue, 6 Nov 2012 23:19:04 +0000 (03:19 +0400)
modules/objdetect/include/opencv2/objdetect/objdetect.hpp
modules/objdetect/src/softcascade.cpp

index 690d63b..c528c8c 100644 (file)
@@ -506,6 +506,7 @@ protected:
     //                                 int stripSize, int yStep, double factor, vector<Rect>& candidates,
     //                                 vector<int>& rejectLevels, vector<double>& levelWeights, bool outputRejectLevels=false);
     enum { BOOST = 0 };
+    enum { FRAME_WIDTH = 640, FRAME_HEIGHT = 480, TOTAL_SCALES = 55, CLASSIFIERS = 5};
 
 private:
     struct Feature
@@ -514,7 +515,7 @@ private:
         int channel;
     };
 
-    stuct Stamp
+    struct Stamp
     {
 
     };
index 1d2604c..61a1197 100644 (file)
 // the use of this software, even if advised of the possibility of such damage.
 //M*/
 
-struct Filds
+#include <precomp.hpp>
+#include <opencv2/objdetect/objdetect.hpp>
+
+#include <vector>
+
+
+struct cv::SoftCascade::Filds
 {
+    std::vector<float> octaves;
     // cv::Mat luv;
     // std::vector<cv::Mat> bins;
     // cv::Mat magnitude;
@@ -48,27 +55,139 @@ struct Filds
     // int windowStep;
 };
 
+namespace {
+
+struct Cascade {
+    int logOctave;
+    float octave;
+    cv::Size objSize;
+};
+
+struct Level {
+    int index;
+    float factor;
+    float logFactor;
+    int width;
+    int height;
+    float octave;
+    cv::Size objSize;
+
+    Level(int i,float f, float lf, int w, int h) : index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {}
+
+    void assign(float o, int detW, int detH)
+    {
+        octave = o;
+        objSize = cv::Size(cv::saturate_cast<int>(detW * o), cv::saturate_cast<int>(detH * o));
+    }
+
+    float relScale() {return (factor / octave); }
+};
+    // compute levels of full pyramid
+    void pyrLevels(int frameW, int frameH, int detW, int detH, int scales, float minScale, float maxScale, std::vector<Level> levels)
+    {
+        CV_Assert(scales > 1);
+        levels.clear();
+        float logFactor = (log(maxScale) - log(minScale)) / (scales -1);
+
+        float scale = minScale;
+        for (int sc = 0; sc < scales; ++sc)
+        {
+            Level level(sc, scale, log(scale) + logFactor, std::max(0.0f, frameW - (detW * scale)), std::max(0.0f, frameH - (detH * scale)));
+            if (!level.width || !level.height)
+                break;
+            else
+                levels.push_back(level);
+
+            if (fabs(scale - maxScale) < FLT_EPSILON) break;
+            scale = std::min(maxScale, expf(log(scale) + logFactor));
+        }
+
+    }
+
+    // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper
+    struct CascadeIntrinsics {
+        static const float lambda = 1.099f/ 0.301029996f, a = 0.89f;
+        static const float intrinsics[10][4];
 
-SoftCascade::SoftCascade() : filds(0) {}
+        static float getFor(int chennel, int scaling, int ab)
+        {
+            CV_Assert(chennel < 10 && scaling < 2 && ab < 2);
+            return intrinsics[chennel][(scaling << 1) + ab];
+        }
 
-SoftCascade::SoftCascade( const string& filename )
+    };
+
+    const float CascadeIntrinsics::intrinsics[10][4] =
+        {   //da, db, ua, ub
+            // hog-like orientation bins
+            {a, lambda, 1, 2},
+            {a, lambda, 1, 2},
+            {a, lambda, 1, 2},
+            {a, lambda, 1, 2},
+            {a, lambda, 1, 2},
+            {a, lambda, 1, 2},
+            // gradient magnitude
+            {a, lambda / log(2), 1, 2},
+            // luv -color chennels
+            {1, 2,      1, 2},
+            {1, 2,      1, 2},
+            {1, 2,      1, 2}
+        };
+}
+
+
+
+
+cv::SoftCascade::SoftCascade() : filds(0) {}
+
+cv::SoftCascade::SoftCascade( const string& filename )
 {
-    filds = new filds;
+    filds = new Filds;
     load(filename);
 }
-virtual SoftCascade::~SoftCascade()
+cv::SoftCascade::~SoftCascade()
 {
     delete filds;
 }
 
-bool SoftCascade::load( const string& filename )
+bool cv::SoftCascade::load( const string& filename )
 {
+    // temp fixture
+    Filds& flds = *filds;
+    flds.octaves.push_back(0.5f);
+    flds.octaves.push_back(1.0f);
+    flds.octaves.push_back(2.0f);
+    flds.octaves.push_back(4.0f);
+    flds.octaves.push_back(8.0f);
+
+    // scales calculations
+    int origObjectW = 64;
+    int origObjectH = 128;
+    float maxScale = 5.f, minScale = 0.4f;
+    std::vector<Level> levels;
+
+    pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, origObjectW, origObjectH, TOTAL_SCALES, minScale, maxScale,levels);
+
+    for (std::vector<Level>::iterator level = levels.begin(); level < levels.end(); ++level)
+    {
+        float minAbsLog = FLT_MAX;
+        for (std::vector<float>::iterator oct = flds.octaves.begin(); oct < flds.octaves.end(); ++oct)
+        {
+            float logOctave = log(*oct);
+            float logAbsScale = fabs((*level).logFactor - logOctave);
+
+            if(logAbsScale < minAbsLog)
+                (*level).assign(*oct, origObjectW, origObjectH);
+
+        }
+    }
+
     return true;
 }
 
-virtual void SoftCascade::detectMultiScale(const Mat& image, const std::vector<cv::Rect>& rois, std::vector<cv::Rect>& objects,
-                                           const double factor = 1.05, const int step = 4, const int rejectfactor = 1)
+void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector<cv::Rect>& rois, std::vector<cv::Rect>& objects,
+                                           const double factor, const int step, const int rejectfactor)
 {}
 
-virtual void SoftCascade::detectForOctave(const int octave)
+void cv::SoftCascade::detectForOctave(const int octave)
 {}
\ No newline at end of file