|
|
|
@ -46,11 +46,15 @@ namespace { |
|
|
|
|
|
|
|
|
|
using namespace cv::softcascade; |
|
|
|
|
|
|
|
|
|
class ICFBuilder : public ChannelFeatureBuilder |
|
|
|
|
class HOG6MagLuv : public ChannelFeatureBuilder |
|
|
|
|
{ |
|
|
|
|
virtual ~ICFBuilder() {} |
|
|
|
|
enum {N_CHANNELS = 10}; |
|
|
|
|
public: |
|
|
|
|
virtual ~HOG6MagLuv() {} |
|
|
|
|
virtual cv::AlgorithmInfo* info() const; |
|
|
|
|
|
|
|
|
|
virtual int totalChannels() const {return N_CHANNELS; } |
|
|
|
|
|
|
|
|
|
virtual void operator()(cv::InputArray _frame, CV_OUT cv::OutputArray _integrals, cv::Size channelsSize) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert(_frame.type() == CV_8UC3); |
|
|
|
@ -60,16 +64,16 @@ class ICFBuilder : public ChannelFeatureBuilder |
|
|
|
|
int w = frame.cols; |
|
|
|
|
|
|
|
|
|
if (channelsSize != cv::Size()) |
|
|
|
|
_integrals.create(channelsSize.height * 10 + 1, channelsSize.width + 1, CV_32SC1); |
|
|
|
|
_integrals.create(channelsSize.height * N_CHANNELS + 1, channelsSize.width + 1, CV_32SC1); |
|
|
|
|
|
|
|
|
|
if(_integrals.empty()) |
|
|
|
|
_integrals.create(frame.rows * 10 + 1, frame.cols + 1, CV_32SC1); |
|
|
|
|
_integrals.create(frame.rows * N_CHANNELS + 1, frame.cols + 1, CV_32SC1); |
|
|
|
|
|
|
|
|
|
cv::Mat& integrals = _integrals.getMatRef(); |
|
|
|
|
|
|
|
|
|
cv::Mat channels, gray; |
|
|
|
|
|
|
|
|
|
channels.create(h * 10, w, CV_8UC1); |
|
|
|
|
channels.create(h * N_CHANNELS, w, CV_8UC1); |
|
|
|
|
channels.setTo(0); |
|
|
|
|
|
|
|
|
|
cvtColor(frame, gray, CV_BGR2GRAY); |
|
|
|
@ -114,14 +118,13 @@ class ICFBuilder : public ChannelFeatureBuilder |
|
|
|
|
using cv::softcascade::ChannelFeatureBuilder; |
|
|
|
|
using cv::softcascade::ChannelFeature; |
|
|
|
|
|
|
|
|
|
CV_INIT_ALGORITHM(ICFBuilder, "ChannelFeatureBuilder.ICFBuilder", ); |
|
|
|
|
CV_INIT_ALGORITHM(HOG6MagLuv, "ChannelFeatureBuilder.HOG6MagLuv", ); |
|
|
|
|
|
|
|
|
|
ChannelFeatureBuilder::~ChannelFeatureBuilder() {} |
|
|
|
|
|
|
|
|
|
cv::Ptr<ChannelFeatureBuilder> ChannelFeatureBuilder::create() |
|
|
|
|
cv::Ptr<ChannelFeatureBuilder> ChannelFeatureBuilder::create(const std::string& featureType) |
|
|
|
|
{ |
|
|
|
|
cv::Ptr<ChannelFeatureBuilder> builder(new ICFBuilder()); |
|
|
|
|
return builder; |
|
|
|
|
return Algorithm::create<ChannelFeatureBuilder>("ChannelFeatureBuilder." + featureType); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ChannelFeature::ChannelFeature(int x, int y, int w, int h, int ch) |
|
|
|
@ -175,9 +178,9 @@ using namespace cv::softcascade; |
|
|
|
|
class ChannelFeaturePool : public FeaturePool |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
ChannelFeaturePool(cv::Size m, int n) : FeaturePool(), model(m) |
|
|
|
|
ChannelFeaturePool(cv::Size m, int n, int ch) : FeaturePool(), model(m), N_CHANNELS(ch) |
|
|
|
|
{ |
|
|
|
|
CV_Assert(m != cv::Size() && n > 0); |
|
|
|
|
CV_Assert(m != cv::Size() && n > 0 && (ch == 10 || ch == 8)); |
|
|
|
|
fill(n); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -193,7 +196,7 @@ private: |
|
|
|
|
|
|
|
|
|
cv::Size model; |
|
|
|
|
std::vector<ChannelFeature> pool; |
|
|
|
|
enum { N_CHANNELS = 10 }; |
|
|
|
|
int N_CHANNELS; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
float ChannelFeaturePool::apply(int fi, int si, const cv::Mat& integrals) const |
|
|
|
@ -203,7 +206,8 @@ float ChannelFeaturePool::apply(int fi, int si, const cv::Mat& integrals) const |
|
|
|
|
|
|
|
|
|
void ChannelFeaturePool::write( cv::FileStorage& fs, int index) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert((index > 0) && (index < (int)pool.size())); |
|
|
|
|
|
|
|
|
|
CV_Assert((index >= 0) && (index < (int)pool.size())); |
|
|
|
|
fs << pool[index]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -240,12 +244,12 @@ void ChannelFeaturePool::fill(int desired) |
|
|
|
|
// the old behavior:
|
|
|
|
|
// http://www.boost.org/doc/libs/1_47_0/boost/random/uniform_int.hpp
|
|
|
|
|
int w = 1 + wRand( |
|
|
|
|
eng, |
|
|
|
|
eng, |
|
|
|
|
// This extra "- 1" appears to be necessary, based on the Boost docs.
|
|
|
|
|
Random::uniform::param_type(0, (model.width - x - 1) - 1)); |
|
|
|
|
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)); |
|
|
|
|
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); |
|
|
|
@ -270,8 +274,8 @@ void ChannelFeaturePool::fill(int desired) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cv::Ptr<FeaturePool> FeaturePool::create(const cv::Size& model, int nfeatures) |
|
|
|
|
cv::Ptr<FeaturePool> FeaturePool::create(const cv::Size& model, int nfeatures, int nchannels ) |
|
|
|
|
{ |
|
|
|
|
cv::Ptr<FeaturePool> pool(new ChannelFeaturePool(model, nfeatures)); |
|
|
|
|
cv::Ptr<FeaturePool> pool(new ChannelFeaturePool(model, nfeatures, nchannels)); |
|
|
|
|
return pool; |
|
|
|
|
} |
|
|
|
|