ed_sensor_integration
kinect/updater.cpp
Go to the documentation of this file.
1 #include "ed/kinect/updater.h"
2 
3 #include <ed/world_model.h>
4 #include <ed/entity.h>
5 #include <ed/update_request.h>
6 
7 #include <geolib/Shape.h>
8 #include <geolib/shapes.h>
9 
10 #include "ed/kinect/association.h"
11 #include "ed/kinect/renderer.h"
12 #include "ed/convex_hull_calc.h"
13 
14 #include <opencv2/highgui/highgui.hpp>
15 #include <rgbd/view.h>
16 #include <ros/console.h>
17 #include <ros/node_handle.h>
18 #include <sensor_msgs/Image.h>
19 #include <sensor_msgs/PointCloud2.h>
20 
22 // ----------------------------------------------------------------------------------------------------
23 
24 // Calculates which depth points are in the given convex hull (in the EntityUpdate), updates the mask,
25 // and updates the convex hull height based on the points found
26 void refitConvexHull(const rgbd::Image& image, const geo::Pose3D& sensor_pose, const geo::DepthCamera& cam_model,
27  const std::unique_ptr<Segmenter>& segmenter_, EntityUpdate& up)
28 {
29  up.pose_map.t.z += (up.chull.z_max + up.chull.z_min) / 2;
30 
31  geo::Shape chull_shape;
32  std::vector<geo::Vec2> points(up.chull.points.size());
33  for(unsigned int i = 0; i < points.size(); ++i)
34  points[i] = geo::Vec2(up.chull.points[i].x, up.chull.points[i].y);
35  geo::createConvexPolygon(chull_shape, points, up.chull.height());
36 
37  cv::Mat filtered_depth_image;
38  segmenter_->calculatePointsWithin(image, chull_shape, sensor_pose.inverse() * up.pose_map, filtered_depth_image);
39 
40  up.points.clear();
41  up.pixel_indices.clear();
42 
43  float z_min = 1e9;
44  float z_max = -1e9;
45 
46  int i_pixel = 0;
47  std::vector<float> z_values;
48  z_values.reserve(filtered_depth_image.rows * filtered_depth_image.cols);
49  for(int y = 0; y < filtered_depth_image.rows; ++y)
50  {
51  for(int x = 0; x < filtered_depth_image.cols; ++x)
52  {
53  float d = filtered_depth_image.at<float>(y, x);
54  if (d == 0)
55  {
56  ++i_pixel;
57  continue;
58  }
59 
60  geo::Vec3 p = cam_model.project2Dto3D(x, y) * d;
61  geo::Vec3 p_map = sensor_pose * p;
62  z_values.push_back(p_map.z);
63 
64  z_min = std::min<float>(z_min, p_map.z);
65  z_max = std::max<float>(z_max, p_map.z);
66 
67  up.pixel_indices.push_back(i_pixel);
68  up.points.push_back(p);
69  ++i_pixel;
70  }
71  }
72 
73  // Statistical filtering out outliers
74  // Calculate z statistics
75  if (z_values.empty()) return;
76 
77  // Sort for percentile calculation
78  std::sort(z_values.begin(), z_values.end());
79 
80  // Use 5th and 95th percentiles instead of min/max to filter outliers
81  int lower_idx = std::max(0, static_cast<int>(z_values.size() * 0.05));
82  int upper_idx = std::min(static_cast<int>(z_values.size()-1),
83  static_cast<int>(z_values.size() * 0.95));
84 
85  z_min = z_values[lower_idx];
86  z_max = z_values[upper_idx];
87 
88  double h = z_max - z_min;
89  up.pose_map.t.z = (z_max + z_min) / 2;
90  up.chull.z_min = -h / 2;
91  up.chull.z_max = h / 2;
92 }
93 
94 // ----------------------------------------------------------------------------------------------------
101 EntityUpdate mergeConvexHulls(const rgbd::Image& image, const geo::Pose3D& sensor_pose, const geo::DepthCamera& cam_model,
102  const std::unique_ptr<Segmenter>& segmenter_, const EntityUpdate& u1, const EntityUpdate& u2)
103 {
104  EntityUpdate new_u = u1;
105  double z_max = std::max(u1.pose_map.t.getZ()+u1.chull.z_max,u2.pose_map.t.getZ()+u2.chull.z_max);
106  double z_min = std::min(u1.pose_map.t.getZ()+u1.chull.z_min,u2.pose_map.t.getZ()+u2.chull.z_min);
107 
108  std::vector<geo::Vec2f> points(u1.chull.points.size()+u2.chull.points.size());
109  for (unsigned int p = 0; p < u1.chull.points.size(); ++p)
110  {
111  geo::Vec3 p_map = u1.pose_map * geo::Vec3(u1.chull.points[p].x, u1.chull.points[p].y, 0);
112  points[p] = geo::Vec2f(p_map.x, p_map.y);
113  }
114  unsigned int offset = u1.chull.points.size();
115  for (unsigned int p = 0; p < u2.chull.points.size(); ++p)
116  {
117  geo::Vector3 p_map = u2.pose_map * geo::Vec3(u2.chull.points[p].x, u2.chull.points[p].y, 0);
118  points[p + offset] = geo::Vec2f(p_map.x, p_map.y);
119  }
120 
121  ed::convex_hull::create(points, z_min, z_max, new_u.chull, new_u.pose_map);
122  refitConvexHull(image, sensor_pose, cam_model, segmenter_, new_u);
123 
124  return new_u;
125 }
126 
127 // ----------------------------------------------------------------------------------------------------
128 
129 // Calculates which depth points are in the given convex hull (in the EntityUpdate), updates the mask,
130 // and updates the convex hull height based on the points found
132  const std::unique_ptr<Segmenter>& segmenter_, const std::vector<EntityUpdate>& updates)
133 {
134 
135  ROS_INFO("mergoverlapping chulls: nr of updates: %lu", updates.size());
136 
137  // Updated convex hulls
138  std::vector<EntityUpdate> new_updates;
139 
140  // Keep track of indices that did collide, skip them in i
141  std::vector<int> collided_indices;
142  std::map<int, std::vector<int> > collission_map;
143 
144  for (uint i = 0; i < updates.size(); ++i)
145  {
146  const EntityUpdate& u1 = updates[i];
147 
148  // If index already collided, it will be merged to another one
149  if (std::find(collided_indices.begin(), collided_indices.end(), i) != collided_indices.end())
150  {
151  continue;
152  }
153 
154  for (uint j = 0; j < updates.size(); ++j)
155  {
156  // skip self
157  if (i == j)
158  continue;
159 
160  const EntityUpdate& u2 = updates[j];
161 
162  // If we collide, update the i convex hull
163  if (ed::convex_hull::collide(u1.chull, u1.pose_map.t, u2.chull, u2.pose_map.t, 0, 1e6)) // This should prevent multiple entities above each other;1e6 is ok, because objects in other areas are ignored.
164  {
165  ROS_DEBUG("Collition item %i with %i", i, j);
166  ROS_DEBUG("Item %i: xyz: %.2f, %.2f, %.2f, z_min: %.2f, z_max: %.2f", i, u1.pose_map.t.getX(), u1.pose_map.t.getY(), u1.pose_map.t.getZ(), u1.chull.z_min, u1.chull.z_max);
167  ROS_DEBUG("Item %i: xyz: %.2f, %.2f, %.2f, z_min: %.2f, z_max: %.2f", j, u2.pose_map.t.getX(), u2.pose_map.t.getY(), u2.pose_map.t.getZ(), u2.chull.z_min, u2.chull.z_max);
168  collission_map[i].push_back(j);
169  collided_indices.push_back(j);
170  }
171  }
172  }
173 
174  // Now again loop over the updates and only push back in the new updates if it will not be merged into an other entity
175  for (uint i = 0; i < updates.size(); ++i)
176  {
177  // If index in collided_indices, it will be merged to another one
178  if (std::find(collided_indices.begin(), collided_indices.end(), i) == collided_indices.end())
179  {
180  // Merging is done by creating a new convexHull. Multiple objects can be merged into one.
181  // No sorting is done. So depending on which entity was taken first, that one is used as basis for merging.
182  // But that shouldn't matter, only for UUID. Although the entities are re-associatied afterwards.
183  // Which match new measurments to old entities.
184 
185  EntityUpdate u1 = updates[i];
186  for (std::vector<int>::iterator it = collission_map[i].begin(); it != collission_map[i].end(); ++it)
187  {
188  ROS_DEBUG_COND(it == collission_map[i].begin(), "Merging entity %i and xx", i);
189  ROS_DEBUG("Merging entity %i and %i", i, *it);
190  const EntityUpdate u2 = updates[*it];
191  u1 = mergeConvexHulls(image, sensor_pose, cam_model, segmenter_, u1, u2);
192 
193  }
194  new_updates.push_back(u1);
195  ROS_DEBUG("Adding update of entity %i", i);
196  }
197  else
198  {
199  ROS_DEBUG("Skipping update %i because of collision", i);
200  }
201  }
202 
203  return new_updates;
204 }
205 
206 // ----------------------------------------------------------------------------------------------------
207 Updater::Updater(tue::Configuration config) : logging(false)
208 {
209  if (config.readGroup("segmenter", tue::config::REQUIRED))
210  {
211  segmenter_ = std::make_unique<Segmenter>(config);
212  }
213  else
214  {
215  ROS_ERROR("Failed to read segmenter configuration group from config file, cannot initialize Updater");
216  throw std::runtime_error("Failed to read segmenter configuration group from config file");
217  }
218 
219  // Initialize the image publisher
221  if (logging)
222  {
223  ros::NodeHandle nh("~");
224  mask_pub_ = nh.advertise<sensor_msgs::Image>("segmentation_masks", 1);
225  cloud_pub_ = nh.advertise<sensor_msgs::PointCloud2>("point_cloud_ooo", 1);
226  }
227 }
228 
229 // ----------------------------------------------------------------------------------------------------
230 
232 {
233 }
234 
235 // ----------------------------------------------------------------------------------------------------
236 
237 bool Updater::update(const ed::WorldModel& world, const rgbd::ImageConstPtr& image, const geo::Pose3D& sensor_pose_const,
238  const UpdateRequest& req, UpdateResult& res)
239 {
240  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
241  // Prepare some things
242 
243  // will contain depth image filtered with given update shape and world model (background) subtraction
244  cv::Mat filtered_depth_image;
245  cv::Mat filtered_rgb_image;
246  // sensor pose might be update, so copy (making non-const)
247  geo::Pose3D sensor_pose = sensor_pose_const;
248 
249  // depth image
250  const cv::Mat& depth = image->getDepthImage();
251  const cv::Mat& rgb = image->getRGBImage();
252  //cv::Mat img = rgb.clone();
253 
254  // Determine depth image camera model
255  rgbd::View view(*image, depth.cols);
256  const geo::DepthCamera& cam_model = view.getRasterizer();
257 
258  std::string area_description;
259 
260  if (!req.area_description.empty())
261  {
262  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
263  // Check if the update_command is a segmented entity.
264  // If so, lookup the corresponding area_description
265 
266  bool fit_supporting_entity = req.fit_supporting_entity;
267 
269  if (it_area_descr != id_to_area_description_.end())
270  {
271  area_description = it_area_descr->second;
272  fit_supporting_entity = false; // We are only interested in the supported entity, so don't fit the supporting entity
273  }
274  else
275  area_description = req.area_description;
276 
277  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
278  // Parse space description (split on space)
279 
280  std::size_t i_space = area_description.find(' ');
281 
282  ed::UUID entity_id;
283  std::string area_name;
284 
285  if (i_space == std::string::npos)
286  {
287  entity_id = area_description;
288  }
289  else
290  {
291  area_name = area_description.substr(0, i_space);
292  entity_id = area_description.substr(i_space + 1);
293  }
294 
295  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
296  // Check for entity
297 
298  ed::EntityConstPtr e = world.getEntity(entity_id);
299 
300  if (!e)
301  {
302  res.error << "No such entity: '" << entity_id.str() << "'.";
303  return false;
304  }
305  else if (!e->has_pose())
306  {
307  res.error << "Entity: '" << entity_id.str() << "' has no pose.";
308  return false;
309  }
310 
311  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
312  // Update entity position
313 
314  geo::Pose3D new_pose;
315 
316  if (fit_supporting_entity)
317  {
318  if (!fitter_.isConfigured())
319  {
320  fitter_.configureBeamModel(image->getCameraModel());
321  }
322  FitterData fitter_data;
323  fitter_.processSensorData(*image, sensor_pose, fitter_data);
324 
325  if (fitter_.estimateEntityPose(fitter_data, world, entity_id, e->pose(), new_pose, req.max_yaw_change))
326  {
327  res.update_req.setPose(entity_id, new_pose);
328  }
329  else
330  {
331  // res.error << "Could not determine pose of '" << entity_id.str() << "'.";
332  // return false;
333 
334  // Could not fit entity, so keep the old pose
335  new_pose = e->pose();
336  }
337  }
338  else
339  {
340  new_pose = e->pose();
341  }
342 
343  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
344  // Optimize sensor pose
345 
346  if (false)
347  {
348  fitZRP(*e->visual(), new_pose, *image, sensor_pose_const, sensor_pose);
349 
350  ROS_DEBUG_STREAM("Old sensor pose: " << sensor_pose_const);
351  ROS_DEBUG_STREAM("New sensor pose: " << sensor_pose);
352  }
353 
354  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
355  // Determine segmentation area
356 
357  if (!area_name.empty())
358  {
359  // Determine segmentation area (the geometrical shape in which the segmentation should take place)
360 
362  if (it == e->volumes().end())
363  {
364  res.error << "No area '" << area_name << "' for entity '" << entity_id.str() << "'.";
365  return false;
366  }
367  geo::Shape shape = *(it->second);
368  if (shape.getMesh().empty())
369  {
370  // Empty shapes shouldn't be stored at all, but check for robustness
371  res.error << "Could not load shape of area '" << area_name << "' for entity '" << entity_id.str() << "'.";
372  return false;
373  }
374 
375  // - - - - - - - - - - - - - - - - - - - - - - - -
376  // Segment
377 
378  geo::Pose3D shape_pose = sensor_pose.inverse() * new_pose;
379  segmenter_->calculatePointsWithin(*image, shape, shape_pose, filtered_depth_image);
380  }
381  }
382  else
383  {
384  filtered_depth_image = image->getDepthImage().clone();
385  }
386 
387  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
388  // Remove background
389 
390  // The world model may have been updated above, but the changes are only captured in
391  // an update request. Therefore, make a (shallow) copy of the world model and apply
392  // the changes, and use this for the background removal
393 
394  ed::WorldModel world_updated = world;
395  world_updated.update(res.update_req);
396 
397  segmenter_->removeBackground(filtered_depth_image, world_updated, cam_model, sensor_pose, req.background_padding);
398 
399  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
400  // Clear convex hulls that are no longer there
401 
402  std::vector<ed::EntityConstPtr> associatable_entities;
403  for(ed::WorldModel::const_iterator e_it = world.begin(); e_it != world.end(); ++e_it)
404  {
405  const ed::EntityConstPtr& e = *e_it;
406  if (e->visual() || !e->has_pose() || e->convexHull().points.empty())
407  continue;
408 
409  associatable_entities.push_back(e);
410  /*
411  geo::Vec3 p_3d = sensor_pose.inverse() * e->pose().t;
412 
413  cv::Point p_2d = cam_model.project3Dto2D(p_3d);
414  if (p_2d.x < 0 || p_2d.y < 0 || p_2d.x >= depth.cols || p_2d.y >= depth.rows)
415  continue;
416  */
417  /*float d = depth.at<float>(p_2d);
418  if (d > 0 && d == d && -p_3d.z < d)
419  {
420  ROS_INFO("Request to remove entity %s", e->id().c_str());
421  res.update_req.removeEntity(e->id());
422  associatable_entities.pop_back();
423  }*/
424  }
425 
426  // - - - - - - - - - - - - - - - - - - - - - - - -
427  // Cluster
428  filtered_rgb_image = segmenter_->preprocessRGBForSegmentation(rgb, filtered_depth_image);
429  std::vector<cv::Mat> clustered_images = segmenter_->cluster(filtered_depth_image, cam_model, sensor_pose, res.entity_updates, filtered_rgb_image, logging);
430  if (logging)
431  {
432  publishSegmentationResults(filtered_depth_image, filtered_rgb_image, sensor_pose, clustered_images, mask_pub_, cloud_pub_, res.entity_updates);
433  }
434  // - - - - - - - - - - - - - - - - - - - - - - - -
435  // Merge the detected clusters if they overlap in XY or Z
436  //res.entity_updates = mergeOverlappingConvexHulls(*image, sensor_pose, cam_model, segmenter_, res.entity_updates);
437 
438  // - - - - - - - - - - - - - - - - - - - - - - - -
439  // Increase the convex hulls a bit towards the supporting surface and re-calculate mask
440  // Then shrink the convex hulls again to get rid of the surface pixels
441 
443  {
444  EntityUpdate& up = *it;
445 
446  up.chull.z_min -= 0.04;
447  refitConvexHull(*image, sensor_pose, cam_model, segmenter_, up);
448 
449  up.chull.z_min += 0.01;
450  refitConvexHull(*image, sensor_pose, cam_model, segmenter_, up);
451  }
452 
453  // - - - - - - - - - - - - - - - - - - - - - - - -
454  // Perform association and update
455  associateAndUpdate(associatable_entities, image, sensor_pose, res.entity_updates, res.update_req);
456 
457  // - - - - - - - - - - - - - - - - - - - - - - - -
458  // Remove entities that are not associated
459  for (std::vector<ed::EntityConstPtr>::const_iterator it = associatable_entities.begin(); it != associatable_entities.end(); ++it)
460  {
461  ed::EntityConstPtr e = *it;
462 
463  // Check if entity is in frustum
464  const geo::Vec3 p_3d = sensor_pose.inverse() * e->pose().t; // Only taking into account the pose, not the shape
465  const cv::Point p_2d = cam_model.project3Dto2D(p_3d);
466  if (p_2d.x < 0 || p_2d.y < 0 || p_2d.x >= depth.cols || p_2d.y >= depth.rows)
467  continue; // Outside of frustum
468 
469  // If the entity is not updated, remove it
470  if (res.update_req.updated_entities.find(e->id()) == res.update_req.updated_entities.end())
471  {
472  ROS_INFO("Entity not associated and not seen in the frustum, while seeable");
473 
474  float d = depth.at<float>(p_2d);
475  if (d > 0 && d == d && -p_3d.z < d)
476  {
477  ROS_INFO_STREAM("We can shoot a ray through the center(" << d << " > " << -p_3d.z << "), removing entity " << e->id());
478  res.update_req.removeEntity(e->id());
479  res.removed_entity_ids.push_back(e->id());
480  }
481  }
482 
483  }
484 
485  // - - - - - - - - - - - - - - - - - - - - - - - -
486  // Remember the area description with which the segments where found
487 
488  if (!area_description.empty())
489  {
491  {
492  const EntityUpdate& up = *it;
493  id_to_area_description_[up.id] = area_description;
494  }
495  }
496 
497  return true;
498 }
geo::Vector3::y
const real & y() const
mergeOverlappingConvexHulls
std::vector< EntityUpdate > mergeOverlappingConvexHulls(const rgbd::Image &image, const geo::Pose3D &sensor_pose, const geo::DepthCamera &cam_model, const std::unique_ptr< Segmenter > &segmenter_, const std::vector< EntityUpdate > &updates)
Definition: kinect/updater.cpp:131
ed::WorldModel::getEntity
EntityConstPtr getEntity(const ed::UUID &id) const
EntityUpdate::pixel_indices
std::vector< unsigned int > pixel_indices
Definition: kinect/entity_update.h:16
ed::ConvexHull::z_min
float z_min
UpdateResult::update_req
ed::UpdateRequest & update_req
Definition: kinect/updater.h:42
geo::Mesh::empty
bool empty() const
std::string
std::shared_ptr
EntityUpdate
collection structure for laser entities
Definition: kinect/entity_update.h:9
publishSegmentationResults
void publishSegmentationResults(const cv::Mat &filtered_depth_image, const cv::Mat &rgb, const geo::Pose3D &sensor_pose, std::vector< cv::Mat > &clustered_images, ros::Publisher &mask_pub_, ros::Publisher &cloud_pub_, std::vector< EntityUpdate > &res_updates)
Publish segmentation results and pointcloud estimation as ROS messages.
Definition: sam_seg_module.cpp:112
sam_seg_module.h
ed::convex_hull::create
void create(const std::vector< geo::Vec2f > &points, float z_min, float z_max, ConvexHull &chull, geo::Pose3D &pose)
update_request.h
std::vector::reserve
T reserve(T... args)
std::vector
std::find
T find(T... args)
std::vector::size
T size(T... args)
geo::Vec3T
Shape.h
association.h
associateAndUpdate
void associateAndUpdate(const std::vector< ed::EntityConstPtr > &entities, const rgbd::ImageConstPtr &image, const geo::Pose3D &sensor_pose, std::vector< EntityUpdate > &clusters, ed::UpdateRequest &req)
Definition: association.cpp:18
geo::Transform3T
ed::UpdateRequest::removeEntity
void removeEntity(const UUID &id)
Fitter::estimateEntityPose
bool estimateEntityPose(const FitterData &data, const ed::WorldModel &world, const ed::UUID &id, const geo::Pose3D &expected_pose, geo::Pose3D &fitted_pose, double max_yaw_change=M_PI) const
estimateEntityPose performs the entity pose estimation. Basically, tries to call estimateEntityPoseIm...
Definition: fitter.cpp:258
FitterData
The FitterData struct contains the downprojected (hence 2D) sensor readings as well as the sensor pos...
Definition: fitter.h:68
geo::Shape::getMesh
virtual const Mesh & getMesh() const
geo::Vec2f
Vec2T< float > Vec2f
ed::WorldModel::update
void update(const UpdateRequest &req)
ed::WorldModel::begin
const_iterator begin() const
std::sort
T sort(T... args)
ed::WorldModel::const_iterator
EntityIterator const_iterator
std::vector::clear
T clear(T... args)
ed::EntityConstPtr
shared_ptr< const Entity > EntityConstPtr
ed::WorldModel::end
const_iterator end() const
std::vector::push_back
T push_back(T... args)
image
cv::Mat image
UpdateResult::entity_updates
std::vector< EntityUpdate > entity_updates
Definition: kinect/updater.h:40
geo::Vec3T::y
T y
tue::config::ReaderWriter
geo::Transform3T::inverse
Transform3T inverse() const
EntityUpdate::pose_map
geo::Pose3D pose_map
Definition: kinect/entity_update.h:23
ed::convex_hull::collide
bool collide(const ConvexHull &c1, const geo::Vector3 &pos1, const ConvexHull &c2, const geo::Vector3 &pos2, float xy_padding, float z_padding)
rgbd::Image
rgbd::View::getRasterizer
const geo::DepthCamera & getRasterizer() const
ed::UpdateRequest::updated_entities
std::set< UUID > updated_entities
geo::Vec3T::getY
T getY() const
mergeConvexHulls
EntityUpdate mergeConvexHulls(const rgbd::Image &image, const geo::Pose3D &sensor_pose, const geo::DepthCamera &cam_model, const std::unique_ptr< Segmenter > &segmenter_, const EntityUpdate &u1, const EntityUpdate &u2)
mergeConvexHulls, creating a new convexHull around the two objects. Working in both XY and Z.
Definition: kinect/updater.cpp:101
ed::ConvexHull::height
double height() const
Updater::~Updater
~Updater()
Definition: kinect/updater.cpp:231
UpdateResult::error
std::stringstream error
Definition: kinect/updater.h:43
ed::UpdateRequest::setPose
void setPose(const UUID &id, const geo::Pose3D &pose)
fitZRP
void fitZRP(const geo::Shape &shape, const geo::Pose3D &shape_pose, const rgbd::Image &image, const geo::Pose3D &sensor_pose, geo::Pose3D &updated_sensor_pose)
Definition: renderer.cpp:49
refitConvexHull
void refitConvexHull(const rgbd::Image &image, const geo::Pose3D &sensor_pose, const geo::DepthCamera &cam_model, const std::unique_ptr< Segmenter > &segmenter_, EntityUpdate &up)
Definition: kinect/updater.cpp:26
geo::Transform3T::t
Vec3T< T > t
shapes.h
std::runtime_error
tue::config::OPTIONAL
OPTIONAL
ed::UUID
Updater::Updater
Updater(tue::Configuration config)
Definition: kinect/updater.cpp:207
Updater::cloud_pub_
ros::Publisher cloud_pub_
Definition: kinect/updater.h:71
req
string req
Updater::fitter_
Fitter fitter_
Definition: kinect/updater.h:62
geo::Vector3
std::map
geo::DepthCamera::project2Dto3D
geo::Vec3T< T > project2Dto3D(int x, int y) const
geo::Vec3
Vec3T< real > Vec3
Fitter::isConfigured
bool isConfigured()
Definition: fitter.h:125
ed::WorldModel
UpdateResult::removed_entity_ids
std::vector< ed::UUID > removed_entity_ids
Definition: kinect/updater.h:41
geo::createConvexPolygon
void createConvexPolygon(geo::Shape &shape, const std::vector< geo::Vec2 > &points, double height)
std::min
T min(T... args)
std::string::substr
T substr(T... args)
view.h
tue::config::ReaderWriter::value
bool value(const std::string &name, T &value, RequiredOrOptional opt=REQUIRED)
EntityUpdate::points
std::vector< geo::Vec3 > points
Definition: kinect/entity_update.h:17
world_model.h
Updater::update
bool update(const ed::WorldModel &world, const rgbd::ImageConstPtr &image, const geo::Pose3D &sensor_pose, const UpdateRequest &req, UpdateResult &res)
Definition: kinect/updater.cpp:237
std::vector::begin
T begin(T... args)
geo::DepthCamera::project3Dto2D
cv::Point_< Tout > project3Dto2D(const geo::Vec3T< Tin > &p) const
UpdateRequest
Definition: kinect/updater.h:15
tue::config::ReaderWriter::readGroup
bool readGroup(const std::string &name, const RequiredOrOptional opt=OPTIONAL)
geo::Vector3::x
const real & x() const
Updater::mask_pub_
ros::Publisher mask_pub_
Definition: kinect/updater.h:70
EntityUpdate::chull
ed::ConvexHull chull
Definition: kinect/entity_update.h:20
geo::Vec3T::z
T z
std::vector::empty
T empty(T... args)
Fitter::configureBeamModel
void configureBeamModel(const image_geometry::PinholeCameraModel &cammodel)
configure the beam model (nr of data points and focal length) according to the camera you are using.
Definition: fitter.cpp:475
geo::DepthCamera
std::size_t
Fitter::processSensorData
void processSensorData(const rgbd::Image &image, const geo::Pose3D &sensor_pose, FitterData &data) const
processSensorData pre-processes sensor data, i.e., performs a downprojection of the input depth image...
Definition: fitter.cpp:486
std::vector::end
T end(T... args)
tue::config::REQUIRED
REQUIRED
std::max
T max(T... args)
updater.h
entity.h
ed::ConvexHull::z_max
float z_max
renderer.h
std::unique_ptr< Segmenter >
convex_hull_calc.h
EntityUpdate::id
ed::UUID id
Definition: kinect/entity_update.h:13
Updater::logging
bool logging
Definition: kinect/updater.h:72
geo::Vec3T::getX
T getX() const
Updater::id_to_area_description_
std::map< ed::UUID, std::string > id_to_area_description_
Definition: kinect/updater.h:67
rgbd::View
geo::Vec3T::x
T x
geo::Vec2T
Updater::segmenter_
std::unique_ptr< Segmenter > segmenter_
Definition: kinect/updater.h:64
ed::UUID::str
const std::string & str() const
UpdateResult
Definition: kinect/updater.h:36
geo::Shape
config
tue::config::ReaderWriter config
ed::ConvexHull::points
std::vector< geo::Vec2f > points
geo::Vec3T::getZ
T getZ() const