From 6f53be4102d59340198d682b2e7a71e4b57400b2 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 13 Sep 2012 15:15:26 +0400 Subject: [PATCH] shrinking before integral calculation --- modules/objdetect/src/softcascade.cpp | 180 ++++++++++++-------- modules/objdetect/test/test_softcascade.cpp | 2 +- 2 files changed, 106 insertions(+), 76 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index c00285a699..6cb9d693fe 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -161,8 +161,8 @@ namespace { // {1, 2, 1, 2} // }; -// struct Level -// { + struct Level + { // int index; // float factor; @@ -189,7 +189,7 @@ namespace { // float relScale() {return (factor / octave.scale); } // float srScale() {return (factor / octave.scale * shrinkage); } -// }; + }; // struct Integral // { @@ -209,6 +209,8 @@ struct cv::SoftCascade::Filds int origObjWidth; int origObjHeight; + int shrinkage; + std::vector octaves; std::vector stages; std::vector nodes; @@ -216,6 +218,8 @@ struct cv::SoftCascade::Filds std::vector features; + std::vector levels; + // typedef std::vector::iterator stIter_t; // // carrently roi must be save for out of ranges. @@ -236,11 +240,11 @@ struct cv::SoftCascade::Filds // } // } - // // compute levels of full pyramid - // void calcLevels(int frameW, int frameH, int scales) - // { - // CV_Assert(scales > 1); - // levels.clear(); + // compute levels of full pyramid + void calcLevels(int frameW, int frameH, int scales) + { + CV_Assert(scales > 1); + levels.clear(); // float logFactor = (log(maxScale) - log(minScale)) / (scales -1); // float scale = minScale; @@ -274,7 +278,7 @@ struct cv::SoftCascade::Filds // } // } // } - // } + } bool fill(const FileNode &root, const float mins, const float maxs) { @@ -360,15 +364,16 @@ struct cv::SoftCascade::Filds for (; st != st_end; ++st ) features.push_back(Feature(*st)); } + + shrinkage = octaves[0].shrinkage; return true; } }; cv::SoftCascade::SoftCascade() : filds(0) {} -cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) +cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) : filds(0) { - filds = new Filds; load(filename, minScale, maxScale); } cv::SoftCascade::~SoftCascade() @@ -378,7 +383,8 @@ cv::SoftCascade::~SoftCascade() bool cv::SoftCascade::load( const string& filename, const float minScale, const float maxScale) { - delete filds; + if (filds) + delete filds; filds = 0; cv::FileStorage fs(filename, FileStorage::READ); @@ -387,56 +393,92 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - // // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); + flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); return true; } namespace { - void calcHistBins(const cv::Mat& grey, cv::Mat magIntegral, std::vector& histInts, const int bins) + void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, const int bins, int shrinkage) { - // CV_Assert( grey.type() == CV_8U); - // const int rows = grey.rows + 1; - // const int cols = grey.cols + 1; - // cv::Size intSumSize(cols, rows); - - // histInts.clear(); - // std::vector hist; - // for (int bin = 0; bin < bins; ++bin) - // { - // hist.push_back(cv::Mat(rows, cols, CV_32FC1)); - // } - // cv::Mat df_dx, df_dy, mag, angle; - // cv::Sobel(grey, df_dx, CV_32F, 1, 0); - // cv::Sobel(grey, df_dy, CV_32F, 0, 1); - - // cv::cartToPolar(df_dx, df_dy, mag, angle, true); - - // const float magnitudeScaling = 1.0 / sqrt(2); - // mag *= magnitudeScaling; - // angle /= 60; - - // for (int h = 0; h < mag.rows; ++h) - // { - // float* magnitude = mag.ptr(h); - // float* ang = angle.ptr(h); - - // for (int w = 0; w < mag.cols; ++w) - // { - // hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; - // } - // } - - // for (int bin = 0; bin < bins; ++bin) - // { - // cv::Mat sum; - // cv::integral(hist[bin], sum); - // histInts.push_back(sum); - // } - - // cv::integral(mag, magIntegral, mag.depth()); + CV_Assert( grey.type() == CV_8U); + + float scale = 1.f / shrinkage; + + const int rows = grey.rows + 1; + const int cols = grey.cols + 1; + cv::Size intSumSize(cols, rows); + + histInts.clear(); + std::vector hist; + for (int bin = 0; bin < bins; ++bin) + { + hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + } + + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(grey, df_dx, CV_32F, 1, 0); + cv::Sobel(grey, df_dy, CV_32F, 0, 1); + + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + + const float magnitudeScaling = 1.0 / sqrt(2); + mag *= magnitudeScaling; + angle /= 60; + + for (int h = 0; h < mag.rows; ++h) + { + float* magnitude = mag.ptr(h); + float* ang = angle.ptr(h); + + for (int w = 0; w < mag.cols; ++w) + { + hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + } + } + + for (int bin = 0; bin < bins; ++bin) + { + cv::Mat shrunk, sum; + cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); + cv::integral(shrunk, sum); + histInts.push_back(sum); + } + + cv::Mat shrMag; + cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); + + cv::integral(shrMag, magIntegral, mag.depth()); } + + struct ChannelStorage + { + std::vector hog; + cv::Mat luv; + cv::Mat magnitude; + + int shrinkage; + + enum {HOG_BINS = 6}; + + ChannelStorage() {} + ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) + { + cv::Mat _luv; + cv::cvtColor(colored, _luv, CV_BGR2Luv); + + cv::integral(luv, luv); + + cv::Mat grey; + cv::cvtColor(colored, grey, CV_RGB2GRAY); + + calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); + std::cout << magnitude.cols << " " << magnitude.rows << std::endl; + cv::imshow("1", magnitude); + cv::waitKey(0); + } + }; } @@ -444,31 +486,19 @@ namespace { void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, const int step, const int rejectfactor)// add step scaling { - // typedef std::vector::const_iterator RIter_t; - // // only color images are supperted - // CV_Assert(image.type() == CV_8UC3); - - // // only this window size allowed - // CV_Assert(image.cols == 640 && image.rows == 480); - - // objects.clear(); - - // // create integrals - // cv::Mat luv; - // cv::cvtColor(image, luv, CV_BGR2Luv); + typedef std::vector::const_iterator RIter_t; + // only color images are supperted + CV_Assert(image.type() == CV_8UC3); - // cv::Mat luvIntegral; - // cv::integral(luv, luvIntegral); + // only this window size allowed + CV_Assert(image.cols == 640 && image.rows == 480); - // cv::Mat grey; - // cv::cvtColor(image, grey, CV_RGB2GRAY); + objects.clear(); - // std::vector hist; - // cv::Mat magnitude; - // const int bins = 6; - // calcHistBins(grey, magnitude, hist, bins); + const Filds& fld = *filds; - // Integral integrals(magnitude, hist, luv); + // create integrals + ChannelStorage storage(image, fld.shrinkage); // for (RIter_t it = rois.begin(); it != rois.end(); ++it) // { diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index ccf713957b..7311ad2914 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -51,7 +51,7 @@ TEST(SoftCascade, readCascade) TEST(SoftCascade, detect) { - std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/softcascade.xml"; + std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml));