diff --git a/apps/sft/include/sft/common.hpp b/apps/sft/include/sft/common.hpp index 86d2355470..6d62dfdb59 100644 --- a/apps/sft/include/sft/common.hpp +++ b/apps/sft/include/sft/common.hpp @@ -48,6 +48,9 @@ namespace sft { using cv::Mat; + struct ICF; + typedef std::vector Icfvector; + } #endif \ No newline at end of file diff --git a/apps/sft/include/sft/octave.hpp b/apps/sft/include/sft/octave.hpp index dab07ef0fc..9243ef7793 100644 --- a/apps/sft/include/sft/octave.hpp +++ b/apps/sft/include/sft/octave.hpp @@ -44,18 +44,63 @@ #define __SFT_OCTAVE_HPP__ #include +#include namespace sft { +struct ICF +{ + ICF(int x, int y, int w, int h, int ch) : bb(cv::Rect(x, y, w, h)), channel(ch) {} + + bool operator ==(ICF b) + { + return bb == b.bb && channel == b.channel; + } + + bool operator !=(ICF b) + { + return bb != b.bb || channel != b.channel; + } + +private: + cv::Rect bb; + int channel; +}; + +class FeaturePool +{ +public: + FeaturePool(cv::Size model, int nfeatures); + ~FeaturePool(); +private: + void fill(int desired); + + cv::Size model; + int nfeatures; + + Mat integrals; + Mat responces; + + Icfvector pool; + + static const unsigned int seed = 0; + + enum { N_CHANNELS = 10 }; +}; + // used for traning single octave scale -class Octave : public cv::Boost +class Octave : cv::Boost { public: Octave(); - ~Octave(); + virtual ~Octave(); + + 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()); private: + CvBoostParams params; }; } diff --git a/apps/sft/include/sft/random.hpp b/apps/sft/include/sft/random.hpp new file mode 100644 index 0000000000..d9d9f7843d --- /dev/null +++ b/apps/sft/include/sft/random.hpp @@ -0,0 +1,75 @@ +#ifndef __SFT_RANDOM_HPP__ +#define __SFT_RANDOM_HPP__ + +#if defined(_MSC_VER) && _MSC_VER >= 1600 + +# include +namespace sft { +struct Random +{ + typedef std::mt19937 engine; + typedef std::uniform_int uniform; +}; +} + +#elif (__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 1 + +# if defined (__cplusplus) && __cplusplus > 201100L +# include +namespace sft { +struct Random +{ + typedef std::mt19937 engine; + typedef std::uniform_int uniform; +}; +} +# else +# include + +namespace sft { +struct Random +{ + typedef std::tr1::mt19937 engine; + typedef std::tr1::uniform_int uniform; +}; +} +# endif + +#else +#include +namespace rnd { + +typedef cv::RNG engine; + +template +struct uniform_int +{ + uniform_int(const int _min, const int _max) : min(_min), max(_max) {} + T operator() (engine& eng, const int bound) const + { + return (T)eng.uniform(min, bound); + } + + T operator() (engine& eng) const + { + return (T)eng.uniform(min, max); + } + +private: + int min; + int max; +}; + +} + +namespace sft { +struct Random +{ + typedef rnd::engine engine; + typedef rnd::uniform_int uniform; +}; +} + +#endif + +#endif \ No newline at end of file diff --git a/apps/sft/octave.cpp b/apps/sft/octave.cpp index a18f082a57..60eed96f89 100644 --- a/apps/sft/octave.cpp +++ b/apps/sft/octave.cpp @@ -41,7 +41,84 @@ //M*/ #include +#include +#if defined VISUALIZE_GENERATION +# include +# define show(a, b) \ + do { \ + cv::imshow(a,b); \ + cv::waitkey(0); \ + } while(0) +#else +# define show(a, b) +#endif + +// ============ Octave ============ // sft::Octave::Octave(){} -sft::Octave::~Octave(){} \ No newline at end of file +sft::Octave::~Octave(){} + +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, + update); +} + +// ========= FeaturePool ========= // +sft::FeaturePool::FeaturePool(cv::Size m, int n) : model(m), nfeatures(n) +{ + CV_Assert(m != cv::Size() && n > 0); + fill(nfeatures); +} + +sft::FeaturePool::~FeaturePool(){} + + +void sft::FeaturePool::fill(int desired) +{ + + int mw = model.width; + int mh = model.height; + + int maxPoolSize = (mw -1) * mw / 2 * (mh - 1) * mh / 2 * N_CHANNELS; + + nfeatures = std::min(desired, maxPoolSize); + + pool.reserve(nfeatures); + + sft::Random::engine eng(seed); + sft::Random::engine eng_ch(seed); + + sft::Random::uniform chRand(0, N_CHANNELS - 1); + + sft::Random::uniform xRand(0, model.width - 2); + sft::Random::uniform yRand(0, model.height - 2); + + sft::Random::uniform wRand(1, model.width - 1); + sft::Random::uniform hRand(1, model.height - 1); + + while (pool.size() < size_t(nfeatures)) + { + int x = xRand(eng); + int y = yRand(eng); + + int w = 1 + wRand(eng, model.width - x - 1); + int h = 1 + hRand(eng, model.height - y - 1); + + CV_Assert(w > 0); + CV_Assert(h > 0); + + CV_Assert(w + x < model.width); + CV_Assert(h + y < model.height); + + int ch = chRand(eng_ch); + + sft::ICF f(x, y, w, h, ch); + + if (std::find(pool.begin(), pool.end(),f) == pool.end()) + pool.push_back(f); + } +} \ No newline at end of file diff --git a/apps/sft/sft.cpp b/apps/sft/sft.cpp index 255919d89b..7b98071bae 100644 --- a/apps/sft/sft.cpp +++ b/apps/sft/sft.cpp @@ -52,63 +52,65 @@ int main(int argc, char** argv) int npositives = 10; int nnegatives = 10; int nsamples = npositives + nnegatives; + cv::Size model(64, 128); sft::Octave boost; cv::Mat train_data(nfeatures, nsamples, CV_32FC1); - // cv::RNG rng; + sft::FeaturePool pool(model, nfeatures); - // for (int y = 0; y < nfeatures; ++y) - // for (int x = 0; x < nsamples; ++x) - // train_data.at(y, x) = rng.uniform(0.f, 1.f); + cv::RNG rng; - // int tflag = CV_COL_SAMPLE; - // Mat responses(nsamples, 1, CV_32FC1); - // for (int y = 0; y < nsamples; ++y) - // responses.at(y, 0) = (y < npositives) ? 1.f : 0.f; + for (int y = 0; y < nfeatures; ++y) + for (int x = 0; x < nsamples; ++x) + train_data.at(y, x) = rng.uniform(0.f, 1.f); + + int tflag = CV_COL_SAMPLE; + cv::Mat responses(nsamples, 1, CV_32FC1); + for (int y = 0; y < nsamples; ++y) + responses.at(y, 0) = (y < npositives) ? 1.f : 0.f; - // Mat var_idx(1, nfeatures, CV_32SC1); - // for (int x = 0; x < nfeatures; ++x) - // var_idx.at(0, x) = x; + cv::Mat var_idx(1, nfeatures, CV_32SC1); + for (int x = 0; x < nfeatures; ++x) + var_idx.at(0, x) = x; - // // Mat sample_idx; - // Mat sample_idx(1, nsamples, CV_32SC1); - // for (int x = 0; x < nsamples; ++x) - // sample_idx.at(0, x) = x; + // Mat sample_idx; + cv::Mat sample_idx(1, nsamples, CV_32SC1); + for (int x = 0; x < nsamples; ++x) + sample_idx.at(0, x) = x; - // Mat var_type(1, nfeatures + 1, CV_8UC1); - // for (int x = 0; x < nfeatures; ++x) - // var_type.at(0, x) = CV_VAR_ORDERED; + cv::Mat var_type(1, nfeatures + 1, CV_8UC1); + for (int x = 0; x < nfeatures; ++x) + var_type.at(0, x) = CV_VAR_ORDERED; - // var_type.at(0, nfeatures) = CV_VAR_CATEGORICAL; + var_type.at(0, nfeatures) = CV_VAR_CATEGORICAL; - // Mat missing_mask; + cv::Mat missing_mask; - // CvBoostParams params; - // { - // params.max_categories = 10; - // params.max_depth = 2; - // params.min_sample_count = 2; - // params.cv_folds = 0; - // params.truncate_pruned_tree = false; + CvBoostParams params; + { + params.max_categories = 10; + params.max_depth = 2; + params.min_sample_count = 2; + params.cv_folds = 0; + params.truncate_pruned_tree = false; - // /// ?????????????????? - // params.regression_accuracy = 0.01; - // params.use_surrogates = false; - // params.use_1se_rule = false; + /// ?????????????????? + params.regression_accuracy = 0.01; + params.use_surrogates = false; + params.use_1se_rule = false; - // ///////// boost params - // params.boost_type = CvBoost::GENTLE; - // params.weak_count = 1; - // params.split_criteria = CvBoost::SQERR; - // params.weight_trim_rate = 0.95; - // } + ///////// boost params + params.boost_type = CvBoost::GENTLE; + params.weak_count = 1; + params.split_criteria = CvBoost::SQERR; + params.weight_trim_rate = 0.95; + } - // bool update = false; + bool update = false; - // boost.train(train_data, tflag, responses, - // var_idx, sample_idx, var_type, missing_mask, params, update); + 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");