registrationMetrics.h
Go to the documentation of this file.
1 // Copyright 2020 Nicolas Mellado
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // -------------------------------------------------------------------------- //
16 //
17 // Authors: Nicolas Mellado
18 //
19 // This file is part of the OpenGR library
20 //
21 
22 #ifndef _OPENGR_UTILS_REGISTRATION_METRICS_H
23 #define _OPENGR_UTILS_REGISTRATION_METRICS_H
24 
25 #include "gr/accelerators/kdtree.h"
26 #include <Eigen/Core> // Eigen::Ref
27 
28 namespace gr{
29 namespace Utils{
30 
31 /// \brief Implementation of the Largest Common PointSet metric
32 ///
33 template <typename Scalar>
34 struct LCPMetric {
35  /// Support size of the LCP
37 
38  template <typename Range>
39  inline Scalar operator()( const gr::KdTree<Scalar> & ref,
40  const Range& target,
41  const Eigen::Ref<const Eigen::MatrixXf>& mat,
42  Scalar terminate_value = Scalar( 0 ))
43  {
44  using RangeQuery = typename gr::KdTree<Scalar>::template RangeQuery<>;
45 
46  std::atomic_uint good_points(0);
47 
48  const size_t number_of_points = target.size();
49  const size_t terminate_int_value = terminate_value * number_of_points;
50  const Scalar sq_eps = epsilon_*epsilon_;
51 
52  for (size_t i = 0; i < number_of_points; ++i) {
53 
54  // Use the kdtree to get the nearest neighbor
55  RangeQuery query;
56  query.queryPoint = (mat * target[i].pos().homogeneous()).template head<3>();
57  query.sqdist = sq_eps;
58 
59  if ( ref.doQueryRestrictedClosestIndex( query ).first != gr::KdTree<Scalar>::invalidIndex() ) {
60  good_points++;
61  }
62 
63  // We can terminate if there is no longer chance to get better than terminate_value
64  if (number_of_points - i + good_points < terminate_int_value) { break; }
65  }
66  return Scalar(good_points) / Scalar(number_of_points);
67  }
68 };
69 
70 /// \brief Implementation of a weighted variant of the Largest Common PointSet metric.
71 ///
72 template <typename Scalar>
74  /// Support size of the LCP
76 
77  template <typename Range>
78  inline Scalar operator()( const gr::KdTree<Scalar> & ref,
79  const Range& target,
80  const Eigen::Ref<const Eigen::MatrixXf>& mat,
81  Scalar terminate_value = Scalar( 0 ))
82  {
83  using RangeQuery = typename gr::KdTree<Scalar>::template RangeQuery<>;
84 
85  std::atomic<Scalar> good_points(0);
86 
87  auto kernel = [](Scalar x) {
88  return std::pow(std::pow(x,4) - Scalar(1), 2);
89  };
90 
91  auto computeWeight = [kernel](Scalar sqx, Scalar th) {
92  return kernel( std::sqrt(sqx) / th );
93  };
94 
95  const size_t number_of_points = target.size();
96  const size_t terminate_int_value = terminate_value * number_of_points;
97  const Scalar sq_eps = epsilon_*epsilon_;
98 
99  for (size_t i = 0; i < number_of_points; ++i) {
100 
101  // Use the kdtree to get the nearest neighbor
102  RangeQuery query;
103  query.queryPoint = (mat * target[i].pos().homogeneous()).template head<3>();
104  query.sqdist = sq_eps;
105 
106  auto result = ref.doQueryRestrictedClosestIndex( query );
107 
108  if ( result.first != gr::KdTree<Scalar>::invalidIndex() ) {
109  assert (result.second <= query.sqdist);
110  good_points = good_points + computeWeight(result.second, epsilon_);
111  }
112 
113  // We can terminate if there is no longer chance to get better than terminate_value
114  if (number_of_points - i + good_points < terminate_int_value) { break; }
115  }
116  return Scalar(good_points) / Scalar(number_of_points);
117  }
118 };
119 
120 } // namespace Utils
121 } // namespace gr
122 
123 
124 #endif // _OPENGR_UTILS_REGISTRATION_METRICS_H
Scalar operator()(const gr::KdTree< Scalar > &ref, const Range &target, const Eigen::Ref< const Eigen::MatrixXf > &mat, Scalar terminate_value=Scalar(0))
Definition: registrationMetrics.h:39
Scalar epsilon_
Support size of the LCP.
Definition: registrationMetrics.h:36
Scalar epsilon_
Support size of the LCP.
Definition: registrationMetrics.h:75
Implementation of the Largest Common PointSet metric.
Definition: registrationMetrics.h:34
CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::Scalar ComputeTransformation(const InputRange1 &P, const InputRange2 &Q, Eigen::Ref< typename CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::MatrixType > transformation, const Sampler< PointType > &sampler, TransformVisitor &v)
Definition: congruentSetExplorationBase.hpp:61
void get(int queryId, int nElPerDim, int, typename NeighborhoodType< 3 >::ptr first, typename NeighborhoodType< 3 >::ptr)
Definition: utils.h:279
Scalar operator()(const gr::KdTree< Scalar > &ref, const Range &target, const Eigen::Ref< const Eigen::MatrixXf > &mat, Scalar terminate_value=Scalar(0))
Definition: registrationMetrics.h:78
Implementation of a weighted variant of the Largest Common PointSet metric.
Definition: registrationMetrics.h:73