Positives preprocessing
authormarina.kolpakova <marina.kolpakova@itseez.com>
Thu, 6 Dec 2012 10:20:45 +0000 (14:20 +0400)
committermarina.kolpakova <marina.kolpakova@itseez.com>
Fri, 1 Feb 2013 10:34:38 +0000 (14:34 +0400)
apps/sft/include/sft/octave.hpp
apps/sft/octave.cpp
apps/sft/sft.cpp

index e2b206a..51457c9 100644 (file)
@@ -54,7 +54,7 @@ class Dataset
 public:
     Dataset(const sft::string& path, const int octave);
 
-private:
+// private:
     svector pos;
     svector neg;
 };
@@ -83,15 +83,14 @@ class FeaturePool
 public:
     FeaturePool(cv::Size model, int nfeatures);
     ~FeaturePool();
+    int size() const { return (int)pool.size(); }
+
 private:
     void fill(int desired);
 
     cv::Size model;
     int nfeatures;
 
-    Mat integrals;
-    Mat responces;
-
     Icfvector pool;
 
     static const unsigned int seed = 0;
@@ -103,15 +102,30 @@ private:
 class Octave : cv::Boost
 {
 public:
-    Octave(int logScale);
+    Octave(int npositives, int nnegatives, int logScale, int shrinkage);
     virtual ~Octave();
 
+     virtual bool train(const Dataset& dataset, const FeaturePool& pool);
+
+    int logScale;
+
+protected:
     virtual bool train( const cv::Mat& trainData, const cv::Mat& responses, const cv::Mat& varIdx=cv::Mat(),
        const cv::Mat& sampleIdx=cv::Mat(), const cv::Mat& varType=cv::Mat(), const cv::Mat& missingDataMask=cv::Mat());
 
-    int logScale;
+    void processPositives(const Dataset& dataset, const FeaturePool& pool);
 private:
+
+    int npositives;
+    int nnegatives;
+
+    int shrinkage;
+
+    Mat integrals;
+    Mat responses;
+
     CvBoostParams params;
+
 };
 
 }
index 613d4c6..c0690b9 100644 (file)
@@ -44,7 +44,6 @@
 #include <sft/random.hpp>
 
 #if defined VISUALIZE_GENERATION
-# include <opencv2/highgui/highgui.hpp>
 # define show(a, b)  \
     do {             \
     cv::imshow(a,b); \
 #endif
 
 #include <glob.h>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/highgui/highgui.hpp>
 
 // ============ Octave ============ //
-sft::Octave::Octave(int ls) : logScale(ls) {}
+sft::Octave::Octave(int np, int nn, int ls, int shr)
+: logScale(ls), npositives(np), nnegatives(nn), shrinkage(shr)
+{
+    int maxSample = npositives + nnegatives;
+    responses.create(maxSample, 1, CV_32FC1);
+}
 
 sft::Octave::~Octave(){}
 
-bool sft::Octave::train( const cv::Mat& trainData, const cv::Mat& responses, const cv::Mat& varIdx,
+bool sft::Octave::train( const cv::Mat& trainData, const cv::Mat& _responses, const cv::Mat& varIdx,
        const cv::Mat& sampleIdx, const cv::Mat& varType, const cv::Mat& missingDataMask)
 {
     bool update = false;
-    return cv::Boost::train(trainData, CV_COL_SAMPLE, responses, varIdx, sampleIdx, varType, missingDataMask, params,
+    return cv::Boost::train(trainData, CV_COL_SAMPLE, _responses, varIdx, sampleIdx, varType, missingDataMask, params,
     update);
 }
 
+namespace {
+using namespace sft;
+class Preprocessor
+{
+public:
+    Preprocessor(int shr) : shrinkage(shr) {}
+
+    void apply(const Mat& frame, Mat integrals)
+    {
+        CV_Assert(frame.type() == CV_8UC3);
+
+        int h = frame.rows;
+        int w = frame.cols;
+
+        cv::Mat channels, gray;
+
+        channels.create(h * BINS, w, CV_8UC1);
+        channels.setTo(0);
+
+        cvtColor(frame, gray, CV_BGR2GRAY);
+
+        cv::Mat df_dx, df_dy, mag, angle;
+        cv::Sobel(gray, df_dx, CV_32F, 1, 0);
+        cv::Sobel(gray, df_dy, CV_32F, 0, 1);
+
+        cv::cartToPolar(df_dx, df_dy, mag, angle, true);
+        mag *= (1.f / (8 * sqrt(2.f)));
+
+        cv::Mat nmag;
+        mag.convertTo(nmag, CV_8UC1);
+
+        angle *=  6 / 360.f;
+
+        for (int y = 0; y < h; ++y)
+        {
+            uchar* magnitude = nmag.ptr<uchar>(y);
+            float* ang = angle.ptr<float>(y);
+
+            for (int x = 0; x < w; ++x)
+            {
+                channels.ptr<uchar>(y + (h * (int)ang[x]))[x] = magnitude[x];
+            }
+        }
+
+        cv::Mat luv, shrunk;
+        cv::cvtColor(frame, luv, CV_BGR2Luv);
+
+        std::vector<cv::Mat> splited;
+        for (int i = 0; i < 3; ++i)
+            splited.push_back(channels(cv::Rect(0, h * (7 + i), w, h)));
+        split(luv, splited);
+
+        cv::resize(channels, shrunk, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA);
+        cv::integral(shrunk, integrals, cv::noArray(), CV_32S);
+    }
+
+    int shrinkage;
+    enum {BINS = 10};
+};
+}
+
+// ToDo: parallelize it
+void sft::Octave::processPositives(const Dataset& dataset, const FeaturePool& pool)
+{
+    Preprocessor prepocessor(shrinkage);
+
+    int cols = (64 * pow(2, logScale) + 1) * (128 * pow(2, logScale) + 1);
+    integrals.create(pool.size(), cols, CV_32SC1);
+
+    int total = 0;
+
+    // float* responce = responce.ptr<float>(0);
+    for (svector::const_iterator it = dataset.pos.begin(); it != dataset.pos.end(); ++it)
+    {
+        const string& curr = *it;
+
+        dprintf("Process candidate positive image %s\n", curr.c_str());
+
+        cv::Mat channels = integrals.col(total).reshape(0, (128 * pow(2, logScale) + 1));
+
+        cv::Mat sample = cv::imread(curr);
+        prepocessor.apply(sample, channels);
+        responses.ptr<float>(total)[0] = 1.f;
+
+        ++total;
+        if (total >= npositives) break;
+    }
+
+    dprintf("Processing positives finished:\n\trequested %d positives, collected %d samples.\n", npositives, total);
+
+    npositives = total;
+    nnegatives *= total / (float)npositives;
+}
+
+bool sft::Octave::train(const Dataset& dataset, const FeaturePool& pool)
+{
+    // 1. fill integrals and classes
+    return false;
+
+}
+
 // ========= FeaturePool ========= //
 sft::FeaturePool::FeaturePool(cv::Size m, int n) : model(m), nfeatures(n)
 {
index e671c21..7c896bc 100644 (file)
@@ -52,16 +52,21 @@ int main(int argc, char** argv)
     int npositives = 10;
     int nnegatives = 10;
 
+    int shrinkage  = 4;
+    int octave = 0;
+
     int nsamples = npositives + nnegatives;
     cv::Size model(64, 128);
     std::string path = "/home/kellan/cuda-dev/opencv_extra/testdata/sctrain/rescaled-train-2012-10-27-19-02-52";
 
-    sft::Octave boost(0);
-    cv::Mat train_data(nfeatures, nsamples, CV_32FC1);
+    sft::Octave boost(npositives, nnegatives, octave, shrinkage);
 
     sft::FeaturePool pool(model, nfeatures);
-    sft::Dataset(path, boost.logScale);
+    sft::Dataset dataset(path, boost.logScale);
 
+    boost.train(dataset, pool);
+
+    cv::Mat train_data(nfeatures, nsamples, CV_32FC1);
     cv::RNG rng;
 
     for (int y = 0; y < nfeatures; ++y)
@@ -113,7 +118,7 @@ int main(int argc, char** argv)
 
     bool update = false;
 
-    boost.train(train_data, responses, var_idx, sample_idx, var_type, missing_mask);
+    // boost.train(train_data, responses, var_idx, sample_idx, var_type, missing_mask);
 
     // CvFileStorage* fs = cvOpenFileStorage( "/home/kellan/train_res.xml", 0, CV_STORAGE_WRITE );
     // boost.write(fs, "test_res");