From cf6694250529a7066664f1b7d1f0e4d26a775da0 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 13 Mar 2013 13:40:11 +0400 Subject: [PATCH 1/2] enable training test. refactor globbing --- apps/sft/dataset.cpp | 96 ++------------------ modules/softcascade/test/test_training.cpp | 101 ++------------------- 2 files changed, 12 insertions(+), 185 deletions(-) diff --git a/apps/sft/dataset.cpp b/apps/sft/dataset.cpp index 52ec8ac84..d89a38e88 100644 --- a/apps/sft/dataset.cpp +++ b/apps/sft/dataset.cpp @@ -46,116 +46,32 @@ #include #include -inline std::string itoa(long i) { return cv::format("%ld", i); } - -#if !defined (_WIN32) && ! defined(__MINGW32__) -# include - -namespace { -using namespace sft; -void glob(const string& path, svector& ret) -{ - glob_t glob_result; - glob(path.c_str(), GLOB_TILDE, 0, &glob_result); - - ret.clear(); - ret.reserve(glob_result.gl_pathc); - - for(unsigned int i = 0; i < glob_result.gl_pathc; ++i) - { - ret.push_back(std::string(glob_result.gl_pathv[i])); - dprintf("%s\n", ret[i].c_str()); - } - - globfree(&glob_result); -} - -} -#else - -# include -namespace { -using namespace sft; -void glob(const string& refRoot, const string& refExt, svector &refvecFiles) -{ - std::string strFilePath; // File path - std::string strExtension; // Extension - - std::string strPattern = refRoot + "\\*.*"; - - WIN32_FIND_DATA FileInformation; // File information - HANDLE hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); - - if(hFile == INVALID_HANDLE_VALUE) - CV_Error(CV_StsBadArg, "Your dataset search path is incorrect"); - - do - { - if(FileInformation.cFileName[0] != '.') - { - strFilePath.erase(); - strFilePath = refRoot + "\\" + FileInformation.cFileName; - - if( !(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { - // Check extension - strExtension = FileInformation.cFileName; - strExtension = strExtension.substr(strExtension.rfind(".") + 1); - - if(strExtension == refExt) - // Save filename - refvecFiles.push_back(strFilePath); - } - } - } - while(::FindNextFile(hFile, &FileInformation) == TRUE); - - // Close handle - ::FindClose(hFile); - - DWORD dwError = ::GetLastError(); - if(dwError != ERROR_NO_MORE_FILES) - CV_Error(CV_StsBadArg, "Your dataset search path is incorrect"); -} -} - -#endif - // in the default case data folders should be aligned as following: // 1. positives: /octave_/pos/*.png // 2. negatives: /octave_/neg/*.png -ScaledDataset::ScaledDataset(const string& path, const int oct) +sft::ScaledDataset::ScaledDataset(const string& path, const int oct) { dprintf("%s\n", "get dataset file names..."); dprintf("%s\n", "Positives globing..."); - -#if !defined (_WIN32) && ! defined(__MINGW32__) - glob(path + "/pos/octave_" + itoa(oct) + "/*.png", pos); -#else - glob(path + "/pos/octave_" + itoa(oct), "png", pos); -#endif + cv::glob(path + "/pos/octave_" + cv::format("%d", oct) + "/*.png", pos); dprintf("%s\n", "Negatives globing..."); -#if !defined (_WIN32) && ! defined(__MINGW32__) - glob(path + "/neg/octave_" + itoa(oct) + "/*.png", neg); -#else - glob(path + "/neg/octave_" + itoa(oct), "png", neg); -#endif + cv::glob(path + "/neg/octave_" + cv::format("%d", oct) + "/*.png", neg); // Check: files not empty CV_Assert(pos.size() != size_t(0)); CV_Assert(neg.size() != size_t(0)); } -cv::Mat ScaledDataset::get(SampleType type, int idx) const +cv::Mat sft::ScaledDataset::get(SampleType type, int idx) const { const std::string& src = (type == POSITIVE)? pos[idx]: neg[idx]; return cv::imread(src); } -int ScaledDataset::available(SampleType type) const +int sft::ScaledDataset::available(SampleType type) const { return (int)((type == POSITIVE)? pos.size():neg.size()); } -ScaledDataset::~ScaledDataset(){} \ No newline at end of file +sft::ScaledDataset::~ScaledDataset(){} \ No newline at end of file diff --git a/modules/softcascade/test/test_training.cpp b/modules/softcascade/test/test_training.cpp index a03ab8abd..0d9f632af 100644 --- a/modules/softcascade/test/test_training.cpp +++ b/modules/softcascade/test/test_training.cpp @@ -46,13 +46,6 @@ #include #include -#include "test_precomp.hpp" -#if !defined (_WIN32) && ! defined(__MINGW32__) -# include -#else -# include -#endif - using namespace std; namespace { @@ -74,92 +67,10 @@ private: svector neg; }; -string itoa(long i) -{ - char s[65]; - sprintf(s, "%ld", i); - return std::string(s); -} - - -#if !defined (_WIN32) && ! defined(__MINGW32__) - -void glob(const string& path, svector& ret) -{ - glob_t glob_result; - glob(path.c_str(), GLOB_TILDE, 0, &glob_result); - - ret.clear(); - ret.reserve(glob_result.gl_pathc); - - for(unsigned int i = 0; i < glob_result.gl_pathc; ++i) - { - ret.push_back(std::string(glob_result.gl_pathv[i])); - } - - globfree(&glob_result); -} - -#else - -void glob(const string& refRoot, const string& refExt, svector &refvecFiles) -{ - std::string strFilePath; // File path - std::string strExtension; // Extension - - std::string strPattern = refRoot + "\\*.*"; - - WIN32_FIND_DATA FileInformation; // File information - HANDLE hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); - - if(hFile == INVALID_HANDLE_VALUE) - CV_Error(CV_StsBadArg, "Your dataset search path is incorrect"); - - do - { - if(FileInformation.cFileName[0] != '.') - { - strFilePath.erase(); - strFilePath = refRoot + "\\" + FileInformation.cFileName; - - if( !(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { - // Check extension - strExtension = FileInformation.cFileName; - strExtension = strExtension.substr(strExtension.rfind(".") + 1); - - if(strExtension == refExt) - // Save filename - refvecFiles.push_back(strFilePath); - } - } - } - while(::FindNextFile(hFile, &FileInformation) == TRUE); - - // Close handle - ::FindClose(hFile); - - DWORD dwError = ::GetLastError(); - if(dwError != ERROR_NO_MORE_FILES) - CV_Error(CV_StsBadArg, "Your dataset search path is incorrect"); -} - -#endif - ScaledDataset::ScaledDataset(const string& path, const int oct) { - -#if !defined (_WIN32) && ! defined(__MINGW32__) - glob(path + "/pos/octave_" + itoa(oct) + "/*.png", pos); -#else - glob(path + "/pos/octave_" + itoa(oct), "png", pos); -#endif - -#if !defined (_WIN32) && ! defined(__MINGW32__) - glob(path + "/neg/octave_" + itoa(oct) + "/*.png", neg); -#else - glob(path + "/neg/octave_" + itoa(oct), "png", neg); -#endif + cv::glob(path + cv::format("/octave_%d/*.png", oct), pos); + cv::glob(path + "/*.png", neg); // Check: files not empty CV_Assert(pos.size() != size_t(0)); @@ -181,7 +92,7 @@ ScaledDataset::~ScaledDataset(){} } -TEST(DISABLED_SoftCascade, training) +TEST(SoftCascade, training) { // // 2. check and open output file string outXmlPath = cv::tempfile(".xml"); @@ -214,8 +125,8 @@ TEST(DISABLED_SoftCascade, training) cv::Ptr pool = FeaturePool::create(model, nfeatures, 10); nfeatures = pool->size(); - int npositives = 20; - int nnegatives = 40; + int npositives = 10; + int nnegatives = 20; cv::Rect boundingBox = cv::Rect( cvRound(20 * octave), cvRound(20 * octave), cvRound(64 * octave), cvRound(128 * octave)); @@ -223,7 +134,7 @@ TEST(DISABLED_SoftCascade, training) cv::Ptr builder = ChannelFeatureBuilder::create("HOG6MagLuv"); cv::Ptr boost = Octave::create(boundingBox, npositives, nnegatives, *it, shrinkage, builder); - std::string path = cvtest::TS::ptr()->get_data_path() + "softcascade/sample_training_set"; + std::string path = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sample_training_set"; ScaledDataset dataset(path, *it); if (boost->train(&dataset, pool, 3, 2)) From 18aa5c921f6bd60e1f967446c39f1565975cd632 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 13 Mar 2013 14:11:34 +0400 Subject: [PATCH 2/2] use OpenCV's twister. --- modules/softcascade/src/_random.hpp | 162 ------------------ .../src/integral_channel_builder.cpp | 14 -- modules/softcascade/src/precomp.hpp | 42 ++++- modules/softcascade/test/test_training.cpp | 1 + 4 files changed, 42 insertions(+), 177 deletions(-) delete mode 100644 modules/softcascade/src/_random.hpp diff --git a/modules/softcascade/src/_random.hpp b/modules/softcascade/src/_random.hpp deleted file mode 100644 index 63fa2565f..000000000 --- a/modules/softcascade/src/_random.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and / or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#ifndef __SFT_RANDOM_HPP__ -#define __SFT_RANDOM_HPP__ - -#if defined(_MSC_VER) && _MSC_VER >= 1600 -# include - -namespace cv { namespace softcascade { namespace internal -{ - -struct Random -{ - typedef std::mt19937 engine; - typedef engine::result_type seed_type; - typedef std::uniform_int uniform; -}; - -}}} - -#elif (__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 1 && !defined(__ANDROID__) -# if defined (__cplusplus) && __cplusplus > 201100L -# include - -namespace cv { namespace softcascade { namespace internal -{ - -struct Random -{ - typedef std::mt19937 engine; - typedef engine::result_type seed_type; -// True if we're using C++11. -#if __cplusplus >= 201103L - // C++11 removes uniform_int. - typedef std::uniform_int_distribution uniform; -#else - typedef std::uniform_int uniform; -#endif -}; -}}} - -# else -# include - -namespace cv { namespace softcascade { namespace internal -{ - -struct Random -{ - typedef std::tr1::mt19937 engine; - typedef engine::result_type seed_type; - typedef std::tr1::uniform_int uniform; -}; - -}}} -# endif - -#else -# include - -namespace cv { namespace softcascade { namespace internal -{ -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; -}; - -} - -struct Random -{ - typedef rnd::engine engine; - typedef uint64 seed_type; - typedef rnd::uniform_int uniform; -}; - -}}} - -#endif - -#if defined _WIN32 && (_WIN32 || _WIN64) -# if _WIN64 -# define USE_LONG_SEEDS -# endif -#endif -#if defined (__GNUC__) &&__GNUC__ -# if defined(__x86_64__) || defined(__ppc64__) -# define USE_LONG_SEEDS -# endif -#endif - -#if defined USE_LONG_SEEDS -# define FEATURE_RECT_SEED 8854342234LU -# define INDEX_ENGINE_SEED 764224349868LU -#else -# define FEATURE_RECT_SEED 88543422LU -# define INDEX_ENGINE_SEED 76422434LU -#endif -#undef USE_LONG_SEEDS - -#define DCHANNELS_SEED 314152314LU -#define DX_DY_SEED 65633343LU - -#endif diff --git a/modules/softcascade/src/integral_channel_builder.cpp b/modules/softcascade/src/integral_channel_builder.cpp index 6959b6e7a..febfe491b 100644 --- a/modules/softcascade/src/integral_channel_builder.cpp +++ b/modules/softcascade/src/integral_channel_builder.cpp @@ -238,22 +238,8 @@ void ChannelFeaturePool::fill(int desired) int x = xRand(eng); int y = yRand(eng); -#if __cplusplus >= 201103L - // The interface changed slightly going from uniform_int to - // uniform_int_distribution. See this page to understand - // the old behavior: - // http://www.boost.org/doc/libs/1_47_0/boost/random/uniform_int.hpp - int w = 1 + wRand( - eng, - // This extra "- 1" appears to be necessary, based on the Boost docs. - Random::uniform::param_type(0, (model.width - x - 1) - 1)); - int h = 1 + hRand( - eng, - Random::uniform::param_type(0, (model.height - y - 1) - 1)); -#else int w = 1 + wRand(eng, model.width - x - 1); int h = 1 + hRand(eng, model.height - y - 1); -#endif CV_Assert(w > 0); CV_Assert(h > 0); diff --git a/modules/softcascade/src/precomp.hpp b/modules/softcascade/src/precomp.hpp index cb20a268e..a4eeb59d9 100644 --- a/modules/softcascade/src/precomp.hpp +++ b/modules/softcascade/src/precomp.hpp @@ -53,6 +53,46 @@ #include "opencv2/core/core_c.h" #include "opencv2/core/internal.hpp" #include "opencv2/ml/ml.hpp" -#include "_random.hpp" + +namespace cv { namespace softcascade { namespace internal +{ +namespace rnd { + +typedef cv::RNG_MT19937 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; +}; + +} + +struct Random +{ + typedef rnd::engine engine; + typedef uint64 seed_type; + typedef rnd::uniform_int uniform; +}; + +}}} + +#define FEATURE_RECT_SEED 88543422U +#define INDEX_ENGINE_SEED 76422434U +#define DCHANNELS_SEED 314152314U +#define DX_DY_SEED 65633343U #endif diff --git a/modules/softcascade/test/test_training.cpp b/modules/softcascade/test/test_training.cpp index 0d9f632af..ef20323d2 100644 --- a/modules/softcascade/test/test_training.cpp +++ b/modules/softcascade/test/test_training.cpp @@ -42,6 +42,7 @@ #if !defined(ANDROID) +#include #include #include #include