rect_array_actual_size_filter.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2016, 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 
37 #include <cv_bridge/cv_bridge.h>
40 
41 namespace jsk_perception
42 {
44  {
45  DiagnosticNodelet::onInit();
46  pnh_->param("approximate_sync", approximate_sync_, false);
47  srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
48  dynamic_reconfigure::Server<Config>::CallbackType f =
49  boost::bind (
51  srv_->setCallback (f);
52 
53  pub_ = advertise<jsk_recognition_msgs::RectArray>(
54  *pnh_, "output", 1);
56  }
57 
59  {
60  sub_rect_array_.subscribe(*pnh_, "input", 1);
61  sub_image_.subscribe(*pnh_, "input/depth_image", 1);
62  sub_info_.subscribe(*pnh_, "input/info", 1);
63  if (approximate_sync_) {
64  async_ = boost::make_shared<message_filters::Synchronizer<ApproxSyncPolicy> >(100);
65  async_->connectInput(sub_rect_array_, sub_image_, sub_info_);
66  async_->registerCallback(boost::bind(&RectArrayActualSizeFilter::filter, this, _1, _2, _3));
67  }
68  else {
69  sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
70  sync_->connectInput(sub_rect_array_, sub_image_, sub_info_);
71  sync_->registerCallback(boost::bind(&RectArrayActualSizeFilter::filter, this, _1, _2, _3));
72  }
73  }
74 
76  {
80  }
81 
83  uint32_t level)
84  {
85  boost::mutex::scoped_lock lock(mutex_);
86  kernel_size_ = config.kernel_size;
87  min_x_ = config.min_x;
88  min_y_ = config.min_y;
89  max_x_ = config.max_x;
90  max_y_ = config.max_y;
91  }
92 
94  const int center_x, const int center_y, const cv::Mat& img) const
95  {
96  double d = 0.0;
97  int valid = 0;
98  for (int j = -kernel_size_; j <= kernel_size_; j++) {
99  for (int i = -kernel_size_; i <= kernel_size_; i++) {
100  const int x = center_x + i;
101  const int y = center_y + j;
102  if (0 <= x && x <= img.cols &&
103  0 <= y && y <= img.rows) {
104  d += img.at<float>(y, x);
105  ++valid;
106  }
107  }
108  }
109  return d / valid;
110  }
111 
113  (const jsk_recognition_msgs::RectArray::ConstPtr& rect_array_msg,
114  const sensor_msgs::Image::ConstPtr& depth_image_msg,
115  const sensor_msgs::CameraInfo::ConstPtr& info_msg)
116  {
117  boost::mutex::scoped_lock lock(mutex_);
118  // 1. compute average distance from kernel_size_
119  // 2. compute x and y actual size at the average distance
120  // 3. filter them
121  jsk_recognition_msgs::RectArray result_msg;
122  result_msg.header = rect_array_msg->header;
124  cv::Mat depth = cv_depth->image;
125  cv::Mat average_depth;
126  // 1
128  model.setCameraInfo(*info_msg);
130  for (size_t i = 0; i< rect_array_msg->rects.size(); i++) {
131  jsk_recognition_msgs::Rect rect = rect_array_msg->rects[i];
132  // rect has x, y, width and height
133  const int center_x = rect.x + rect.width / 2;
134  const int center_y = rect.y + rect.height / 2;
135  const cv::Point A(rect.x, rect.y);
136  const cv::Point C(rect.x + rect.width, rect.y + rect.height);
137  //const double distance = average_depth.at<double>(center_y, center_x);
138  const double distance = averageDistance(center_x, center_y, depth); // z [m]
139  cv::Point3d a_ray = camera_model.projectPixelTo3dRay(A); // (x, y, z) [depth_value]
140  cv::Point3d c_ray = camera_model.projectPixelTo3dRay(C); // (x, y, z) [depth_value]
141  if (a_ray.z != 0.0 && c_ray.z != 0.0) {
142  cv::Point3d a_3d = a_ray * (distance / a_ray.z); // m = depth_value * (m / depth_value)
143  cv::Point3d c_3d = c_ray * (distance / c_ray.z); // m = depth_value * (m / depth_value)
144  const double width = std::abs(a_3d.x - c_3d.x);
145  const double height = std::abs(a_3d.y - c_3d.y);
146  if (min_x_ <= width && width <= max_x_ &&
147  min_y_ <= height && height <= max_y_) {
148  result_msg.rects.push_back(rect);
149  }
150  }
151  else {
152  NODELET_ERROR("rect has z=0 ray");
153  return;
154  }
155  }
156 
157  pub_.publish(result_msg);
158  }
159 
160 }
161 
d
Definition: setup.py:6
f
#define NODELET_ERROR(...)
void publish(const boost::shared_ptr< M > &message) const
virtual double averageDistance(const int center_x, const int center_y, const cv::Mat &img) const
cv::Point3d projectPixelTo3dRay(const cv::Point2d &uv_rect) const
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
message_filters::Subscriber< sensor_msgs::Image > sub_image_
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
width
PLUGINLIB_EXPORT_CLASS(jsk_perception::RectArrayActualSizeFilter, nodelet::Nodelet)
virtual image_geometry::PinholeCameraModel getPinholeCameraModel() const
boost::shared_ptr< message_filters::Synchronizer< ApproxSyncPolicy > > async_
message_filters::Subscriber< sensor_msgs::CameraInfo > sub_info_
virtual void configCallback(Config &config, uint32_t level)
boost::shared_ptr< ros::NodeHandle > pnh_
const std::string TYPE_32FC1
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
message_filters::Subscriber< jsk_recognition_msgs::RectArray > sub_rect_array_
x
y
mutex_t * lock
C
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)
height
virtual void filter(const jsk_recognition_msgs::RectArray::ConstPtr &rect_array_msg, const sensor_msgs::Image::ConstPtr &depth_image_msg, const sensor_msgs::CameraInfo::ConstPtr &info_msg)
virtual void setCameraInfo(const sensor_msgs::CameraInfo &info)
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_


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