polygon_array_color_likelihood.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2015, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
38 #include <yaml-cpp/yaml.h>
39 #include <fstream>
40 
41 namespace jsk_perception
42 {
44  {
45  DiagnosticNodelet::onInit();
46  pnh_->param("approximate_sync", approximate_sync_, false);
47  pnh_->param("max_queue_size", max_queue_size_, 10);
48  pnh_->param("synchronizer_queue_size", sync_queue_size_, 100);
49  std::string reference_file;
50  pnh_->param("reference_file", reference_file, std::string(""));
51  reference_from_file_ = !reference_file.empty();
53  ROS_INFO("Reading reference from %s", reference_file.c_str());
54  readReference(reference_file);
55  }
56  srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
57  dynamic_reconfigure::Server<Config>::CallbackType f =
58  boost::bind (
60  srv_->setCallback (f);
61  pub_ = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_, "output", 1);
62  }
63 
65  {
66  if (!reference_from_file_) {
67  sub_reference_ = pnh_->subscribe(
68  "input/reference", 1, &PolygonArrayColorLikelihood::referenceCallback, this);
69  }
70  sub_polygon_.subscribe(*pnh_, "input/polygons", max_queue_size_);
71  sub_histogram_.subscribe(*pnh_, "input/histograms", max_queue_size_);
72  if (approximate_sync_) {
73  async_ = boost::make_shared<message_filters::Synchronizer<ApproximateSyncPolicy> >(sync_queue_size_);
74  async_->connectInput(sub_polygon_, sub_histogram_);
75  async_->registerCallback(
76  boost::bind(&PolygonArrayColorLikelihood::likelihood, this, _1, _2));
77  }
78  else {
79  sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(sync_queue_size_);
80  sync_->connectInput(sub_polygon_, sub_histogram_);
81  sync_->registerCallback(
82  boost::bind(&PolygonArrayColorLikelihood::likelihood, this, _1, _2));
83  }
84  }
85 
87  {
88  // The yaml format should be
89  // bins:
90  // -
91  // min_value: xx
92  // max_value: xx
93  // count: xx
94  // -
95  // min_value: xx
96  // max_value: xx
97  // count: xx
98  // ...
99  jsk_recognition_msgs::HistogramWithRange read_msg;
100  #ifdef USE_OLD_YAML
101  YAML::Node doc;
102  std::ifstream fin;
103 
104  fin.open(file.c_str(), std::ifstream::in);
105  YAML::Parser parser(fin);
106  while (parser.GetNextDocument(doc)) {
107  const YAML::Node& bins_yaml = doc["bins"];
108  for (size_t i = 0; i < bins_yaml.size(); i++) {
109  const YAML::Node& bin_yaml = bins_yaml[i];
110  const YAML::Node& min_value_yaml = bin_yaml["min_value"];
111  const YAML::Node& max_value_yaml = bin_yaml["max_value"];
112  const YAML::Node& count_yaml = bin_yaml["count"];
113  jsk_recognition_msgs::HistogramWithRangeBin bin;
114  min_value_yaml >> bin.min_value;
115  max_value_yaml >> bin.max_value;
116  count_yaml >> bin.count;
117  read_msg.bins.push_back(bin);
118  }
119  }
120  #else
121  // yaml-cpp is greater than 0.5.0
122  YAML::Node doc;
123 
124  doc = YAML::LoadFile(file);
125  if ( doc["bins"] ) {
126  const YAML::Node& bins_yaml = doc["bins"];
127  for (size_t i = 0; i < bins_yaml.size(); i++) {
128  const YAML::Node& bin_yaml = bins_yaml[i];
129  const YAML::Node& min_value_yaml = bin_yaml["min_value"];
130  const YAML::Node& max_value_yaml = bin_yaml["max_value"];
131  const YAML::Node& count_yaml = bin_yaml["count"];
132  jsk_recognition_msgs::HistogramWithRangeBin bin;
133  bin.min_value = min_value_yaml.as<double> ();
134  bin.max_value = max_value_yaml.as<double> ();
135  bin.count = count_yaml.as<int> ();
136  read_msg.bins.push_back(bin);
137  }
138  } else {
139  ROS_ERROR_STREAM("bins: keyword is not found in file(" << file << ")");
140  }
141  #endif
142  reference_ = boost::make_shared<jsk_recognition_msgs::HistogramWithRange>(read_msg);
143  }
144 
146  {
147  if (!reference_from_file_) {
149  }
152  }
153 
155  const jsk_recognition_msgs::HistogramWithRange::ConstPtr& ref_msg)
156  {
157  boost::mutex::scoped_lock lock(mutex_);
158  reference_ = ref_msg;
159  }
160 
162  Config &config, uint32_t level)
163  {
164  boost::mutex::scoped_lock lock(mutex_);
165  coefficient_method_ = config.coefficient_method;
166  }
167 
169  const cv::MatND& ref_hist,
170  const cv::MatND& target_hist)
171  {
172  if (coefficient_method_ == 0) {
173  return (1.0 + cv::compareHist(ref_hist, target_hist, CV_COMP_CORREL)) / 2.0;
174  }
175  else if (coefficient_method_ == 1) {
176  double x = cv::compareHist(ref_hist, target_hist, CV_COMP_CHISQR);
177  return 1/ (x * x + 1);
178  }
179  else if (coefficient_method_ == 2) {
180  return cv::compareHist(ref_hist, target_hist, CV_COMP_INTERSECT);
181  }
182  else if (coefficient_method_ == 3) {
183  return 1.0 - cv::compareHist(ref_hist, target_hist, CV_COMP_BHATTACHARYYA);
184  }
185  else if (coefficient_method_ == 4 || coefficient_method_ == 5) {
186  cv::Mat ref_sig = cv::Mat::zeros(ref_hist.cols, 2, CV_32FC1);
187  cv::Mat target_sig = cv::Mat::zeros(ref_hist.cols, 2, CV_32FC1);
188  //NODELET_INFO("ref_hist.cols = %d", ref_hist.cols);
189  for (size_t i = 0; i < ref_hist.cols; i++) {
190  ref_sig.at<float>(i, 0) = ref_hist.at<float>(0, i);
191  target_sig.at<float>(i, 0) = target_hist.at<float>(0, i);
192  ref_sig.at<float>(i, 1) = i;
193  target_sig.at<float>(i, 1) = i;
194  }
195  if (coefficient_method_ == 4) {
196  double x = cv::EMD(ref_sig, target_sig, CV_DIST_L1);
197  return 1.0 / (1.0 + x * x);
198  }
199  else {
200  double x = cv::EMD(ref_sig, target_sig, CV_DIST_L2);
201  return 1.0 / (1.0 + x * x);
202  }
203  }
204  else {
205  NODELET_ERROR("unknown coefficiet method: %d", coefficient_method_);
206  return 0;
207  }
208  }
209 
211  const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
212  const jsk_recognition_msgs::HistogramWithRangeArray::ConstPtr& histogram_msg)
213  {
214  boost::mutex::scoped_lock lock(mutex_);
215  if (!reference_) {
216  return;
217  }
218  if (polygon_msg->polygons.size() != histogram_msg->histograms.size()) {
219  NODELET_ERROR("length of polygon and histogram are not same");
220  return;
221  }
222  cv::MatND reference_histogram
224  reference_->bins);
225  cv::normalize(reference_histogram, reference_histogram, 1, reference_histogram.rows, cv::NORM_L2,
226  -1, cv::Mat());
227  jsk_recognition_msgs::PolygonArray new_msg(*polygon_msg);
228  for (size_t i = 0; i < new_msg.polygons.size(); i++) {
229  cv::MatND hist
231  histogram_msg->histograms[i].bins);
232  cv::normalize(hist, hist, 1, hist.rows, cv::NORM_L2,
233  -1, cv::Mat());
234  double d = compareHist(reference_histogram, hist);
235  if (polygon_msg->likelihood.size() == 0) {
236  new_msg.likelihood.push_back(d);
237  }
238  else {
239  new_msg.likelihood[i] *= d;
240  }
241  }
242  pub_.publish(new_msg);
243  }
244 }
245 
PLUGINLIB_EXPORT_CLASS(jsk_perception::PolygonArrayColorLikelihood, nodelet::Nodelet)
d
Definition: setup.py:6
f
virtual void likelihood(const jsk_recognition_msgs::PolygonArray::ConstPtr &polygon_msg, const jsk_recognition_msgs::HistogramWithRangeArray::ConstPtr &histogram_msg)
#define NODELET_ERROR(...)
virtual void referenceCallback(const jsk_recognition_msgs::HistogramWithRange::ConstPtr &ref_msg)
message_filters::Subscriber< jsk_recognition_msgs::PolygonArray > sub_polygon_
void publish(const boost::shared_ptr< M > &message) const
jsk_recognition_msgs::HistogramWithRange::ConstPtr reference_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
virtual void configCallback(Config &config, uint32_t level)
cv::MatND HistogramWithRangeBinArrayTocvMatND(const std::vector< jsk_recognition_msgs::HistogramWithRangeBin > &histogram)
hist
message_filters::Subscriber< jsk_recognition_msgs::HistogramWithRangeArray > sub_histogram_
#define ROS_INFO(...)
boost::shared_ptr< ros::NodeHandle > pnh_
x
boost::shared_ptr< message_filters::Synchronizer< ApproximateSyncPolicy > > async_
mutex_t * lock
virtual double compareHist(const cv::MatND &ref_hist, const cv::MatND &target_hist)
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
#define ROS_ERROR_STREAM(args)


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