edge_weight_computer.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2014-, Open Perception, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #ifndef PCL_GRAPH_EDGE_WEIGHT_COMPUTER_H
39 #define PCL_GRAPH_EDGE_WEIGHT_COMPUTER_H
40 
41 #include <boost/function.hpp>
42 
43 #include "point_cloud_graph.h"
45 
47 
48 namespace pcl::graph
49 {
50 
195  template <typename GraphT>
196  class PCL_EXPORTS EdgeWeightComputer
197  {
198 
199  BOOST_CONCEPT_ASSERT((pcl::graph::PointCloudGraphConcept<GraphT>));
200 
201  public:
202 
204  typedef boost::function<float (float, float)> TermBalancingFunction;
206 
209  {
215  NORMALIZATION_LOCAL
216  };
217 
221  {
232  };
233 
240  : policy_(SMALL_WEIGHT_IGNORE)
241  , threshold_(0.0f)
242  , balancing_function_(&EdgeWeightComputer<GraphT>::gaussian)
243  {
244  }
245 
256  template <typename EdgeWeightMap> void
257  compute(GraphT& graph, EdgeWeightMap weights);
258 
268  inline void
269  compute(GraphT& graph)
270  {
271  compute(graph, boost::get(boost::edge_weight, graph));
272  }
273 
285  template <typename TermT> void
286  addTerm(float influence,
287  float convex_influence_multiplier = 1.0,
288  NormalizationType normalization = NORMALIZATION_NONE)
289  {
290  addTermImpl<TermT> (influence, convex_influence_multiplier, normalization,
291  typename boost::mpl::apply<typename TermT::is_compatible, PointT>::type());
292  }
293 
298  template <typename TermT> void
299  addTerm(float influence,
300  NormalizationType normalization)
301  {
302  addTermImpl<TermT> (influence, 1.0, normalization,
303  typename boost::mpl::apply<typename TermT::is_compatible, PointT>::type());
304  }
305 
307  inline void
309  {
310  policy_ = policy;
311  }
312 
314  inline void
315  setSmallWeightThreshold(float threshold)
316  {
317  threshold_ = threshold;
318  }
319 
321  inline void
323  {
324  balancing_function_ = func;
325  }
326 
327  private:
328 
330  static float
331  gaussian(float val, float influence)
332  {
333  return (influence > 0.0 ? std::exp(-val / influence) : 1.0);
334  };
335 
338  struct Term
339  {
340 
341  typedef boost::function<float (const PointT&, const PointT&)> ComputeFunction;
342 
343  ComputeFunction compute_;
344  float influence_;
345  float convex_influence_multiplier_;
346 
347  Term(ComputeFunction f, float i, float c)
348  : compute_(f)
349  , influence_(i)
350  , convex_influence_multiplier_(c)
351  {
352  }
353 
354  inline float
355  getInfluence(bool is_convex = false) const
356  {
357  return (influence_ * (is_convex ? convex_influence_multiplier_ : 1.0));
358  }
359 
360  };
361 
365  struct GloballyNormalizedTerm : Term
366  {
367 
368  GloballyNormalizedTerm(typename Term::ComputeFunction f, float i, float c)
369  : Term(f, i, c)
370  {
371  }
372 
373  void
374  init(size_t num_edges)
375  {
376  edge_weights_.resize(num_edges, 0.0f);
377  total_weight_ = 0.0f;
378  }
379 
380  float
381  round1(const PointT& p1, const PointT& p2, size_t edge_id)
382  {
383  float weight = this->compute_(p1, p2);
384  edge_weights_[edge_id] = weight;
385  total_weight_ += weight;
386  return (weight);
387  }
388 
389  void
390  extract()
391  {
392  average_ = total_weight_ / edge_weights_.size();
393  }
394 
395  float
396  round2(size_t edge_id)
397  {
398  return (edge_weights_[edge_id] / average_);
399  }
400 
401  std::vector<float> edge_weights_;
402  float total_weight_;
403  float average_;
404 
405  };
406 
410  struct LocallyNormalizedTerm : Term
411  {
412 
413  LocallyNormalizedTerm(typename Term::ComputeFunction f, float i, float c)
414  : Term(f, i, c)
415  {
416  }
417 
418  void
419  init(size_t num_edges, size_t num_vertices)
420  {
421  edge_weights_.resize(num_edges, 0.0f);
422  vertex_sums_.resize(num_vertices, 0.0f);
423  vertex_degrees_.resize(num_vertices, 0);
424  }
425 
426  float
427  round1(const PointT& p1,
428  const PointT& p2,
429  size_t vertex1_id,
430  size_t vertex2_id,
431  size_t edge_id)
432  {
433  float weight = this->compute_(p1, p2);
434  edge_weights_[edge_id] = weight;
435  vertex_sums_[vertex1_id] += weight;
436  vertex_sums_[vertex2_id] += weight;
437  ++vertex_degrees_[vertex1_id];
438  ++vertex_degrees_[vertex2_id];
439  return (weight);
440  }
441 
442  void
443  extract()
444  {
445  for (size_t i = 0; i < vertex_sums_.size(); ++i)
446  if (vertex_degrees_[i])
447  {
448  vertex_sums_[i] /= vertex_degrees_[i];
449  }
450  }
451 
452  float
453  round2(size_t vertex1_id,
454  size_t vertex2_id,
455  size_t edge_id) const
456  {
457  float n = (vertex_sums_[vertex1_id] + vertex_sums_[vertex2_id]) / 2.0;
458  float weight = (n > 0.0f && this->getInfluence() > 0.0f)
459  ? edge_weights_[edge_id] / n
460  : 0.0f;
461  return (weight);
462  }
463 
464  std::vector<float> edge_weights_;
465  std::vector<float> vertex_sums_;
466  std::vector<size_t> vertex_degrees_;
467 
468  };
469 
470  template <typename TermT> void
471  addTermImpl(float influence,
472  float convex_influence_multiplier,
473  NormalizationType normalization,
474  boost::mpl::bool_<true>)
475  {
476  switch (normalization)
477  {
478  case NORMALIZATION_NONE:
479  {
480  terms_.push_back(Term(TermT::template compute<PointT>, influence, convex_influence_multiplier));
481  break;
482  }
483  case NORMALIZATION_GLOBAL:
484  {
485  g_terms_.push_back(GloballyNormalizedTerm(TermT::template compute<PointT>, influence, convex_influence_multiplier));
486  break;
487  }
488  case NORMALIZATION_LOCAL:
489  {
490  l_terms_.push_back(LocallyNormalizedTerm(TermT::template compute<PointT>, influence, convex_influence_multiplier));
491  break;
492  }
493  }
494  }
495 
498  template <typename TermT> void
499  addTermImpl(float influence,
500  float convex_influence_multiplier,
501  NormalizationType normalization,
502  boost::mpl::bool_<false>)
503  {
504  }
505 
506  std::vector<Term> terms_;
507  std::vector<GloballyNormalizedTerm> g_terms_;
508  std::vector<LocallyNormalizedTerm> l_terms_;
509 
510  SmallWeightPolicy policy_;
511  float threshold_;
512  TermBalancingFunction balancing_function_;
513 
514  };
515 
516 }
517 
518 
519 #include "edge_weight_computer.hpp"
520 
521 #endif /* PCL_GRAPH_EDGE_WEIGHT_COMPUTER_H */
522 
pcl::graph::EdgeWeightComputer::setSmallWeightThreshold
void setSmallWeightThreshold(float threshold)
Set the threshold for edge weights.
Definition: edge_weight_computer.h:315
pcl::graph::EdgeWeightComputer
This class computes edge weights for a given point cloud graph.
Definition: edge_weight_computer.h:196
pcl::graph::EdgeWeightComputer::SMALL_WEIGHT_COERCE_TO_THRESHOLD
@ SMALL_WEIGHT_COERCE_TO_THRESHOLD
Coerce the weight to the threshold.
Definition: edge_weight_computer.h:227
boost::shared_ptr
Definition: IceGridAdmin.h:51
pcl::graph::EdgeWeightComputer::addTerm
void addTerm(float influence, float convex_influence_multiplier=1.0, NormalizationType normalization=NORMALIZATION_NONE)
Add a term to the edge weighting function.
Definition: edge_weight_computer.h:286
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
PointCloudGraphConcept
pcl::graph::EdgeWeightComputer::setTermBalancingFunction
void setTermBalancingFunction(TermBalancingFunction func)
Set the function used to balance the contributions of the terms.
Definition: edge_weight_computer.h:322
pcl::graph::EdgeWeightComputer::Ptr
boost::shared_ptr< EdgeWeightComputer > Ptr
Definition: edge_weight_computer.h:205
pcl::graph
Definition: common.h:45
pcl::graph::EdgeWeightComputer::NormalizationType
NormalizationType
Different normalization types that could be applied to a term.
Definition: edge_weight_computer.h:208
point_cloud_graph_concept.h
edge_weight_computer.hpp
pcl::graph::EdgeWeightComputer::EdgeWeightComputer
EdgeWeightComputer()
Construct a weight computer with default settings.
Definition: edge_weight_computer.h:239
pcl::graph::EdgeWeightComputer::compute
void compute(GraphT &graph)
Compute weights for the edges in a given graph.
Definition: edge_weight_computer.h:269
pcl::graph::EdgeWeightComputer::SMALL_WEIGHT_IGNORE
@ SMALL_WEIGHT_IGNORE
Do nothing, leave the weights and edges as is.
Definition: edge_weight_computer.h:223
armarx::PointT
pcl::PointXYZRGBL PointT
Definition: Common.h:28
pcl::graph::EdgeWeightComputer::TermBalancingFunction
boost::function< float(float, float)> TermBalancingFunction
Definition: edge_weight_computer.h:204
pcl::graph::point_cloud_graph_traits::point_type
Graph::point_type point_type
The type of PCL points bundled in vertices.
Definition: point_cloud_graph.h:560
edge_weight_computer_terms.h
pcl::graph::EdgeWeightComputer::addTerm
void addTerm(float influence, NormalizationType normalization)
Add a term to the edge weighting function.
Definition: edge_weight_computer.h:299
float
#define float
Definition: 16_Level.h:22
pcl::graph::EdgeWeightComputer::NORMALIZATION_NONE
@ NORMALIZATION_NONE
No normalization.
Definition: edge_weight_computer.h:211
pcl::graph::EdgeWeightComputer::NORMALIZATION_GLOBAL
@ NORMALIZATION_GLOBAL
Global normalization.
Definition: edge_weight_computer.h:213
pcl::graph::EdgeWeightComputer::setSmallWeightPolicy
void setSmallWeightPolicy(SmallWeightPolicy policy)
Set the policy for edges with small (below threshold) weights.
Definition: edge_weight_computer.h:308
pcl::graph::EdgeWeightComputer::SMALL_WEIGHT_REMOVE_EDGE
@ SMALL_WEIGHT_REMOVE_EDGE
Remove edges with weights below threshold.
Definition: edge_weight_computer.h:231
pcl::graph::EdgeWeightComputer::PointT
pcl::graph::point_cloud_graph_traits< GraphT >::point_type PointT
Definition: edge_weight_computer.h:203
point_cloud_graph.h
pcl::graph::EdgeWeightComputer::SmallWeightPolicy
SmallWeightPolicy
Policy which controls what happens to edges with small weights (i.e.
Definition: edge_weight_computer.h:220