From fb113e5ce42079e4bc3bd741ec5c402acc7f1e92 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 30 Aug 2012 19:48:59 +0400 Subject: [PATCH] scale pyramid calculations --- .../include/opencv2/objdetect/objdetect.hpp | 3 +- modules/objdetect/src/softcascade.cpp | 137 +++++++++++++++++++-- 2 files changed, 130 insertions(+), 10 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 690d63b..c528c8c 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -506,6 +506,7 @@ protected: // int stripSize, int yStep, double factor, vector& candidates, // vector& rejectLevels, vector& 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 { }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 1d2604c..61a1197 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -39,8 +39,15 @@ // the use of this software, even if advised of the possibility of such damage. //M*/ -struct Filds +#include +#include + +#include + + +struct cv::SoftCascade::Filds { + std::vector octaves; // cv::Mat luv; // std::vector 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(detW * o), cv::saturate_cast(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 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 levels; + + pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, origObjectW, origObjectH, TOTAL_SCALES, minScale, maxScale,levels); + + for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) + { + float minAbsLog = FLT_MAX; + for (std::vector::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& rois, std::vector& objects, - const double factor = 1.05, const int step = 4, const int rejectfactor = 1) +void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& 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 -- 2.7.4