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