sliding_window_object_detector_trainer_node.cpp
Go to the documentation of this file.
3 
4 #include <iostream>
5 namespace jsk_perception
6 {
8 #if CV_MAJOR_VERSION < 3
9  : supportVectorMachine_(new cv::SVM)
10 #endif
11  {
12 #if CV_MAJOR_VERSION >= 3
13  this->supportVectorMachine_ = cv::ml::SVM::create();
14 #endif
15  nh_.getParam("dataset_path", this->dataset_path_);
16  nh_.getParam("object_dataset_filename", this->object_dataset_filename_);
17  nh_.param<std::string>("object_dataset_topic", this->object_dataset_topic_, "/dataset/roi");
18  nh_.getParam("nonobject_dataset_filename", this->nonobject_dataset_filename_);
19  nh_.param<std::string>("nonobject_dataset_topic", this->nonobject_dataset_topic_, "/dataset/background/roi");
20  nh_.getParam("classifier_name", this->trained_classifier_name_);
21  nh_.getParam("swindow_x", this->swindow_x_);
22  nh_.getParam("swindow_y", this->swindow_y_);
23  nh_.param<std::string>("manifest_filename", this->manifest_filename_, "sliding_window_trainer_manifest.xml");
24 
25  ROS_INFO("--Training Classifier");
26  std::string pfilename = dataset_path_ + this->object_dataset_filename_;
27  std::string nfilename = dataset_path_ + this->nonobject_dataset_filename_;
28  trainObjectClassifier(pfilename, nfilename);
29  ROS_INFO("--Trained Successfully..");
30 
31  /*write the training manifest*/
32  std::string manifest_filename = this->manifest_filename_;
33  cv::FileStorage fs(manifest_filename, cv::FileStorage::WRITE);
34  this->writeTrainingManifestToDirectory(fs);
35  fs.release();
36 
37  cv::destroyAllWindows();
38  nh_.shutdown();
39  }
40 
42  std::string pfilename, std::string nfilename)
43  {
44  cv::Mat featureMD;
45  cv::Mat labelMD;
46  std::string topic_name = this->object_dataset_topic_;
47  this->readDataset(pfilename, topic_name, featureMD, labelMD, true, 1);
48  ROS_INFO("Info: Total Object Sample: %d", featureMD.rows);
49 
50  topic_name = this->nonobject_dataset_topic_;
51  this->readDataset(nfilename, topic_name, featureMD, labelMD, true, -1);
52  ROS_INFO("Info: Total Training Features: %d", featureMD.rows);
53 
54  try {
55  this->trainBinaryClassSVM(featureMD, labelMD);
56  this->supportVectorMachine_->save(
57  this->trained_classifier_name_.c_str());
58  } catch(std::exception &e) {
59  ROS_ERROR("--ERROR: PLEASE CHECK YOUR DATA \n%s", e.what());
60  std::_Exit(EXIT_FAILURE);
61  }
62  }
63 
65  std::string filename, std::string topic_name, cv::Mat &featureMD,
66  cv::Mat &labelMD, bool is_usr_label, const int usr_label) {
67  ROS_INFO("--READING DATASET IMAGE");
68  try {
70  this->rosbag_->open(filename, rosbag::bagmode::Read);
71  ROS_INFO("Bag Found and Opened Successfully...");
72  std::vector<std::string> topics;
73  topics.push_back(std::string(topic_name));
74  rosbag::View view(*rosbag_, rosbag::TopicQuery(topics));
75  BOOST_FOREACH(rosbag::MessageInstance const m, view) {
76  sensor_msgs::Image::ConstPtr img_msg = m.instantiate<
77  sensor_msgs::Image>();
80  if (cv_ptr->image.data) {
81  cv::Mat image = cv_ptr->image.clone();
82  float label = static_cast<float>(usr_label);
83  labelMD.push_back(label);
84  this->extractFeatures(image, featureMD);
85  cv::imshow("image", image);
86  cv::waitKey(3);
87  } else {
88  ROS_WARN("-> NO IMAGE");
89  }
90  }
91  this->rosbag_->close();
92  } catch (ros::Exception &e) {
93  ROS_ERROR("ERROR: Bag File:%s not found..\n%s",
94  filename.c_str(), e.what());
95  std::_Exit(EXIT_FAILURE);
96  }
97  }
98 
103  cv::Mat &img, cv::Mat &featureMD) {
104  ROS_INFO("--EXTRACTING IMAGE FEATURES.");
105  if (img.data) {
106  cv::resize(img, img, cv::Size(this->swindow_x_, this->swindow_y_));
107  cv::Mat hog_feature = this->computeHOG(img);
108  cv::Mat hsv_feature;
109  this->computeHSHistogram(img, hsv_feature, 16, 16, true);
110  hsv_feature = hsv_feature.reshape(1, 1);
111  cv::Mat _feature;
112  this->concatenateCVMat(hog_feature, hsv_feature, _feature, true);
113  featureMD.push_back(_feature);
114  }
115  cv::imshow("image", img);
116  cv::waitKey(3);
117  }
118 
120  const cv::Mat &featureMD, const cv::Mat &labelMD)
121  {
122  ROS_INFO("--TRAINING CLASSIFIER");
123 #if CV_MAJOR_VERSION >= 3
124  this->supportVectorMachine_->setType(cv::ml::SVM::NU_SVC);
125  //this->supportVectorMachine_->setKernelType(cv::ml::SVM::RBF);
126  this->supportVectorMachine_->setDegree(0.0);
127  this->supportVectorMachine_->setGamma(0.90);
128  this->supportVectorMachine_->setCoef0(0.50);
129  this->supportVectorMachine_->setC(1);
130  this->supportVectorMachine_->setNu(0.70);
131  this->supportVectorMachine_->setP(1.0);
132  //this->supportVectorMachine_->setClassWeights(NULL);
133  cv::TermCriteria term_crit;
134  term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
135  term_crit.maxCount = 1e6;
136  term_crit.epsilon = 1e-6;
137  this->supportVectorMachine_->setTermCriteria(term_crit);
138  cv::ml::ParamGrid paramGrid = cv::ml::ParamGrid();
139  paramGrid.minVal = 0;
140  paramGrid.maxVal = 0;
141  paramGrid.logStep = 1;
142 
143  cv::Ptr<cv::ml::TrainData> train = cv::ml::TrainData::create(featureMD, cv::ml::ROW_SAMPLE, labelMD, cv::Mat(), cv::Mat()); // ROW_SAMPLE ? COL_SAMPLE ?
144  this->supportVectorMachine_->trainAuto
145  (train, 10,
146  paramGrid, cv::ml::SVM::getDefaultGrid(cv::ml::SVM::GAMMA),
147  cv::ml::SVM::getDefaultGrid(cv::ml::SVM::P),
148  cv::ml::SVM::getDefaultGrid(cv::ml::SVM::NU),
149  cv::ml::SVM::getDefaultGrid(cv::ml::SVM::COEF),
150  cv::ml::SVM::getDefaultGrid(cv::ml::SVM::DEGREE),
151  true);
152 #else
153  cv::SVMParams svm_param = cv::SVMParams();
154  svm_param.svm_type = cv::SVM::NU_SVC;
155  svm_param.kernel_type = cv::SVM::RBF;
156  svm_param.degree = 0.0;
157  svm_param.gamma = 0.90;
158  svm_param.coef0 = 0.50;
159  svm_param.C = 1;
160  svm_param.nu = 0.70;
161  svm_param.p = 1.0;
162  svm_param.class_weights = NULL;
163  svm_param.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
164  svm_param.term_crit.max_iter = 1e6;
165  svm_param.term_crit.epsilon = 1e-6;
166  cv::ParamGrid paramGrid = cv::ParamGrid();
167  paramGrid.min_val = 0;
168  paramGrid.max_val = 0;
169  paramGrid.step = 1;
170 
171  /*this->supportVectorMachine_->train(
172  featureMD, labelMD, cv::Mat(), cv::Mat(), svm_param);*/
173  this->supportVectorMachine_->train_auto
174  (featureMD, labelMD, cv::Mat(), cv::Mat(), svm_param, 10,
175  paramGrid, cv::SVM::get_default_grid(cv::SVM::GAMMA),
176  cv::SVM::get_default_grid(cv::SVM::P),
177  cv::SVM::get_default_grid(cv::SVM::NU),
178  cv::SVM::get_default_grid(cv::SVM::COEF),
179  cv::SVM::get_default_grid(cv::SVM::DEGREE),
180  true);
181 #endif
182  }
183 
185  const cv::Mat &mat_1, const cv::Mat &mat_2,
186  cv::Mat &featureMD, bool iscolwise)
187  {
188  if (iscolwise) {
189  featureMD = cv::Mat(mat_1.rows, (mat_1.cols + mat_2.cols), CV_32F);
190  for (int i = 0; i < featureMD.rows; i++) {
191  for (int j = 0; j < mat_1.cols; j++) {
192  featureMD.at<float>(i, j) = mat_1.at<float>(i, j);
193  }
194  for (int j = mat_1.cols; j < featureMD.cols; j++) {
195  featureMD.at<float>(i, j) = mat_2.at<float>(i, j - mat_1.cols);
196  }
197  }
198  } else {
199  featureMD = cv::Mat((mat_1.rows + mat_2.rows), mat_1.cols, CV_32F);
200  for (int i = 0; i < featureMD.cols; i++) {
201  for (int j = 0; j < mat_1.rows; j++) {
202  featureMD.at<float>(j, i) = mat_1.at<float>(j, i);
203  }
204  for (int j = mat_1.rows; j < featureMD.rows; j++) {
205  featureMD.at<float>(j, i) = mat_2.at<float>(j - mat_1.rows, i);
206  }
207  }
208  }
209  }
210 
212  cv::FileStorage &fs)
213  {
214  fs << "TrainerInfo" << "{";
215  fs << "trainer_type" << "cv::SVM";
216  fs << "trainer_path" << this->trained_classifier_name_;
217  fs << "}";
218 
219  fs << "FeatureInfo" << "{";
220  fs << "HOG" << 1;
221  // fs << "LBP" << 0;
222  // fs << "SIFT" << 0;
223  // fs << "SURF" << 0;
224  fs << "COLOR_HISTOGRAM" << 1;
225  fs << "}";
226 
227  fs << "SlidingWindowInfo" << "{";
228  fs << "swindow_x" << this->swindow_x_;
229  fs << "swindow_y" << this->swindow_y_;
230  fs << "}";
231 
232  fs << "TrainingDatasetDirectoryInfo" << "{";
233  fs << "object_dataset_filename" << this->object_dataset_filename_;
234  fs << "nonobject_dataset_filename" << this->nonobject_dataset_filename_;
235  fs << "dataset_path" << this->dataset_path_; // only path to neg
236  fs << "}";
237  }
238 
240  cv::Mat &src, cv::Mat &hist, const int hBin, const int sBin, bool is_norm)
241  {
242  if (src.empty()) {
243  return;
244  }
245  cv::Mat hsv;
246  cv::cvtColor(src, hsv, CV_BGR2HSV);
247  int histSize[] = {hBin, sBin};
248  float h_ranges[] = {0, 180};
249  float s_ranges[] = {0, 256};
250  const float* ranges[] = {h_ranges, s_ranges};
251  int channels[] = {0, 1};
252  cv::calcHist(
253  &hsv, 1, channels, cv::Mat(), hist, 2, histSize, ranges, true, false);
254  if (is_norm) {
255  cv::normalize(hist, hist, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
256  }
257  }
258 } // namespace jsk_perception
259 
260 int main(int argc, char *argv[]) {
261  ros::init(argc, argv, "sliding_window_object_detector_trainer_node");
262  ROS_INFO("RUNNING NODELET %s", "sliding_window_object_detector_trainer");
264  ros::spin();
265  return 0;
266 }
virtual void concatenateCVMat(const cv::Mat &, const cv::Mat &, cv::Mat &, bool=true)
virtual void readDataset(std::string, std::string, cv::Mat &, cv::Mat &, bool=false, const int=0)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
#define ROS_WARN(...)
ROSCPP_DECL void spin(Spinner &spinner)
virtual cv::Mat computeHOG(const cv::Mat &)
#define ROS_INFO(...)
boost::shared_ptr< T > instantiate() const
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
topics
std::string filename
Definition: linemod.cpp:198
label
#define EXIT_FAILURE
#define NULL
virtual void computeHSHistogram(cv::Mat &, cv::Mat &, const int=64, const int=32, bool=true)
int main(int argc, char *argv[])
#define ROS_ERROR(...)


jsk_perception
Author(s): Manabu Saito, Ryohei Ueda
autogenerated on Mon May 3 2021 03:03:27