Merge pull request #291 from shahurik:master
commit
cdbe335258
26 changed files with 1447 additions and 1844 deletions
@ -1,8 +0,0 @@ |
||||
if(IOS) |
||||
ocv_module_disable(adas) |
||||
endif() |
||||
|
||||
set(the_description "Automatic driver assistance algorithms") |
||||
ocv_define_module(adas opencv_xobjdetect) |
||||
|
||||
add_subdirectory(tools) |
@ -1,2 +0,0 @@ |
||||
ADAS: Advanced Driver Assistance Systems module with Forward Collision Warning |
||||
============================================================================== |
@ -1,2 +0,0 @@ |
||||
add_subdirectory(fcw_train) |
||||
add_subdirectory(fcw_detect) |
@ -1,35 +0,0 @@ |
||||
set(name fcw_detect) |
||||
set(the_target opencv_${name}) |
||||
|
||||
set(OPENCV_${the_target}_DEPS opencv_core opencv_imgcodecs opencv_videoio |
||||
opencv_highgui opencv_xobjdetect) |
||||
|
||||
ocv_check_dependencies(${OPENCV_${the_target}_DEPS}) |
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND) |
||||
return() |
||||
endif() |
||||
|
||||
project(${the_target}) |
||||
|
||||
ocv_include_directories("${OpenCV_SOURCE_DIR}/include/opencv") |
||||
ocv_include_modules_recurse(${OPENCV_${the_target}_DEPS}) |
||||
|
||||
file(GLOB ${the_target}_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) |
||||
|
||||
add_executable(${the_target} ${${the_target}_SOURCES}) |
||||
|
||||
target_link_libraries(${the_target} ${OPENCV_${the_target}_DEPS}) |
||||
|
||||
set_target_properties(${the_target} PROPERTIES |
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" |
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} |
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} |
||||
INSTALL_NAME_DIR lib |
||||
OUTPUT_NAME ${the_target}) |
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS) |
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications") |
||||
endif() |
||||
|
||||
install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION bin COMPONENT main) |
@ -1,132 +0,0 @@ |
||||
#include <string> |
||||
using std::string; |
||||
|
||||
#include <vector> |
||||
using std::vector; |
||||
|
||||
#include <iostream> |
||||
using std::cerr; |
||||
using std::endl; |
||||
|
||||
#include <opencv2/core.hpp> |
||||
using cv::Rect; |
||||
using cv::Size; |
||||
using cv::Mat; |
||||
using cv::Mat_; |
||||
using cv::Vec3b; |
||||
|
||||
#include <opencv2/highgui.hpp> |
||||
using cv::imread; |
||||
using cv::imwrite; |
||||
|
||||
#include <opencv2/core/utility.hpp> |
||||
using cv::CommandLineParser; |
||||
using cv::FileStorage; |
||||
|
||||
#include <opencv2/xobjdetect.hpp> |
||||
using cv::xobjdetect::ICFDetector; |
||||
|
||||
static Mat visualize(const Mat &image, const vector<Rect> &objects) |
||||
{ |
||||
CV_Assert(image.type() == CV_8UC3); |
||||
Mat_<Vec3b> img = image.clone(); |
||||
for( size_t j = 0; j < objects.size(); ++j ) |
||||
{ |
||||
Rect obj = objects[j]; |
||||
int x = obj.x; |
||||
int y = obj.y; |
||||
int width = obj.width; |
||||
int height = obj.height; |
||||
for( int i = y; i <= y + height; ++i ) { |
||||
img(i, x) = Vec3b(255, 0, 0); |
||||
img(i, x + width) = Vec3b(255, 0, 0); |
||||
} |
||||
for( int i = x; i <= x + width; ++i) { |
||||
img(y, i) = Vec3b(255, 0, 0); |
||||
img(y + height, i) = Vec3b(255, 0, 0); |
||||
} |
||||
} |
||||
return img; |
||||
} |
||||
static bool read_window_size(const char *str, int *rows, int *cols) |
||||
{ |
||||
int pos = 0; |
||||
if( sscanf(str, "%dx%d%n", rows, cols, &pos) != 2 || str[pos] != '\0' || |
||||
*rows <= 0 || *cols <= 0) |
||||
{ |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
const string keys = |
||||
"{help | | print this message}" |
||||
"{model_filename | model.xml | filename for reading model}" |
||||
"{image_path | test.png | path to image for detection}" |
||||
"{out_image_path | out.png | path to image for output}" |
||||
"{threshold | 0.0 | threshold for cascade}" |
||||
"{step | 8 | sliding window step}" |
||||
"{min_window_size | 40x40 | min window size in pixels}" |
||||
"{max_window_size | 300x300 | max window size in pixels}" |
||||
"{is_grayscale | false | read the image as grayscale}" |
||||
; |
||||
|
||||
CommandLineParser parser(argc, argv, keys); |
||||
parser.about("FCW detection"); |
||||
|
||||
if( parser.has("help") || argc == 1) |
||||
{ |
||||
parser.printMessage(); |
||||
return 0; |
||||
} |
||||
|
||||
string model_filename = parser.get<string>("model_filename"); |
||||
string image_path = parser.get<string>("image_path"); |
||||
string out_image_path = parser.get<string>("out_image_path"); |
||||
bool is_grayscale = parser.get<bool>("is_grayscale"); |
||||
float threshold = parser.get<float>("threshold"); |
||||
int step = parser.get<int>("step"); |
||||
|
||||
int min_rows, min_cols, max_rows, max_cols; |
||||
string min_window_size = parser.get<string>("min_window_size"); |
||||
if( !read_window_size(min_window_size.c_str(), &min_rows, |
||||
&min_cols) ) |
||||
{ |
||||
cerr << "Error reading min window size from `" << min_window_size << "`" << endl; |
||||
return 1; |
||||
} |
||||
string max_window_size = parser.get<string>("max_window_size"); |
||||
if( !read_window_size(max_window_size.c_str(), &max_rows, |
||||
&max_cols) ) |
||||
{ |
||||
cerr << "Error reading max window size from `" << max_window_size << "`" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
int color; |
||||
if(is_grayscale == false) |
||||
color = cv::IMREAD_COLOR; |
||||
else |
||||
color = cv::IMREAD_GRAYSCALE; |
||||
|
||||
|
||||
if( !parser.check() ) |
||||
{ |
||||
parser.printErrors(); |
||||
return 1; |
||||
} |
||||
|
||||
ICFDetector detector; |
||||
FileStorage fs(model_filename, FileStorage::READ); |
||||
detector.read(fs["icfdetector"]); |
||||
fs.release(); |
||||
vector<Rect> objects; |
||||
Mat img = imread(image_path, color); |
||||
std::vector<float> values; |
||||
detector.detect(img, objects, 1.1f, Size(min_cols, min_rows), Size(max_cols, max_rows), threshold, step, values); |
||||
imwrite(out_image_path, visualize(img, objects)); |
||||
|
||||
|
||||
} |
@ -1,187 +0,0 @@ |
||||
#include <cstdio> |
||||
#include <cstring> |
||||
|
||||
#include <string> |
||||
using std::string; |
||||
|
||||
#include <vector> |
||||
using std::vector; |
||||
|
||||
#include <fstream> |
||||
using std::ifstream; |
||||
using std::getline; |
||||
|
||||
#include <sstream> |
||||
using std::stringstream; |
||||
|
||||
#include <iostream> |
||||
using std::cerr; |
||||
using std::endl; |
||||
|
||||
#include <opencv2/core.hpp> |
||||
using cv::Rect; |
||||
using cv::Size; |
||||
#include <opencv2/highgui.hpp> |
||||
using cv::imread; |
||||
#include <opencv2/core/utility.hpp> |
||||
using cv::CommandLineParser; |
||||
using cv::FileStorage; |
||||
#include <opencv2/core/utility.hpp> |
||||
|
||||
#include <ctime> // std::time |
||||
#include <cstdlib> // std::rand, std::srand |
||||
|
||||
#include <opencv2/xobjdetect.hpp> |
||||
|
||||
|
||||
using cv::xobjdetect::ICFDetectorParams; |
||||
using cv::xobjdetect::ICFDetector; |
||||
using cv::xobjdetect::WaldBoost; |
||||
using cv::xobjdetect::WaldBoostParams; |
||||
using cv::Mat; |
||||
|
||||
static bool read_model_size(const char *str, int *rows, int *cols) |
||||
{ |
||||
int pos = 0; |
||||
if( sscanf(str, "%dx%d%n", rows, cols, &pos) != 2 || str[pos] != '\0' || |
||||
*rows <= 0 || *cols <= 0) |
||||
{ |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static int randomPred (int i) { return std::rand()%i;} |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
|
||||
const string keys = |
||||
"{help | | print this message}" |
||||
"{pos_path | pos | path to training object samples}" |
||||
"{bg_path | bg | path to background images}" |
||||
"{bg_per_image | 5 | number of windows to sample per bg image}" |
||||
"{feature_count | 10000 | number of features to generate}" |
||||
"{weak_count | 100 | number of weak classifiers in cascade}" |
||||
"{model_size | 40x40 | model size in pixels}" |
||||
"{model_filename | model.xml | filename for saving model}" |
||||
"{features_type | icf | features type, \"icf\" or \"acf\"}" |
||||
"{alpha | 0.02 | alpha value}" |
||||
"{is_grayscale | false | read the image as grayscale}" |
||||
"{use_fast_log | false | use fast log function}" |
||||
"{limit_ps | -1 | limit to positive samples (-1 means all)}" |
||||
"{limit_bg | -1 | limit to negative samples (-1 means all)}" |
||||
; |
||||
|
||||
|
||||
CommandLineParser parser(argc, argv, keys); |
||||
parser.about("FCW trainer"); |
||||
|
||||
if( parser.has("help") || argc == 1) |
||||
{ |
||||
parser.printMessage(); |
||||
return 0; |
||||
} |
||||
|
||||
string pos_path = parser.get<string>("pos_path"); |
||||
string bg_path = parser.get<string>("bg_path"); |
||||
string model_filename = parser.get<string>("model_filename"); |
||||
|
||||
ICFDetectorParams params; |
||||
params.feature_count = parser.get<int>("feature_count"); |
||||
params.weak_count = parser.get<int>("weak_count"); |
||||
params.bg_per_image = parser.get<int>("bg_per_image"); |
||||
params.features_type = parser.get<string>("features_type"); |
||||
params.alpha = parser.get<float>("alpha"); |
||||
params.is_grayscale = parser.get<bool>("is_grayscale"); |
||||
params.use_fast_log = parser.get<bool>("use_fast_log"); |
||||
|
||||
int limit_ps = parser.get<int>("limit_ps"); |
||||
int limit_bg = parser.get<int>("limit_bg");
|
||||
|
||||
string model_size = parser.get<string>("model_size"); |
||||
if( !read_model_size(model_size.c_str(), ¶ms.model_n_rows, |
||||
¶ms.model_n_cols) ) |
||||
{ |
||||
cerr << "Error reading model size from `" << model_size << "`" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
if( params.feature_count <= 0 ) |
||||
{ |
||||
cerr << "feature_count must be positive number" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
if( params.weak_count <= 0 ) |
||||
{ |
||||
cerr << "weak_count must be positive number" << endl; |
||||
return 1; |
||||
} |
||||
|
||||
if( params.features_type != "icf" && params.features_type != "acf" ) |
||||
{ |
||||
cerr << "features_type must be \"icf\" or \"acf\"" << endl; |
||||
return 1; |
||||
} |
||||
if( params.alpha <= 0 ) |
||||
{ |
||||
cerr << "alpha must be positive float number" << endl; |
||||
return 1; |
||||
} |
||||
if( !parser.check() ) |
||||
{ |
||||
parser.printErrors(); |
||||
return 1; |
||||
} |
||||
|
||||
std::vector<cv::String> pos_filenames; |
||||
glob(pos_path, pos_filenames); |
||||
|
||||
std::vector<cv::String> bg_filenames; |
||||
glob(bg_path, bg_filenames); |
||||
|
||||
if(limit_ps != -1 && (int)pos_filenames.size() > limit_ps) |
||||
pos_filenames.erase(pos_filenames.begin()+limit_ps, pos_filenames.end()); |
||||
if(limit_bg != -1 && (int)bg_filenames.size() > limit_bg) |
||||
bg_filenames.erase(bg_filenames.begin()+limit_bg, bg_filenames.end()); |
||||
|
||||
//random pick input images
|
||||
bool random_shuffle = false; |
||||
if(random_shuffle) |
||||
{ |
||||
std::srand ( unsigned ( std::time(0) ) ); |
||||
std::random_shuffle ( pos_filenames.begin(), pos_filenames.end(), randomPred ); |
||||
std::random_shuffle ( bg_filenames.begin(), bg_filenames.end(), randomPred ); |
||||
} |
||||
|
||||
int samples_size = (int)((params.bg_per_image * bg_filenames.size()) + pos_filenames.size()); |
||||
int features_size = params.feature_count; |
||||
int max_features_allowed = (int)(INT_MAX/(sizeof(int)* samples_size)); |
||||
int max_samples_allowed = (int)(INT_MAX/(sizeof(int)* features_size)); |
||||
int total_samples = (int)((params.bg_per_image * bg_filenames.size()) + pos_filenames.size()); |
||||
|
||||
|
||||
if(total_samples >max_samples_allowed) |
||||
{ |
||||
CV_Error_(1, ("exceeded maximum number of samples. Maximum number of samples with %d features is %d, you have %d (%d positive samples + (%d bg * %d bg_per_image))\n",features_size,max_samples_allowed,total_samples,pos_filenames.size(),bg_filenames.size(),params.bg_per_image )); |
||||
} |
||||
|
||||
if(params.feature_count >max_features_allowed) |
||||
{ |
||||
CV_Error_(1, ("exceeded maximum number of features. Maximum number of features with %d samples is %d, you have %d\n",samples_size,max_features_allowed, features_size )); |
||||
} |
||||
|
||||
std::cout<<pos_filenames.size()<<std::endl; |
||||
std::cout<<bg_filenames.size()<<std::endl; |
||||
|
||||
ICFDetector detector;
|
||||
|
||||
|
||||
detector.train(pos_filenames, bg_filenames, params); |
||||
|
||||
FileStorage fs(model_filename, FileStorage::WRITE); |
||||
fs << "icfdetector"; |
||||
detector.write(fs); |
||||
fs.release(); |
||||
} |
@ -1,2 +1,3 @@ |
||||
set(the_description "Object detection algorithms") |
||||
ocv_define_module(xobjdetect opencv_core opencv_imgproc opencv_highgui WRAP python) |
||||
ocv_define_module(xobjdetect opencv_core opencv_imgproc opencv_highgui opencv_objdetect WRAP python) |
||||
add_subdirectory(tools) |
||||
|
@ -1,88 +0,0 @@ |
||||
#ifndef __OPENCV_XOBJDETECT_PRIVATE_HPP__ |
||||
#define __OPENCV_XOBJDETECT_PRIVATE_HPP__ |
||||
|
||||
#ifndef __OPENCV_BUILD |
||||
# error this is a private header, do not include it outside OpenCV |
||||
#endif |
||||
|
||||
#include <opencv2/core.hpp> |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace xobjdetect |
||||
{ |
||||
|
||||
class CV_EXPORTS Stump |
||||
{ |
||||
public: |
||||
|
||||
/* Initialize zero stump */ |
||||
Stump(): threshold_(0), polarity_(1), pos_value_(1), neg_value_(-1) {} |
||||
|
||||
/* Initialize stump with given threshold, polarity
|
||||
and classification values */ |
||||
Stump(int threshold, int polarity, float pos_value, float neg_value): |
||||
threshold_(threshold), polarity_(polarity), |
||||
pos_value_(pos_value), neg_value_(neg_value) {} |
||||
|
||||
/* Train stump for given data
|
||||
|
||||
data — matrix of feature values, size M x N, one feature per row |
||||
|
||||
labels — matrix of sample class labels, size 1 x N. Labels can be from |
||||
{-1, +1} |
||||
|
||||
weights — matrix of sample weights, size 1 x N |
||||
|
||||
visited_features: vector of already visited features (ignored in successive calls) |
||||
|
||||
Returns chosen feature index. Feature enumeration starts from 0 |
||||
*/ |
||||
int train(const Mat& data, const Mat& labels, const Mat& weights, const std::vector<int>& visited_features, bool use_fast_log = false); |
||||
|
||||
/* Predict object class given
|
||||
|
||||
value — feature value. Feature must be the same as was chosen |
||||
during training stump |
||||
|
||||
Returns real value, sign(value) means class
|
||||
*/ |
||||
float predict(int value) const; |
||||
|
||||
/* Write stump in FileStorage */ |
||||
void write(FileStorage& fs) const |
||||
{ |
||||
fs << "{" |
||||
<< "threshold" << threshold_ |
||||
<< "polarity" << polarity_ |
||||
<< "pos_value" << pos_value_ |
||||
<< "neg_value" << neg_value_ |
||||
<< "}"; |
||||
} |
||||
|
||||
/* Read stump */ |
||||
void read(const FileNode& node) |
||||
{ |
||||
threshold_ = (int)node["threshold"]; |
||||
polarity_ = (int)node["polarity"]; |
||||
pos_value_ = (float)node["pos_value"]; |
||||
neg_value_ = (float)node["neg_value"]; |
||||
} |
||||
|
||||
private: |
||||
/* Stump decision threshold */ |
||||
int threshold_; |
||||
/* Stump polarity, can be from {-1, +1} */ |
||||
int polarity_; |
||||
/* Classification values for positive and negative classes */ |
||||
float pos_value_, neg_value_; |
||||
}; |
||||
|
||||
void read(const FileNode& node, Stump& s, const Stump& default_value=Stump()); |
||||
|
||||
void write(FileStorage& fs, String&, const Stump& s); |
||||
|
||||
} /* namespace xobjdetect */ |
||||
} /* namespace cv */ |
||||
|
||||
#endif // __OPENCV_XOBJDETECT_PRIVATE_HPP__
|
@ -1,344 +0,0 @@ |
||||
/*
|
||||
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2013, OpenCV Foundation, 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
|
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
using std::vector; |
||||
|
||||
using std::min; |
||||
|
||||
#include <iostream> |
||||
using std::cout; |
||||
using std::endl; |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace xobjdetect |
||||
{ |
||||
|
||||
static bool isNull(const Mat_<int> &m) |
||||
{ |
||||
bool null_data = true; |
||||
for( int row = 0; row < m.rows; ++row ) |
||||
{ |
||||
for( int col = 0; col < m.cols; ++col ) |
||||
if( m.at<int>(row, col) ) |
||||
null_data = false; |
||||
} |
||||
return null_data; |
||||
} |
||||
|
||||
class FeatureEvaluatorImpl : public FeatureEvaluator |
||||
{ |
||||
public: |
||||
FeatureEvaluatorImpl(const vector<vector<int> >& features): |
||||
features_(features), channels_(), position_() |
||||
{ |
||||
CV_Assert(features.size() > 0); |
||||
} |
||||
|
||||
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(); |
||||
vector<Mat> ch; |
||||
channels.getMatVector(ch); |
||||
|
||||
for( size_t i = 0; i < ch.size(); ++i ) |
||||
{ |
||||
const Mat &channel = ch[i]; |
||||
Mat integral_channel; |
||||
integral(channel, integral_channel, CV_32F); |
||||
integral_channel.convertTo(integral_channel, CV_32S); |
||||
channels_.push_back(integral_channel.clone()); |
||||
} |
||||
} |
||||
|
||||
void ICFFeatureEvaluatorImpl::setPosition(Size position) |
||||
{ |
||||
position_ = position; |
||||
} |
||||
|
||||
|
||||
int ICFFeatureEvaluatorImpl::evaluate(size_t feature_ind) const |
||||
{ |
||||
/*
|
||||
|
||||
//following return is equal to this commented code, left here for readability. The new code runs much faster.
|
||||
*
|
||||
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); |
||||
*/ |
||||
|
||||
CV_Assert(feature_ind < features_.size()); |
||||
|
||||
return *(channels_[features_[feature_ind][4]].ptr<int>()+((channels_[features_[feature_ind][4]].cols*(features_[feature_ind][3] + position_.width+1))+ features_[feature_ind][2] + position_.height + 1)) -
|
||||
*(channels_[features_[feature_ind][4]].ptr<int>()+((channels_[features_[feature_ind][4]].cols*(features_[feature_ind][1] + position_.width))+ features_[feature_ind][2] + position_.height + 1)) - |
||||
*(channels_[features_[feature_ind][4]].ptr<int>()+((channels_[features_[feature_ind][4]].cols*(features_[feature_ind][3] + position_.width+1))+ features_[feature_ind][0] + position_.height)) + |
||||
*(channels_[features_[feature_ind][4]].ptr<int>()+((channels_[features_[feature_ind][4]].cols*(features_[feature_ind][1] + position_.width))+ features_[feature_ind][0] + position_.height)); |
||||
} |
||||
|
||||
class ACFFeatureEvaluatorImpl : public FeatureEvaluatorImpl |
||||
{ |
||||
public: |
||||
ACFFeatureEvaluatorImpl(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 ACFFeatureEvaluatorImpl::setChannels(InputArrayOfArrays channels) |
||||
{ |
||||
channels_.clear(); |
||||
vector<Mat> ch; |
||||
channels.getMatVector(ch); |
||||
|
||||
for( size_t i = 0; i < ch.size(); ++i ) |
||||
{ |
||||
const Mat &channel = ch[i]; |
||||
Mat_<int> acf_channel = Mat_<int>::zeros(channel.rows / 4, channel.cols / 4); |
||||
for( int row = 0; row < channel.rows; row += 4 ) |
||||
{ |
||||
for( int col = 0; col < channel.cols; col += 4 ) |
||||
{ |
||||
int sum = 0; |
||||
for( int cell_row = row; cell_row < row + 4; ++cell_row ) |
||||
for( int cell_col = col; cell_col < col + 4; ++cell_col ) |
||||
sum += (int)channel.at<float>(cell_row, cell_col); |
||||
|
||||
acf_channel(row / 4, col / 4) = sum; |
||||
} |
||||
} |
||||
|
||||
channels_.push_back(acf_channel.clone()); |
||||
} |
||||
} |
||||
|
||||
void ACFFeatureEvaluatorImpl::setPosition(Size position) |
||||
{ |
||||
position_ = Size(position.width / 4, position.height / 4); |
||||
} |
||||
|
||||
int ACFFeatureEvaluatorImpl::evaluate(size_t feature_ind) const |
||||
{ |
||||
CV_Assert(feature_ind < features_.size()); |
||||
|
||||
const vector<int>& feature = features_[feature_ind]; |
||||
int x = feature[0]; |
||||
int y = feature[1]; |
||||
int n = feature[2]; |
||||
return channels_[n].at<int>(y + position_.width, x + position_.height); |
||||
} |
||||
|
||||
Ptr<FeatureEvaluator> createFeatureEvaluator( |
||||
const vector<vector<int> >& features, const std::string& type) |
||||
{ |
||||
FeatureEvaluator *evaluator = NULL; |
||||
if( type == "acf" ) |
||||
evaluator = new ACFFeatureEvaluatorImpl(features); |
||||
else if( type == "icf" ) |
||||
evaluator = new ICFFeatureEvaluatorImpl(features); |
||||
else |
||||
CV_Error(CV_StsBadArg, "type value is either acf or icf"); |
||||
|
||||
return Ptr<FeatureEvaluator>(evaluator); |
||||
} |
||||
|
||||
vector<vector<int> > generateFeatures(Size window_size, const std::string& type, |
||||
int count, int channel_count) |
||||
{ |
||||
CV_Assert(count > 0); |
||||
vector<vector<int> > features; |
||||
if( type == "acf" ) |
||||
{ |
||||
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 ) |
||||
{ |
||||
int x = rng.uniform(0, window_size.width - 1); |
||||
int y = rng.uniform(0, window_size.height - 1); |
||||
int x_to = rng.uniform(x, window_size.width - 1); |
||||
int y_to = rng.uniform(y, window_size.height - 1); |
||||
int n = rng.uniform(0, channel_count - 1); |
||||
int f[] = {x, y, x_to, y_to, n}; |
||||
vector<int> feature(f, f + sizeof(f) / sizeof(*f)); |
||||
features.push_back(feature); |
||||
} |
||||
} |
||||
else |
||||
CV_Error(CV_StsBadArg, "type value is either acf or icf"); |
||||
|
||||
return features; |
||||
} |
||||
|
||||
void computeChannels(InputArray image, vector<Mat>& channels) |
||||
{ |
||||
Mat_<float> grad; |
||||
Mat_<float> angles; |
||||
Mat luv, gray, src; |
||||
|
||||
if(image.getMat().channels() > 1) |
||||
{ |
||||
src = Mat(image.getMat().rows, image.getMat().cols, CV_32FC3); |
||||
image.getMat().convertTo(src, CV_32FC3, 1./255); |
||||
|
||||
cvtColor(src, gray, CV_RGB2GRAY); |
||||
cvtColor(src, luv, CV_RGB2Luv); |
||||
} |
||||
else |
||||
{ |
||||
src = Mat(image.getMat().rows, image.getMat().cols, CV_32FC1); |
||||
image.getMat().convertTo(src, CV_32FC1, 1./255); |
||||
src.copyTo(gray); |
||||
} |
||||
|
||||
Mat_<float> row_der, col_der; |
||||
Sobel(gray, row_der, CV_32F, 0, 1); |
||||
Sobel(gray, col_der, CV_32F, 1, 0); |
||||
|
||||
cartToPolar(col_der, row_der, grad, angles, true); |
||||
//magnitude(row_der, col_der, grad);
|
||||
|
||||
Mat_<Vec6f> hist = Mat_<Vec6f>::zeros(grad.rows, grad.cols); |
||||
//const float to_deg = 180 / 3.1415926f;
|
||||
for (int row = 0; row < grad.rows; ++row) { |
||||
for (int col = 0; col < grad.cols; ++col) { |
||||
//float angle = atan2(row_der(row, col), col_der(row, col)) * to_deg;
|
||||
float angle = angles(row, col); |
||||
if (angle > 180) |
||||
angle -= 180; |
||||
if (angle < 0) |
||||
angle += 180; |
||||
int ind = (int)(angle / 30); |
||||
|
||||
// If angle == 180, prevent index overflow
|
||||
if (ind == 6) |
||||
ind = 5; |
||||
|
||||
hist(row, col)[ind] = grad(row, col) * 255; |
||||
} |
||||
} |
||||
|
||||
channels.clear(); |
||||
|
||||
if(image.getMat().channels() > 1) |
||||
{ |
||||
Mat luv_channels[3]; |
||||
split(luv, luv_channels); |
||||
for( int i = 0; i < 3; ++i ) |
||||
channels.push_back(luv_channels[i]); |
||||
} |
||||
|
||||
channels.push_back(grad); |
||||
|
||||
vector<Mat> hist_channels; |
||||
split(hist, hist_channels); |
||||
|
||||
for( size_t i = 0; i < hist_channels.size(); ++i ) |
||||
channels.push_back(hist_channels[i]); |
||||
} |
||||
|
||||
} /* namespace xobjdetect */ |
||||
} /* namespace cv */ |
@ -0,0 +1,95 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#ifndef _OPENCV_CASCADECLASSIFIER_H_ |
||||
#define _OPENCV_CASCADECLASSIFIER_H_ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
#define CC_CASCADE_FILENAME "cascade.xml" |
||||
#define CC_PARAMS_FILENAME "params.xml" |
||||
|
||||
#define CC_CASCADE_PARAMS "cascadeParams" |
||||
#define CC_STAGE_TYPE "stageType" |
||||
#define CC_FEATURE_TYPE "featureType" |
||||
#define CC_HEIGHT "height" |
||||
#define CC_WIDTH "width" |
||||
|
||||
#define CC_STAGE_NUM "stageNum" |
||||
#define CC_STAGES "stages" |
||||
#define CC_STAGE_PARAMS "stageParams" |
||||
|
||||
#define CC_BOOST "BOOST" |
||||
#define CC_BOOST_TYPE "boostType" |
||||
#define CC_DISCRETE_BOOST "DAB" |
||||
#define CC_REAL_BOOST "RAB" |
||||
#define CC_LOGIT_BOOST "LB" |
||||
#define CC_GENTLE_BOOST "GAB" |
||||
#define CC_MINHITRATE "minHitRate" |
||||
#define CC_MAXFALSEALARM "maxFalseAlarm" |
||||
#define CC_TRIM_RATE "weightTrimRate" |
||||
#define CC_MAX_DEPTH "maxDepth" |
||||
#define CC_WEAK_COUNT "maxWeakCount" |
||||
#define CC_STAGE_THRESHOLD "stageThreshold" |
||||
#define CC_WEAK_CLASSIFIERS "weakClassifiers" |
||||
#define CC_INTERNAL_NODES "internalNodes" |
||||
#define CC_LEAF_VALUES "leafValues" |
||||
|
||||
#define CC_FEATURES FEATURES |
||||
#define CC_FEATURE_PARAMS "featureParams" |
||||
#define CC_MAX_CAT_COUNT "maxCatCount" |
||||
#define CC_FEATURE_SIZE "featSize" |
||||
|
||||
#define CC_HAAR "HAAR" |
||||
#define CC_MODE "mode" |
||||
#define CC_MODE_BASIC "BASIC" |
||||
#define CC_MODE_CORE "CORE" |
||||
#define CC_MODE_ALL "ALL" |
||||
#define CC_RECTS "rects" |
||||
#define CC_TILTED "tilted" |
||||
|
||||
#define CC_LBP "LBP" |
||||
#define CC_RECT "rect" |
||||
|
||||
#endif |
@ -0,0 +1,131 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
float calcNormFactor( const Mat& sum, const Mat& sqSum ) |
||||
{ |
||||
CV_DbgAssert( sum.cols > 3 && sqSum.rows > 3 ); |
||||
Rect normrect( 1, 1, sum.cols - 3, sum.rows - 3 ); |
||||
size_t p0, p1, p2, p3; |
||||
CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, sum.step1() ) |
||||
double area = normrect.width * normrect.height; |
||||
const int *sp = sum.ptr<int>(); |
||||
int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3]; |
||||
const double *sqp = sqSum.ptr<double>(); |
||||
double valSqSum = sqp[p0] - sqp[p1] - sqp[p2] + sqp[p3]; |
||||
return (float) sqrt( (double) (area * valSqSum - (double)valSum * valSum) ); |
||||
} |
||||
|
||||
CvParams::CvParams() : name( "params" ) {} |
||||
void CvParams::printDefaults() const |
||||
{ std::cout << "--" << name << "--" << std::endl; } |
||||
void CvParams::printAttrs() const {} |
||||
bool CvParams::scanAttr( const std::string, const std::string ) { return false; } |
||||
|
||||
|
||||
//---------------------------- FeatureParams --------------------------------------
|
||||
|
||||
CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 ) |
||||
{ |
||||
name = CC_FEATURE_PARAMS; |
||||
} |
||||
|
||||
void CvFeatureParams::init( const CvFeatureParams& fp ) |
||||
{ |
||||
maxCatCount = fp.maxCatCount; |
||||
featSize = fp.featSize; |
||||
} |
||||
|
||||
void CvFeatureParams::write( FileStorage &fs ) const |
||||
{ |
||||
fs << CC_MAX_CAT_COUNT << maxCatCount; |
||||
fs << CC_FEATURE_SIZE << featSize; |
||||
} |
||||
|
||||
bool CvFeatureParams::read( const FileNode &node ) |
||||
{ |
||||
if ( node.empty() ) |
||||
return false; |
||||
maxCatCount = node[CC_MAX_CAT_COUNT]; |
||||
featSize = node[CC_FEATURE_SIZE]; |
||||
return ( maxCatCount >= 0 && featSize >= 1 ); |
||||
} |
||||
|
||||
Ptr<CvFeatureParams> CvFeatureParams::create() |
||||
{ |
||||
return Ptr<CvFeatureParams>(new CvLBPFeatureParams); |
||||
} |
||||
|
||||
//------------------------------------- FeatureEvaluator ---------------------------------------
|
||||
|
||||
void CvFeatureEvaluator::init(const CvFeatureParams *_featureParams, |
||||
int _maxSampleCount, Size _winSize ) |
||||
{ |
||||
CV_Assert(_maxSampleCount > 0); |
||||
featureParams = (CvFeatureParams *)_featureParams; |
||||
winSize = _winSize; |
||||
numFeatures = 0; |
||||
cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); |
||||
generateFeatures(); |
||||
} |
||||
|
||||
void CvFeatureEvaluator::setImage(const Mat &, uchar clsLabel, int idx, const std::vector<int>&) |
||||
{ |
||||
//CV_Assert(img.cols == winSize.width);
|
||||
//CV_Assert(img.rows == winSize.height);
|
||||
CV_Assert(idx < cls.rows); |
||||
cls.ptr<float>(idx)[0] = clsLabel; |
||||
} |
||||
|
||||
Ptr<CvFeatureEvaluator> CvFeatureEvaluator::create() |
||||
{ |
||||
return Ptr<CvFeatureEvaluator>(new CvLBPEvaluator); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,151 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#ifndef _OPENCV_FEATURES_H_ |
||||
#define _OPENCV_FEATURES_H_ |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#define FEATURES "features" |
||||
|
||||
#define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \ |
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p1) = (rect).x + (rect).width + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p2) = (rect).x + (step) * ((rect).y + (rect).height); \
|
||||
/* (x + w, y + h) */ \
|
||||
(p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height); |
||||
|
||||
#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \ |
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x - h, y + h) */ \
|
||||
(p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\
|
||||
/* (x + w, y + w) */ \
|
||||
(p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width); \
|
||||
/* (x + w - h, y + w + h) */ \
|
||||
(p3) = (rect).x + (rect).width - (rect).height \
|
||||
+ (step) * ((rect).y + (rect).width + (rect).height); |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
float calcNormFactor( const cv::Mat& sum, const cv::Mat& sqSum ); |
||||
|
||||
template<class Feature> |
||||
void _writeFeatures( const std::vector<Feature> features, cv::FileStorage &fs, const cv::Mat& featureMap ) |
||||
{ |
||||
fs << FEATURES << "["; |
||||
const cv::Mat_<int>& featureMap_ = (const cv::Mat_<int>&)featureMap; |
||||
for ( int fi = 0; fi < featureMap.cols; fi++ ) |
||||
if ( featureMap_(0, fi) >= 0 ) |
||||
{ |
||||
fs << "{"; |
||||
features[fi].write( fs ); |
||||
fs << "}"; |
||||
} |
||||
fs << "]"; |
||||
} |
||||
|
||||
class CvParams |
||||
{ |
||||
public: |
||||
CvParams(); |
||||
virtual ~CvParams() {} |
||||
// from|to file
|
||||
virtual void write( cv::FileStorage &fs ) const = 0; |
||||
virtual bool read( const cv::FileNode &node ) = 0; |
||||
// from|to screen
|
||||
virtual void printDefaults() const; |
||||
virtual void printAttrs() const; |
||||
virtual bool scanAttr( const std::string prmName, const std::string val ); |
||||
std::string name; |
||||
}; |
||||
|
||||
class CvFeatureParams : public CvParams |
||||
{ |
||||
public: |
||||
enum { HAAR = 0, LBP = 1, HOG = 2 }; |
||||
CvFeatureParams(); |
||||
virtual void init( const CvFeatureParams& fp ); |
||||
virtual void write( cv::FileStorage &fs ) const; |
||||
virtual bool read( const cv::FileNode &node ); |
||||
static cv::Ptr<CvFeatureParams> create(); |
||||
int maxCatCount; // 0 in case of numerical features
|
||||
int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features
|
||||
}; |
||||
|
||||
class CvFeatureEvaluator |
||||
{ |
||||
public: |
||||
virtual ~CvFeatureEvaluator() {} |
||||
virtual void init(const CvFeatureParams *_featureParams, |
||||
int _maxSampleCount, cv::Size _winSize ); |
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx, const std::vector<int> &feature_ind); |
||||
virtual void setWindow(const cv::Point& p) = 0; |
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const = 0; |
||||
virtual float operator()(int featureIdx) = 0; |
||||
static cv::Ptr<CvFeatureEvaluator> create(); |
||||
|
||||
int getNumFeatures() const { return numFeatures; } |
||||
int getMaxCatCount() const { return featureParams->maxCatCount; } |
||||
int getFeatureSize() const { return featureParams->featSize; } |
||||
const cv::Mat& getCls() const { return cls; } |
||||
float getCls(int si) const { return cls.at<float>(si, 0); } |
||||
protected: |
||||
virtual void generateFeatures() = 0; |
||||
|
||||
int npos, nneg; |
||||
int numFeatures; |
||||
cv::Size winSize; |
||||
CvFeatureParams *featureParams; |
||||
cv::Mat cls; |
||||
}; |
||||
|
||||
} |
||||
} |
||||
|
||||
#endif |
@ -1,316 +0,0 @@ |
||||
/*
|
||||
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2013, OpenCV Foundation, 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
|
||||
*/ |
||||
|
||||
#include <sstream> |
||||
using std::ostringstream; |
||||
|
||||
#include <iomanip> |
||||
using std::setfill; |
||||
using std::setw; |
||||
|
||||
#include <iostream> |
||||
using std::cout; |
||||
using std::endl; |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
using std::vector; |
||||
using std::string; |
||||
|
||||
using std::min; |
||||
using std::max; |
||||
|
||||
|
||||
namespace cv |
||||
{ |
||||
|
||||
namespace xobjdetect |
||||
{ |
||||
|
||||
|
||||
void ICFDetector::train(const vector<String>& pos_filenames, |
||||
const vector<String>& bg_filenames, |
||||
ICFDetectorParams params) |
||||
{ |
||||
|
||||
int color; |
||||
if(params.is_grayscale == false) |
||||
color = IMREAD_COLOR; |
||||
else |
||||
color = IMREAD_GRAYSCALE; |
||||
|
||||
model_n_rows_ = params.model_n_rows; |
||||
model_n_cols_ = params.model_n_cols; |
||||
ftype_ = params.features_type; |
||||
|
||||
Size model_size(params.model_n_cols, params.model_n_rows); |
||||
|
||||
vector<Mat> samples; /* positive samples + negative samples */ |
||||
Mat sample, resized_sample; |
||||
int pos_count = 0; |
||||
|
||||
for( size_t i = 0; i < pos_filenames.size(); ++i, ++pos_count ) |
||||
{ |
||||
cout << setw(6) << (i + 1) << "/" << pos_filenames.size() << "\r"; |
||||
Mat img = imread(pos_filenames[i], color); |
||||
resize(img, resized_sample, model_size); |
||||
samples.push_back(resized_sample.clone()); |
||||
} |
||||
cout << "\n"; |
||||
|
||||
int neg_count = 0; |
||||
RNG rng; |
||||
for( size_t i = 0; i < bg_filenames.size(); ++i ) |
||||
{ |
||||
cout << setw(6) << (i + 1) << "/" << bg_filenames.size() << "\r"; |
||||
Mat img = imread(bg_filenames[i], color); |
||||
for( int j = 0; j < params.bg_per_image; ++j, ++neg_count) |
||||
{ |
||||
Rect r; |
||||
r.x = rng.uniform(0, img.cols-model_size.width); |
||||
r.width = model_size.width; |
||||
r.y = rng.uniform(0, img.rows-model_size.height); |
||||
r.height = model_size.height; |
||||
sample = img.colRange(r.x, r.x + r.width).rowRange(r.y, r.y + r.height); |
||||
samples.push_back(sample.clone()); |
||||
} |
||||
} |
||||
cout << "\n"; |
||||
|
||||
Mat_<int> labels(1, pos_count + neg_count); |
||||
for( int i = 0; i < pos_count; ++i) |
||||
labels(0, i) = 1; |
||||
for( int i = pos_count; i < pos_count + neg_count; ++i ) |
||||
labels(0, i) = -1; |
||||
|
||||
|
||||
vector<vector<int> > features; |
||||
if(params.is_grayscale == false) |
||||
features = generateFeatures(model_size, params.features_type, params.feature_count, 10); |
||||
else |
||||
features = generateFeatures(model_size, params.features_type, params.feature_count, 7); |
||||
|
||||
Ptr<FeatureEvaluator> evaluator = createFeatureEvaluator(features, params.features_type); |
||||
|
||||
|
||||
Mat_<int> data = Mat_<int>::zeros((int)features.size(), (int)samples.size()); |
||||
Mat_<int> feature_col(1, (int)samples.size()); |
||||
|
||||
vector<Mat> channels; |
||||
for( int i = 0; i < (int)samples.size(); ++i ) |
||||
{ |
||||
cout << setw(6) << i << "/" << samples.size() << "\r"; |
||||
computeChannels(samples[i], channels); |
||||
evaluator->setChannels(channels); |
||||
//evaluator->assertChannels();
|
||||
evaluator->evaluateAll(feature_col); |
||||
|
||||
CV_Assert(feature_col.cols == (int)features.size()); |
||||
|
||||
for( int j = 0; j < feature_col.cols; ++j ) |
||||
data(j, i) = feature_col(0, j); |
||||
} |
||||
cout << "\n"; |
||||
samples.clear(); |
||||
|
||||
WaldBoostParams wparams; |
||||
wparams.weak_count = params.weak_count; |
||||
wparams.alpha = params.alpha; |
||||
|
||||
waldboost_ = createWaldBoost(wparams); |
||||
vector<int> indices = waldboost_->train(data, labels, params.use_fast_log); |
||||
cout << "indices: "; |
||||
for( size_t i = 0; i < indices.size(); ++i ) |
||||
cout << indices[i] << " "; |
||||
cout << endl; |
||||
|
||||
features_.clear(); |
||||
for( size_t i = 0; i < indices.size(); ++i ) |
||||
features_.push_back(features[indices[i]]); |
||||
} |
||||
|
||||
void ICFDetector::write(FileStorage& fs) const |
||||
{ |
||||
fs << "{"; |
||||
fs << "model_n_rows" << model_n_rows_; |
||||
fs << "model_n_cols" << model_n_cols_; |
||||
fs << "ftype" << String(ftype_.c_str()); |
||||
fs << "waldboost"; |
||||
waldboost_->write(fs); |
||||
fs << "features" << "["; |
||||
for( size_t i = 0; i < features_.size(); ++i ) |
||||
{ |
||||
fs << features_[i]; |
||||
} |
||||
fs << "]"; |
||||
fs << "}"; |
||||
} |
||||
|
||||
void ICFDetector::read(const FileNode& node) |
||||
{ |
||||
waldboost_ = Ptr<WaldBoost>(createWaldBoost(WaldBoostParams())); |
||||
String f_temp; |
||||
node["model_n_rows"] >> model_n_rows_; |
||||
node["model_n_cols"] >> model_n_cols_; |
||||
f_temp = (String)node["ftype"];
|
||||
this->ftype_ = (string)f_temp.c_str(); |
||||
waldboost_->read(node["waldboost"]); |
||||
FileNode features = node["features"]; |
||||
features_.clear(); |
||||
vector<int> p; |
||||
for( FileNodeIterator n = features.begin(); n != features.end(); ++n ) |
||||
{ |
||||
(*n) >> p; |
||||
features_.push_back(p); |
||||
} |
||||
} |
||||
|
||||
void ICFDetector::detect(const Mat& img, vector<Rect>& objects, |
||||
float scaleFactor, Size minSize, Size maxSize, float threshold, int slidingStep, std::vector<float>& values) |
||||
{ |
||||
|
||||
|
||||
float scale_from = min(model_n_cols_ / (float)maxSize.width, |
||||
model_n_rows_ / (float)maxSize.height); |
||||
float scale_to = max(model_n_cols_ / (float)minSize.width, |
||||
model_n_rows_ / (float)minSize.height); |
||||
objects.clear(); |
||||
Ptr<FeatureEvaluator> evaluator = createFeatureEvaluator(features_, ftype_); |
||||
Mat rescaled_image; |
||||
vector<Mat> channels; |
||||
|
||||
for( float scale = scale_from; scale < scale_to + 0.001; scale *= scaleFactor ) |
||||
{ |
||||
int new_width = int(img.cols * scale); |
||||
new_width -= new_width % 4; |
||||
int new_height = int(img.rows * scale); |
||||
new_height -= new_height % 4; |
||||
|
||||
resize(img, rescaled_image, Size(new_width, new_height)); |
||||
computeChannels(rescaled_image, channels); |
||||
evaluator->setChannels(channels); |
||||
for( int row = 0; row <= rescaled_image.rows - model_n_rows_; row += slidingStep) |
||||
{ |
||||
for( int col = 0; col <= rescaled_image.cols - model_n_cols_; |
||||
col += slidingStep ) |
||||
{ |
||||
evaluator->setPosition(Size(row, col)); |
||||
float value = waldboost_->predict(evaluator); |
||||
if( value > threshold ) |
||||
{ |
||||
values.push_back(value); |
||||
int x = (int)(col / scale); |
||||
int y = (int)(row / scale); |
||||
int width = (int)(model_n_cols_ / scale); |
||||
int height = (int)(model_n_rows_ / scale); |
||||
objects.push_back(Rect(x, y, width, height)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
void ICFDetector::detect(const Mat& img, vector<Rect>& objects, |
||||
float minScaleFactor, float maxScaleFactor, float factorStep, float threshold, int slidingStep, std::vector<float>& values) |
||||
{ |
||||
|
||||
if(factorStep <= 0) |
||||
{ |
||||
CV_Error_(CV_StsBadArg, ("factorStep must be > 0")); |
||||
} |
||||
|
||||
objects.clear(); |
||||
Ptr<FeatureEvaluator> evaluator = createFeatureEvaluator(features_, ftype_); |
||||
Mat rescaled_image; |
||||
vector<Mat> channels; |
||||
|
||||
for( float scale = minScaleFactor; scale < maxScaleFactor + 0.001; scale += factorStep ) |
||||
{ |
||||
if(scale < 1.0) |
||||
resize(img, rescaled_image, Size(),scale, scale, INTER_AREA); |
||||
else if (scale > 1.0) |
||||
resize(img, rescaled_image, Size(),scale, scale, INTER_CUBIC); |
||||
else //scale == 1.0
|
||||
img.copyTo(rescaled_image); |
||||
|
||||
computeChannels(rescaled_image, channels); |
||||
evaluator->setChannels(channels); |
||||
for( int row = 0; row <= rescaled_image.rows - model_n_rows_; row += slidingStep) |
||||
{ |
||||
for( int col = 0; col <= rescaled_image.cols - model_n_cols_; |
||||
col += slidingStep ) |
||||
{ |
||||
evaluator->setPosition(Size(row, col)); |
||||
float value = waldboost_->predict(evaluator); |
||||
if( value > threshold ) |
||||
{ |
||||
values.push_back(value); |
||||
int x = (int)(col / scale); |
||||
int y = (int)(row / scale); |
||||
int width = (int)(model_n_cols_ / scale); |
||||
int height = (int)(model_n_rows_ / scale); |
||||
objects.push_back(Rect(x, y, width, height)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
void write(FileStorage& fs, String&, const ICFDetector& detector) |
||||
{ |
||||
detector.write(fs); |
||||
} |
||||
|
||||
void read(const FileNode& node, ICFDetector& d, |
||||
const ICFDetector& default_value) |
||||
{ |
||||
if( node.empty() ) |
||||
d = default_value; |
||||
else |
||||
d.read(node); |
||||
} |
||||
|
||||
} /* namespace xobjdetect */ |
||||
} /* namespace cv */ |
@ -0,0 +1,128 @@ |
||||
|
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
CvLBPFeatureParams::CvLBPFeatureParams() |
||||
{ |
||||
maxCatCount = 256; |
||||
name = LBPF_NAME; |
||||
} |
||||
|
||||
void CvLBPEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize) |
||||
{ |
||||
CV_Assert( _maxSampleCount > 0); |
||||
sum.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1); |
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize ); |
||||
} |
||||
|
||||
void CvLBPEvaluator::setImage(const Mat &img, uchar clsLabel, int idx, |
||||
const std::vector<int> &feature_ind) |
||||
{ |
||||
CV_DbgAssert( !sum.empty() ); |
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx, feature_ind ); |
||||
integral( img, sum ); |
||||
cur_sum = sum; |
||||
offset_ = int(sum.ptr<int>(1) - sum.ptr<int>()); |
||||
for (size_t i = 0; i < feature_ind.size(); ++i) { |
||||
features[feature_ind[i]].calcPoints(offset_); |
||||
} |
||||
} |
||||
|
||||
void CvLBPEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const |
||||
{ |
||||
_writeFeatures( features, fs, featureMap ); |
||||
} |
||||
|
||||
void CvLBPEvaluator::generateFeatures() |
||||
{ |
||||
int offset = winSize.width + 1; |
||||
for( int x = 0; x < winSize.width; x++ ) |
||||
for( int y = 0; y < winSize.height; y++ ) |
||||
for( int w = 1; w <= winSize.width / 3; w++ ) |
||||
for( int h = 1; h <= winSize.height / 3; h++ ) |
||||
if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) ) |
||||
features.push_back( Feature(offset, x, y, w, h ) ); |
||||
numFeatures = (int)features.size(); |
||||
} |
||||
|
||||
CvLBPEvaluator::Feature::Feature() |
||||
{ |
||||
rect = cvRect(0, 0, 0, 0); |
||||
} |
||||
|
||||
CvLBPEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) |
||||
{ |
||||
x_ = x; |
||||
y_ = y; |
||||
block_w_ = _blockWidth; |
||||
block_h_ = _blockHeight; |
||||
offset_ = offset; |
||||
calcPoints(offset); |
||||
} |
||||
|
||||
void CvLBPEvaluator::Feature::calcPoints(int offset) |
||||
{ |
||||
Rect tr = rect = cvRect(x_, y_, block_w_, block_h_); |
||||
CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset ) |
||||
tr.x += 2*rect.width; |
||||
CV_SUM_OFFSETS( p[2], p[3], p[6], p[7], tr, offset ) |
||||
tr.y +=2*rect.height; |
||||
CV_SUM_OFFSETS( p[10], p[11], p[14], p[15], tr, offset ) |
||||
tr.x -= 2*rect.width; |
||||
CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset ) |
||||
offset_ = offset; |
||||
} |
||||
|
||||
void CvLBPEvaluator::Feature::write(FileStorage &fs) const |
||||
{ |
||||
fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]"; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,116 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#ifndef _OPENCV_LBPFEATURES_H_ |
||||
#define _OPENCV_LBPFEATURES_H_ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
|
||||
#define LBPF_NAME "lbpFeatureParams" |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
struct CvLBPFeatureParams : CvFeatureParams |
||||
{ |
||||
CvLBPFeatureParams(); |
||||
|
||||
}; |
||||
|
||||
class CvLBPEvaluator : public CvFeatureEvaluator |
||||
{ |
||||
public: |
||||
virtual ~CvLBPEvaluator() {} |
||||
virtual void init(const CvFeatureParams *_featureParams, |
||||
int _maxSampleCount, cv::Size _winSize ); |
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx, const std::vector<int> &feature_ind); |
||||
virtual void setWindow(const cv::Point& p) |
||||
{ cur_sum = sum.rowRange(p.y, p.y + winSize.height).colRange(p.x, p.x + winSize.width); } |
||||
virtual float operator()(int featureIdx) |
||||
{ return (float)features[featureIdx].calc( cur_sum ); } |
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; |
||||
protected: |
||||
virtual void generateFeatures(); |
||||
|
||||
class Feature |
||||
{ |
||||
public: |
||||
Feature(); |
||||
Feature( int offset, int x, int y, int _block_w, int _block_h ); |
||||
uchar calc( const cv::Mat& _sum ); |
||||
void write( cv::FileStorage &fs ) const; |
||||
|
||||
cv::Rect rect; |
||||
int p[16]; |
||||
|
||||
int x_, y_, block_w_, block_h_, offset_; |
||||
void calcPoints(int offset); |
||||
}; |
||||
std::vector<Feature> features; |
||||
|
||||
cv::Mat sum, cur_sum; |
||||
int offset_; |
||||
}; |
||||
|
||||
inline uchar CvLBPEvaluator::Feature::calc(const cv::Mat &_sum) |
||||
{ |
||||
const int* psum = _sum.ptr<int>(); |
||||
|
||||
int cval = psum[p[5]] - psum[p[6]] - psum[p[9]] + psum[p[10]]; |
||||
|
||||
return (uchar)((psum[p[0]] - psum[p[1]] - psum[p[4]] + psum[p[5]] >= cval ? 128 : 0) | // 0
|
||||
(psum[p[1]] - psum[p[2]] - psum[p[5]] + psum[p[6]] >= cval ? 64 : 0) | // 1
|
||||
(psum[p[2]] - psum[p[3]] - psum[p[6]] + psum[p[7]] >= cval ? 32 : 0) | // 2
|
||||
(psum[p[6]] - psum[p[7]] - psum[p[10]] + psum[p[11]] >= cval ? 16 : 0) | // 5
|
||||
(psum[p[10]] - psum[p[11]] - psum[p[14]] + psum[p[15]] >= cval ? 8 : 0) | // 8
|
||||
(psum[p[9]] - psum[p[10]] - psum[p[13]] + psum[p[14]] >= cval ? 4 : 0) | // 7
|
||||
(psum[p[8]] - psum[p[9]] - psum[p[12]] + psum[p[13]] >= cval ? 2 : 0) | // 6
|
||||
(psum[p[4]] - psum[p[5]] - psum[p[8]] + psum[p[9]] >= cval ? 1 : 0)); // 3
|
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
#endif |
@ -1,236 +0,0 @@ |
||||
/*
|
||||
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2013, OpenCV Foundation, 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
|
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv |
||||
{ |
||||
namespace xobjdetect |
||||
{ |
||||
|
||||
/* Cumulative sum by rows */ |
||||
static void cumsum(const Mat_<float>& src, Mat_<float> dst) |
||||
{ |
||||
CV_Assert(src.cols > 0); |
||||
|
||||
for( int row = 0; row < src.rows; ++row ) |
||||
{ |
||||
dst(row, 0) = src(row, 0); |
||||
for( int col = 1; col < src.cols; ++col ) |
||||
{ |
||||
dst(row, col) = dst(row, col - 1) + src(row, col); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//fast log implementation. A bit less accurate but ~5x faster
|
||||
inline float fast_log2 (float val) |
||||
{ |
||||
int * const exp_ptr = reinterpret_cast <int *> (&val); |
||||
int x = *exp_ptr; |
||||
const int log_2 = ((x >> 23) & 255) - 128; |
||||
x &= ~(255 << 23); |
||||
x += 127 << 23; |
||||
*exp_ptr = x; |
||||
|
||||
val = ((-1.0f/3) * val + 2) * val - 2.0f/3; // (1)
|
||||
|
||||
return (val + log_2); |
||||
}
|
||||
|
||||
inline float fast_log (const float &val) |
||||
{ |
||||
return (fast_log2 (val) * 0.69314718f); |
||||
} |
||||
|
||||
int Stump::train(const Mat& data, const Mat& labels, const Mat& weights, const std::vector<int>& visited_features, bool use_fast_log) |
||||
{ |
||||
CV_Assert(labels.rows == 1 && labels.cols == data.cols); |
||||
CV_Assert(weights.rows == 1 && weights.cols == data.cols); |
||||
CV_Assert(data.cols > 1); |
||||
/* Assert that data and labels have int type */ |
||||
/* Assert that weights have float type */ |
||||
|
||||
Mat_<int> d = Mat_<int>::zeros(1, data.cols); |
||||
const Mat_<int>& l = labels; |
||||
const Mat_<float>& w = weights; |
||||
|
||||
Mat_<int> indices(1, l.cols); |
||||
|
||||
Mat_<int> sorted_d(1, data.cols); |
||||
Mat_<int> sorted_l(1, l.cols); |
||||
Mat_<float> sorted_w(1, w.cols); |
||||
|
||||
|
||||
Mat_<float> pos_c_w = Mat_<float>::zeros(1, w.cols); |
||||
Mat_<float> neg_c_w = Mat_<float>::zeros(1, w.cols); |
||||
|
||||
|
||||
float min_err = FLT_MAX; |
||||
int min_row = -1; |
||||
int min_thr = -1; |
||||
int min_pol = -1; |
||||
float min_pos = 1; |
||||
float min_neg = -1; |
||||
float eps = 1.0f / (4 * l.cols); |
||||
|
||||
/* For every feature */ |
||||
for( int row = 0; row < data.rows; ++row ) |
||||
{ |
||||
if(std::find(visited_features.begin(), visited_features.end(), row) != visited_features.end()) { |
||||
//feature discarded
|
||||
continue; |
||||
} |
||||
data.row(row).copyTo(d.row(0)); |
||||
|
||||
sortIdx(d, indices, cv::SORT_EVERY_ROW | cv::SORT_ASCENDING); |
||||
|
||||
for( int col = 0; col < indices.cols; ++col ) |
||||
{ |
||||
int ind = indices(0, col); |
||||
sorted_d(0, col) = d(0, ind); |
||||
sorted_l(0, col) = l(0, ind); |
||||
sorted_w(0, col) = w(0, ind); |
||||
} |
||||
|
||||
Mat_<float> pos_w = Mat_<float>::zeros(1, w.cols); |
||||
Mat_<float> neg_w = Mat_<float>::zeros(1, w.cols); |
||||
for( int col = 0; col < d.cols; ++col ) |
||||
{ |
||||
float weight = sorted_w(0, col); |
||||
if( sorted_l(0, col) == +1) |
||||
pos_w(0, col) = weight; |
||||
else |
||||
neg_w(0, col) = weight; |
||||
} |
||||
|
||||
cumsum(pos_w, pos_c_w); |
||||
cumsum(neg_w, neg_c_w); |
||||
|
||||
float pos_total_w = pos_c_w(0, w.cols - 1); |
||||
float neg_total_w = neg_c_w(0, w.cols - 1); |
||||
|
||||
for( int col = 0; col < w.cols - 1; ++col ) |
||||
{ |
||||
float err, h_pos, h_neg; |
||||
float pos_wrong, pos_right; |
||||
float neg_wrong, neg_right; |
||||
|
||||
/* Direct polarity */ |
||||
|
||||
pos_wrong = pos_c_w(0, col); |
||||
pos_right = pos_total_w - pos_wrong; |
||||
|
||||
neg_right = neg_c_w(0, col); |
||||
neg_wrong = neg_total_w - neg_right; |
||||
|
||||
err = sqrt(pos_right * neg_wrong) + sqrt(pos_wrong * neg_right); |
||||
|
||||
if(use_fast_log) |
||||
{ |
||||
h_pos = .5f * fast_log((pos_right + eps) / (pos_wrong + eps)); |
||||
h_neg = .5f * fast_log((neg_wrong + eps) / (neg_right + eps)); |
||||
} |
||||
else |
||||
{ |
||||
h_pos = .5f * log((pos_right + eps) / (pos_wrong + eps)); |
||||
h_neg = .5f * log((neg_wrong + eps) / (neg_right + eps)); |
||||
} |
||||
|
||||
if( err < min_err ) |
||||
{ |
||||
min_err = err; |
||||
min_row = row; |
||||
min_thr = (sorted_d(0, col) + sorted_d(0, col + 1)) / 2; |
||||
min_pol = +1; |
||||
min_pos = h_pos; |
||||
min_neg = h_neg; |
||||
} |
||||
|
||||
/* Opposite polarity */ |
||||
|
||||
swap(pos_right, pos_wrong); |
||||
swap(neg_right, neg_wrong); |
||||
|
||||
err = sqrt(pos_right * neg_wrong) + sqrt(pos_wrong * neg_right); |
||||
|
||||
if( err < min_err ) |
||||
{ |
||||
min_err = err; |
||||
min_row = row; |
||||
min_thr = (sorted_d(0, col) + sorted_d(0, col + 1)) / 2; |
||||
min_pol = -1; |
||||
min_pos = -h_pos; |
||||
min_neg = -h_neg; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
threshold_ = min_thr; |
||||
polarity_ = min_pol; |
||||
pos_value_ = min_pos; |
||||
neg_value_ = min_neg; |
||||
|
||||
return min_row; |
||||
} |
||||
|
||||
float Stump::predict(int value) const |
||||
{ |
||||
return polarity_ * (value - threshold_) > 0 ? pos_value_ : neg_value_; |
||||
} |
||||
|
||||
|
||||
void read(const FileNode& node, Stump& s, const Stump& default_value) |
||||
{ |
||||
if( node.empty() ) |
||||
s = default_value; |
||||
else |
||||
s.read(node); |
||||
} |
||||
|
||||
void write(FileStorage& fs, String&, const Stump& s) |
||||
{ |
||||
s.write(fs); |
||||
} |
||||
|
||||
} /* namespace xobjdetect */ |
||||
} /* namespace cv */ |
@ -0,0 +1,94 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#ifndef __OPENCV_XOBJDETECT_WALDBOOST_HPP__ |
||||
#define __OPENCV_XOBJDETECT_WALDBOOST_HPP__ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
class WaldBoost { |
||||
public: |
||||
WaldBoost(int weak_count); |
||||
WaldBoost(); |
||||
std::vector<int> get_feature_indices(); |
||||
|
||||
void detect(Ptr<CvFeatureEvaluator> eval, |
||||
const Mat& img, |
||||
const std::vector<float>& scales, |
||||
std::vector<Rect>& bboxes, |
||||
Mat1f& confidences); |
||||
|
||||
void detect(Ptr<CvFeatureEvaluator> eval, |
||||
const Mat& img, |
||||
const std::vector<float>& scales, |
||||
std::vector<Rect>& bboxes, |
||||
std::vector<double>& confidences); |
||||
|
||||
void fit(Mat& data_pos, Mat& data_neg); |
||||
int predict(Ptr<CvFeatureEvaluator> eval, float *h) const; |
||||
void save(const std::string& filename); |
||||
void load(const std::string& filename); |
||||
|
||||
void read(const FileNode &node); |
||||
void write(FileStorage &fs) const; |
||||
|
||||
void reset(int weak_count); |
||||
~WaldBoost(); |
||||
|
||||
private: |
||||
int weak_count_; |
||||
std::vector<float> thresholds_; |
||||
std::vector<float> alphas_; |
||||
std::vector<int> feature_indices_; |
||||
std::vector<int> polarities_; |
||||
std::vector<float> cascade_thresholds_; |
||||
}; |
||||
|
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,222 @@ |
||||
/*
|
||||
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 |
||||
(3-clause BSD License) |
||||
|
||||
Copyright (C) 2000-2015, Intel Corporation, all rights reserved. |
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. |
||||
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. |
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. |
||||
Copyright (C) 2015, OpenCV Foundation, all rights reserved. |
||||
Copyright (C) 2015, Itseez 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: |
||||
|
||||
* Redistributions of source code must retain the above copyright notice, |
||||
this list of conditions and the following disclaimer. |
||||
|
||||
* Redistributions 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. |
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors |
||||
may 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 copyright holders 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. |
||||
*/ |
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
using std::cerr; |
||||
using std::endl; |
||||
using std::vector; |
||||
using std::string; |
||||
|
||||
namespace cv { |
||||
namespace xobjdetect { |
||||
|
||||
static vector<Mat> sample_patches( |
||||
const string& path, |
||||
int n_rows, |
||||
int n_cols, |
||||
size_t n_patches) |
||||
{ |
||||
vector<String> filenames; |
||||
glob(path, filenames); |
||||
vector<Mat> patches; |
||||
size_t patch_count = 0; |
||||
for (size_t i = 0; i < filenames.size(); ++i) { |
||||
Mat img = imread(filenames[i], CV_LOAD_IMAGE_GRAYSCALE); |
||||
for (int row = 0; row + n_rows < img.rows; row += n_rows) { |
||||
for (int col = 0; col + n_cols < img.cols; col += n_cols) { |
||||
patches.push_back(img(Rect(col, row, n_cols, n_rows)).clone()); |
||||
patch_count += 1; |
||||
if (patch_count == n_patches) { |
||||
goto sampling_finished; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
sampling_finished: |
||||
return patches; |
||||
} |
||||
|
||||
static vector<Mat> read_imgs(const string& path) |
||||
{ |
||||
vector<String> filenames; |
||||
glob(path, filenames); |
||||
vector<Mat> imgs; |
||||
for (size_t i = 0; i < filenames.size(); ++i) { |
||||
imgs.push_back(imread(filenames[i], CV_LOAD_IMAGE_GRAYSCALE)); |
||||
} |
||||
return imgs; |
||||
} |
||||
|
||||
void WBDetectorImpl::read(const FileNode& node) |
||||
{ |
||||
boost_.read(node); |
||||
} |
||||
|
||||
|
||||
void WBDetectorImpl::write(FileStorage &fs) const |
||||
{ |
||||
boost_.write(fs); |
||||
} |
||||
|
||||
void WBDetectorImpl::train( |
||||
const string& pos_samples_path, |
||||
const string& neg_imgs_path) |
||||
{ |
||||
|
||||
vector<Mat> pos_imgs = read_imgs(pos_samples_path); |
||||
vector<Mat> neg_imgs = sample_patches(neg_imgs_path, 24, 24, pos_imgs.size() * 10); |
||||
|
||||
assert(pos_imgs.size()); |
||||
assert(neg_imgs.size()); |
||||
|
||||
int n_features; |
||||
Mat pos_data, neg_data; |
||||
|
||||
Ptr<CvFeatureEvaluator> eval = CvFeatureEvaluator::create(); |
||||
eval->init(CvFeatureParams::create(), 1, Size(24, 24)); |
||||
n_features = eval->getNumFeatures(); |
||||
|
||||
const int stages[] = {64, 128, 256, 512, 1024}; |
||||
const int stage_count = sizeof(stages) / sizeof(*stages); |
||||
const int stage_neg = (int)(pos_imgs.size() * 5); |
||||
const int max_per_image = 100; |
||||
|
||||
const float scales_arr[] = {.3f, .4f, .5f, .6f, .7f, .8f, .9f, 1.0f}; |
||||
const vector<float> scales(scales_arr, |
||||
scales_arr + sizeof(scales_arr) / sizeof(*scales_arr)); |
||||
|
||||
vector<String> neg_filenames; |
||||
glob(neg_imgs_path, neg_filenames); |
||||
|
||||
|
||||
for (int i = 0; i < stage_count; ++i) { |
||||
|
||||
cerr << "compute features" << endl; |
||||
|
||||
pos_data = Mat1b(n_features, (int)pos_imgs.size()); |
||||
neg_data = Mat1b(n_features, (int)neg_imgs.size()); |
||||
|
||||
for (size_t k = 0; k < pos_imgs.size(); ++k) { |
||||
eval->setImage(pos_imgs[k], +1, 0, boost_.get_feature_indices()); |
||||
for (int j = 0; j < n_features; ++j) { |
||||
pos_data.at<uchar>(j, (int)k) = (uchar)(*eval)(j); |
||||
} |
||||
} |
||||
|
||||
for (size_t k = 0; k < neg_imgs.size(); ++k) { |
||||
eval->setImage(neg_imgs[k], 0, 0, boost_.get_feature_indices()); |
||||
for (int j = 0; j < n_features; ++j) { |
||||
neg_data.at<uchar>(j, (int)k) = (uchar)(*eval)(j); |
||||
} |
||||
} |
||||
|
||||
|
||||
boost_.reset(stages[i]); |
||||
boost_.fit(pos_data, neg_data); |
||||
|
||||
if (i + 1 == stage_count) { |
||||
break; |
||||
} |
||||
|
||||
int bootstrap_count = 0; |
||||
size_t img_i = 0; |
||||
for (; img_i < neg_filenames.size(); ++img_i) { |
||||
cerr << "win " << bootstrap_count << "/" << stage_neg |
||||
<< " img " << (img_i + 1) << "/" << neg_filenames.size() << "\r"; |
||||
Mat img = imread(neg_filenames[img_i], CV_LOAD_IMAGE_GRAYSCALE); |
||||
vector<Rect> bboxes; |
||||
Mat1f confidences; |
||||
boost_.detect(eval, img, scales, bboxes, confidences); |
||||
|
||||
if (confidences.rows > 0) { |
||||
Mat1i indices; |
||||
sortIdx(confidences, indices, |
||||
CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING); |
||||
|
||||
int win_count = min(max_per_image, confidences.rows); |
||||
win_count = min(win_count, stage_neg - bootstrap_count); |
||||
Mat window; |
||||
for (int k = 0; k < win_count; ++k) { |
||||
resize(img(bboxes[indices(k, 0)]), window, Size(24, 24)); |
||||
neg_imgs.push_back(window.clone()); |
||||
bootstrap_count += 1; |
||||
} |
||||
if (bootstrap_count >= stage_neg) { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
cerr << "bootstrapped " << bootstrap_count << " windows from " |
||||
<< (img_i + 1) << " images" << endl; |
||||
} |
||||
} |
||||
|
||||
void WBDetectorImpl::detect( |
||||
const Mat& img, |
||||
vector<Rect> &bboxes, |
||||
vector<double> &confidences) |
||||
{ |
||||
Mat test_img = img.clone(); |
||||
bboxes.clear(); |
||||
confidences.clear(); |
||||
vector<float> scales; |
||||
for (float scale = 0.2f; scale < 1.2f; scale *= 1.1f) { |
||||
scales.push_back(scale); |
||||
} |
||||
Ptr<CvFeatureParams> params = CvFeatureParams::create(); |
||||
Ptr<CvFeatureEvaluator> eval = CvFeatureEvaluator::create(); |
||||
eval->init(params, 1, Size(24, 24)); |
||||
boost_.detect(eval, img, scales, bboxes, confidences); |
||||
assert(confidences.size() == bboxes.size()); |
||||
} |
||||
|
||||
Ptr<WBDetector> |
||||
WBDetector::create() |
||||
{ |
||||
return Ptr<WBDetector>(new WBDetectorImpl()); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
add_subdirectory(waldboost_detector) |
@ -1,4 +1,4 @@ |
||||
set(name fcw_train) |
||||
set(name waldboost_detector) |
||||
set(the_target opencv_${name}) |
||||
|
||||
set(OPENCV_${the_target}_DEPS opencv_core opencv_imgcodecs opencv_videoio |
@ -0,0 +1,46 @@ |
||||
#include <opencv2/xobjdetect.hpp> |
||||
#include <opencv2/imgcodecs/imgcodecs_c.h> |
||||
#include <opencv2/imgproc.hpp> |
||||
#include <iostream> |
||||
#include <cstdio> |
||||
using namespace std; |
||||
using namespace cv; |
||||
using namespace cv::xobjdetect; |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
if (argc < 5) { |
||||
cerr << "Usage: " << argv[0] << " train <model_filename> <pos_path> <neg_path>" << endl; |
||||
cerr << " " << argv[0] << " detect <model_filename> <img_filename> <out_filename> <labelling_filename>" << endl; |
||||
return 0; |
||||
} |
||||
|
||||
string mode = argv[1]; |
||||
Ptr<WBDetector> detector = WBDetector::create(); |
||||
if (mode == "train") { |
||||
assert(argc == 5); |
||||
detector->train(argv[3], argv[4]); |
||||
FileStorage fs(argv[2], FileStorage::WRITE); |
||||
fs << "waldboost"; |
||||
detector->write(fs); |
||||
} else if (mode == "detect") { |
||||
assert(argc == 6); |
||||
vector<Rect> bboxes; |
||||
vector<double> confidences; |
||||
Mat img = imread(argv[3], CV_LOAD_IMAGE_GRAYSCALE); |
||||
FileStorage fs(argv[2], FileStorage::READ); |
||||
detector->read(fs.getFirstTopLevelNode()); |
||||
detector->detect(img, bboxes, confidences); |
||||
|
||||
FILE *fhandle = fopen(argv[5], "a"); |
||||
for (size_t i = 0; i < bboxes.size(); ++i) { |
||||
Rect o = bboxes[i]; |
||||
fprintf(fhandle, "%s;%u;%u;%u;%u;%lf\n", |
||||
argv[3], o.x, o.y, o.width, o.height, confidences[i]); |
||||
} |
||||
for (size_t i = 0; i < bboxes.size(); ++i) { |
||||
rectangle(img, bboxes[i], Scalar(255, 0, 0)); |
||||
} |
||||
imwrite(argv[4], img); |
||||
} |
||||
} |
Loading…
Reference in new issue