mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-17 15:26:00 +08:00
Add icf feature evaluator
This commit is contained in:
@@ -58,9 +58,9 @@ namespace xobjdetect
|
|||||||
channels — output array for computed channels
|
channels — output array for computed channels
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void computeChannels(InputArray image, std::vector<Mat>& channels);
|
CV_EXPORTS void computeChannels(InputArray image, std::vector<Mat>& channels);
|
||||||
|
|
||||||
class CV_EXPORTS ACFFeatureEvaluator : public Algorithm
|
class CV_EXPORTS FeatureEvaluator : public Algorithm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* Set channels for feature evaluation */
|
/* Set channels for feature evaluation */
|
||||||
@@ -69,8 +69,6 @@ public:
|
|||||||
/* Set window position */
|
/* Set window position */
|
||||||
virtual void setPosition(Size position) = 0;
|
virtual void setPosition(Size position) = 0;
|
||||||
|
|
||||||
virtual void assertChannels() = 0;
|
|
||||||
|
|
||||||
/* Evaluate feature with given index for current channels
|
/* Evaluate feature with given index for current channels
|
||||||
and window position */
|
and window position */
|
||||||
virtual int evaluate(size_t feature_ind) const = 0;
|
virtual int evaluate(size_t feature_ind) const = 0;
|
||||||
@@ -81,23 +79,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void evaluateAll(OutputArray feature_values) const = 0;
|
virtual void evaluateAll(OutputArray feature_values) const = 0;
|
||||||
|
|
||||||
|
virtual void assertChannels() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Construct evaluator, set features to evaluate */
|
/* Construct feature evaluator, set features to evaluate
|
||||||
CV_EXPORTS Ptr<ACFFeatureEvaluator>
|
type can "icf" or "acf" */
|
||||||
createACFFeatureEvaluator(const std::vector<Point3i>& features);
|
CV_EXPORTS Ptr<FeatureEvaluator>
|
||||||
|
createFeatureEvaluator(const std::vector<std::vector<int> >& features,
|
||||||
|
const std::string& type);
|
||||||
|
|
||||||
/* Generate acf features
|
/* Generate acf features
|
||||||
|
|
||||||
window_size — size of window in which features should be evaluated
|
window_size — size of window in which features should be evaluated
|
||||||
|
|
||||||
|
type — type of features, can be "icf" or "acf"
|
||||||
count — number of features to generate.
|
count — number of features to generate.
|
||||||
Max number of features is min(count, # possible distinct features)
|
Max number of features is min(count, # possible distinct features)
|
||||||
|
|
||||||
Returns vector of distinct acf features
|
Returns vector of distinct acf features
|
||||||
*/
|
*/
|
||||||
std::vector<Point3i>
|
std::vector<std::vector<int> >
|
||||||
generateFeatures(Size window_size, int count = INT_MAX);
|
generateFeatures(Size window_size, const std::string& type,
|
||||||
|
int count = INT_MAX, int channel_count = 10);
|
||||||
|
|
||||||
|
|
||||||
struct CV_EXPORTS WaldBoostParams
|
struct CV_EXPORTS WaldBoostParams
|
||||||
@@ -135,7 +138,7 @@ public:
|
|||||||
is from class +1
|
is from class +1
|
||||||
*/
|
*/
|
||||||
virtual float predict(
|
virtual float predict(
|
||||||
const Ptr<ACFFeatureEvaluator>& /*feature_evaluator*/) const
|
const Ptr<FeatureEvaluator>& /*feature_evaluator*/) const
|
||||||
{return 0.0f;}
|
{return 0.0f;}
|
||||||
|
|
||||||
/* Write WaldBoost to FileStorage */
|
/* Write WaldBoost to FileStorage */
|
||||||
@@ -207,7 +210,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ptr<WaldBoost> waldboost_;
|
Ptr<WaldBoost> waldboost_;
|
||||||
std::vector<Point3i> features_;
|
std::vector<std::vector<int> > features_;
|
||||||
int model_n_rows_;
|
int model_n_rows_;
|
||||||
int model_n_cols_;
|
int model_n_cols_;
|
||||||
};
|
};
|
||||||
|
@@ -54,31 +54,6 @@ namespace cv
|
|||||||
namespace xobjdetect
|
namespace xobjdetect
|
||||||
{
|
{
|
||||||
|
|
||||||
class ACFFeatureEvaluatorImpl : public ACFFeatureEvaluator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ACFFeatureEvaluatorImpl(const vector<Point3i>& features):
|
|
||||||
features_(features), channels_(), position_()
|
|
||||||
{
|
|
||||||
CV_Assert(features.size() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setChannels(InputArrayOfArrays channels);
|
|
||||||
virtual void assertChannels();
|
|
||||||
virtual void setPosition(Size position);
|
|
||||||
virtual int evaluate(size_t feature_ind) const;
|
|
||||||
virtual void evaluateAll(OutputArray feature_values) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/* Features to evaluate */
|
|
||||||
std::vector<Point3i> features_;
|
|
||||||
/* Channels for feature evaluation */
|
|
||||||
std::vector<Mat> channels_;
|
|
||||||
/* Channels window position */
|
|
||||||
Size position_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static bool isNull(const Mat_<int> &m)
|
static bool isNull(const Mat_<int> &m)
|
||||||
{
|
{
|
||||||
bool null_data = true;
|
bool null_data = true;
|
||||||
@@ -91,38 +66,114 @@ static bool isNull(const Mat_<int> &m)
|
|||||||
return null_data;
|
return null_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACFFeatureEvaluatorImpl::assertChannels()
|
class FeatureEvaluatorImpl : public FeatureEvaluator
|
||||||
{
|
{
|
||||||
bool null_data = true;
|
public:
|
||||||
for( size_t i = 0; i < channels_.size(); ++i )
|
FeatureEvaluatorImpl(const vector<vector<int> >& features):
|
||||||
null_data &= isNull(channels_[i]);
|
features_(features), channels_(), position_()
|
||||||
CV_Assert(!null_data);
|
{
|
||||||
}
|
CV_Assert(features.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ACFFeatureEvaluatorImpl::setChannels(cv::InputArrayOfArrays channels)
|
virtual void assertChannels()
|
||||||
|
{
|
||||||
|
bool null_data = true;
|
||||||
|
for( size_t i = 0; i < channels_.size(); ++i )
|
||||||
|
null_data &= isNull(channels_[i]);
|
||||||
|
CV_Assert(!null_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void evaluateAll(OutputArray feature_values) const
|
||||||
|
{
|
||||||
|
Mat_<int> feature_vals(1, (int)features_.size());
|
||||||
|
for( int i = 0; i < (int)features_.size(); ++i )
|
||||||
|
{
|
||||||
|
feature_vals(0, i) = evaluate(i);
|
||||||
|
}
|
||||||
|
feature_values.assign(feature_vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* Features to evaluate */
|
||||||
|
vector<vector<int> > features_;
|
||||||
|
/* Channels for feature evaluation */
|
||||||
|
std::vector<Mat> channels_;
|
||||||
|
/* Channels window position */
|
||||||
|
Size position_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ICFFeatureEvaluatorImpl : public FeatureEvaluatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ICFFeatureEvaluatorImpl(const vector<vector<int> >& features):
|
||||||
|
FeatureEvaluatorImpl(features)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setChannels(InputArrayOfArrays channels);
|
||||||
|
virtual void setPosition(Size position);
|
||||||
|
virtual int evaluate(size_t feature_ind) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ICFFeatureEvaluatorImpl::setChannels(InputArrayOfArrays channels)
|
||||||
{
|
{
|
||||||
channels_.clear();
|
channels_.clear();
|
||||||
vector<Mat> ch;
|
vector<Mat> ch;
|
||||||
channels.getMatVector(ch);
|
channels.getMatVector(ch);
|
||||||
CV_Assert(ch.size() == 10);
|
CV_Assert(ch.size() == 10);
|
||||||
|
|
||||||
/*int min_val = 100500, max_val = -1;
|
|
||||||
for( size_t i = 0; i < ch.size(); ++i )
|
for( size_t i = 0; i < ch.size(); ++i )
|
||||||
{
|
{
|
||||||
const Mat &channel = ch[i];
|
const Mat &channel = ch[i];
|
||||||
for( int row = 0; row < channel.rows; ++row )
|
Mat integral_channel;
|
||||||
for( int col = 0; col < channel.cols; ++col )
|
integral(channel, integral_channel, CV_32F);
|
||||||
{
|
Mat_<int> chan(integral_channel.rows, integral_channel.cols);
|
||||||
int val = (int)channel.at<float>(row, col);
|
for( int row = 0; row < integral_channel.rows; ++row )
|
||||||
if( val < min_val )
|
for( int col = 0; col < integral_channel.cols; ++col )
|
||||||
min_val = val;
|
chan(row, col) = (int)integral_channel.at<float>(row, col);
|
||||||
else if( val > max_val )
|
channels_.push_back(chan.clone());
|
||||||
max_val = val;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ICFFeatureEvaluatorImpl::setPosition(Size position)
|
||||||
|
{
|
||||||
|
position_ = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ICFFeatureEvaluatorImpl::evaluate(size_t feature_ind) const
|
||||||
|
{
|
||||||
|
CV_Assert(channels_.size() == 10);
|
||||||
|
CV_Assert(feature_ind < features_.size());
|
||||||
|
|
||||||
|
const vector<int>& feature = features_[feature_ind];
|
||||||
|
int x = feature[0] + position_.height;
|
||||||
|
int y = feature[1] + position_.width;
|
||||||
|
int x_to = feature[2] + position_.height;
|
||||||
|
int y_to = feature[3] + position_.width;
|
||||||
|
int n = feature[4];
|
||||||
|
const Mat_<int>& ch = channels_[n];
|
||||||
|
return ch(y_to + 1, x_to + 1) - ch(y, x_to + 1) - ch(y_to + 1, x) + ch(y, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ACFFeatureEvaluatorImpl : public FeatureEvaluatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ACFFeatureEvaluatorImpl(const vector<vector<int> >& features):
|
||||||
|
FeatureEvaluatorImpl(features)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "SET " << min_val << " " << max_val << endl;
|
virtual void setChannels(InputArrayOfArrays channels);
|
||||||
*/
|
virtual void setPosition(Size position);
|
||||||
|
virtual int evaluate(size_t feature_ind) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ACFFeatureEvaluatorImpl::setChannels(InputArrayOfArrays channels)
|
||||||
|
{
|
||||||
|
channels_.clear();
|
||||||
|
vector<Mat> ch;
|
||||||
|
channels.getMatVector(ch);
|
||||||
|
CV_Assert(ch.size() == 10);
|
||||||
|
|
||||||
for( size_t i = 0; i < ch.size(); ++i )
|
for( size_t i = 0; i < ch.size(); ++i )
|
||||||
{
|
{
|
||||||
@@ -135,11 +186,7 @@ void ACFFeatureEvaluatorImpl::setChannels(cv::InputArrayOfArrays channels)
|
|||||||
int sum = 0;
|
int sum = 0;
|
||||||
for( int cell_row = row; cell_row < row + 4; ++cell_row )
|
for( int cell_row = row; cell_row < row + 4; ++cell_row )
|
||||||
for( int cell_col = col; cell_col < col + 4; ++cell_col )
|
for( int cell_col = col; cell_col < col + 4; ++cell_col )
|
||||||
{
|
|
||||||
//cout << channel.rows << " " << channel.cols << endl;
|
|
||||||
//cout << cell_row << " " << cell_col << endl;
|
|
||||||
sum += (int)channel.at<float>(cell_row, cell_col);
|
sum += (int)channel.at<float>(cell_row, cell_col);
|
||||||
}
|
|
||||||
|
|
||||||
acf_channel(row / 4, col / 4) = sum;
|
acf_channel(row / 4, col / 4) = sum;
|
||||||
}
|
}
|
||||||
@@ -159,49 +206,66 @@ int ACFFeatureEvaluatorImpl::evaluate(size_t feature_ind) const
|
|||||||
CV_Assert(channels_.size() == 10);
|
CV_Assert(channels_.size() == 10);
|
||||||
CV_Assert(feature_ind < features_.size());
|
CV_Assert(feature_ind < features_.size());
|
||||||
|
|
||||||
Point3i feature = features_.at(feature_ind);
|
const vector<int>& feature = features_[feature_ind];
|
||||||
int x = feature.x;
|
int x = feature[0];
|
||||||
int y = feature.y;
|
int y = feature[1];
|
||||||
int n = feature.z;
|
int n = feature[2];
|
||||||
return channels_[n].at<int>(y + position_.width, x + position_.height);
|
return channels_[n].at<int>(y + position_.width, x + position_.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACFFeatureEvaluatorImpl::evaluateAll(OutputArray feature_values) const
|
Ptr<FeatureEvaluator> createFeatureEvaluator(
|
||||||
|
const vector<vector<int> >& features, const std::string& type)
|
||||||
{
|
{
|
||||||
Mat_<int> feature_vals(1, (int)features_.size());
|
FeatureEvaluator *evaluator = NULL;
|
||||||
for( int i = 0; i < (int)features_.size(); ++i )
|
if( type == "acf" )
|
||||||
{
|
evaluator = new ACFFeatureEvaluatorImpl(features);
|
||||||
feature_vals(0, i) = evaluate(i);
|
else if( type == "icf" )
|
||||||
}
|
evaluator = new ICFFeatureEvaluatorImpl(features);
|
||||||
feature_values.assign(feature_vals);
|
else
|
||||||
|
CV_Assert(false);
|
||||||
|
|
||||||
|
return Ptr<FeatureEvaluator>(evaluator);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<ACFFeatureEvaluator>
|
vector<vector<int> > generateFeatures(Size window_size, const std::string& type,
|
||||||
createACFFeatureEvaluator(const vector<Point3i>& features)
|
int count, int channel_count)
|
||||||
{
|
|
||||||
return Ptr<ACFFeatureEvaluator>(new ACFFeatureEvaluatorImpl(features));
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Point3i> generateFeatures(Size window_size, int count)
|
|
||||||
{
|
{
|
||||||
CV_Assert(count > 0);
|
CV_Assert(count > 0);
|
||||||
int cur_count = 0;
|
vector<vector<int> > features;
|
||||||
int max_count = window_size.width * window_size.height / 16;
|
if( type == "acf" )
|
||||||
count = min(count, max_count);
|
|
||||||
vector<Point3i> features;
|
|
||||||
for( int x = 0; x < window_size.width / 4; ++x )
|
|
||||||
{
|
{
|
||||||
for( int y = 0; y < window_size.height / 4; ++y )
|
int cur_count = 0;
|
||||||
|
int max_count = window_size.width * window_size.height / 16;
|
||||||
|
count = min(count, max_count);
|
||||||
|
for( int x = 0; x < window_size.width / 4; ++x )
|
||||||
|
for( int y = 0; y < window_size.height / 4; ++y )
|
||||||
|
for( int n = 0; n < channel_count; ++n )
|
||||||
|
{
|
||||||
|
int f[] = {x, y, n};
|
||||||
|
vector<int> feature(f, f + sizeof(f) / sizeof(*f));
|
||||||
|
features.push_back(feature);
|
||||||
|
if( (cur_count += 1) == count )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( type == "icf" )
|
||||||
|
{
|
||||||
|
RNG rng;
|
||||||
|
for( int i = 0; i < count; ++i )
|
||||||
{
|
{
|
||||||
/* Assume there are 10 channel types */
|
int x = rng.uniform(0, window_size.width - 1);
|
||||||
for( int n = 0; n < 10; ++n )
|
int y = rng.uniform(0, window_size.height - 1);
|
||||||
{
|
int x_to = rng.uniform(x, window_size.width - 1);
|
||||||
features.push_back(Point3i(x, y, n));
|
int y_to = rng.uniform(y, window_size.height - 1);
|
||||||
if( (cur_count += 1) == count )
|
int n = rng.uniform(0, channel_count - 1);
|
||||||
break;
|
int f[] = {x, y, x_to, y_to, n};
|
||||||
}
|
vector<int> feature(f, f + sizeof(f) / sizeof(*f));
|
||||||
|
features.push_back(feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
CV_Assert(false);
|
||||||
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -118,8 +118,9 @@ void ICFDetector::train(const String& pos_path,
|
|||||||
for( int i = pos_count; i < pos_count + neg_count; ++i )
|
for( int i = pos_count; i < pos_count + neg_count; ++i )
|
||||||
labels(0, i) = -1;
|
labels(0, i) = -1;
|
||||||
|
|
||||||
vector<Point3i> features = generateFeatures(model_size);
|
vector<vector<int> > features = generateFeatures(model_size, "icf",
|
||||||
Ptr<ACFFeatureEvaluator> feature_evaluator = createACFFeatureEvaluator(features);
|
params.feature_count);
|
||||||
|
Ptr<FeatureEvaluator> evaluator = createFeatureEvaluator(features, "icf");
|
||||||
|
|
||||||
Mat_<int> data = Mat_<int>::zeros((int)features.size(), (int)samples.size());
|
Mat_<int> data = Mat_<int>::zeros((int)features.size(), (int)samples.size());
|
||||||
Mat_<int> feature_col(1, (int)samples.size());
|
Mat_<int> feature_col(1, (int)samples.size());
|
||||||
@@ -129,9 +130,9 @@ void ICFDetector::train(const String& pos_path,
|
|||||||
{
|
{
|
||||||
cout << setw(6) << i << "/" << samples.size() << "\r";
|
cout << setw(6) << i << "/" << samples.size() << "\r";
|
||||||
computeChannels(samples[i], channels);
|
computeChannels(samples[i], channels);
|
||||||
feature_evaluator->setChannels(channels);
|
evaluator->setChannels(channels);
|
||||||
//feature_evaluator->assertChannels();
|
//evaluator->assertChannels();
|
||||||
feature_evaluator->evaluateAll(feature_col);
|
evaluator->evaluateAll(feature_col);
|
||||||
|
|
||||||
CV_Assert(feature_col.cols == (int)features.size());
|
CV_Assert(feature_col.cols == (int)features.size());
|
||||||
|
|
||||||
@@ -180,7 +181,7 @@ void ICFDetector::read(const FileNode& node)
|
|||||||
node["waldboost"] >> *waldboost_;
|
node["waldboost"] >> *waldboost_;
|
||||||
FileNode features = node["features"];
|
FileNode features = node["features"];
|
||||||
features_.clear();
|
features_.clear();
|
||||||
Point3i p;
|
vector<int> p;
|
||||||
for( FileNodeIterator n = features.begin(); n != features.end(); ++n )
|
for( FileNodeIterator n = features.begin(); n != features.end(); ++n )
|
||||||
{
|
{
|
||||||
(*n) >> p;
|
(*n) >> p;
|
||||||
@@ -196,7 +197,7 @@ void ICFDetector::detect(const Mat& img, vector<Rect>& objects,
|
|||||||
float scale_to = max(model_n_cols_ / (float)minSize.width,
|
float scale_to = max(model_n_cols_ / (float)minSize.width,
|
||||||
model_n_rows_ / (float)minSize.height);
|
model_n_rows_ / (float)minSize.height);
|
||||||
objects.clear();
|
objects.clear();
|
||||||
Ptr<ACFFeatureEvaluator> evaluator = createACFFeatureEvaluator(features_);
|
Ptr<FeatureEvaluator> evaluator = createFeatureEvaluator(features_, "icf");
|
||||||
Mat rescaled_image;
|
Mat rescaled_image;
|
||||||
int step = 8;
|
int step = 8;
|
||||||
vector<Mat> channels;
|
vector<Mat> channels;
|
||||||
|
@@ -67,7 +67,7 @@ public:
|
|||||||
const Mat& labels);
|
const Mat& labels);
|
||||||
|
|
||||||
virtual float predict(
|
virtual float predict(
|
||||||
const Ptr<ACFFeatureEvaluator>& feature_evaluator) const;
|
const Ptr<FeatureEvaluator>& feature_evaluator) const;
|
||||||
|
|
||||||
virtual void write(FileStorage& fs) const;
|
virtual void write(FileStorage& fs) const;
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ vector<int> WaldBoostImpl::train(const Mat& data_, const Mat& labels_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
float WaldBoostImpl::predict(
|
float WaldBoostImpl::predict(
|
||||||
const Ptr<ACFFeatureEvaluator>& feature_evaluator) const
|
const Ptr<FeatureEvaluator>& feature_evaluator) const
|
||||||
{
|
{
|
||||||
float trace = 0;
|
float trace = 0;
|
||||||
CV_Assert(stumps_.size() == thresholds_.size());
|
CV_Assert(stumps_.size() == thresholds_.size());
|
||||||
|
Reference in New Issue
Block a user