5 #ifndef OPENGR_FUNCTOR4PCS_H 6 #define OPENGR_FUNCTOR4PCS_H 9 #include "gr/utils/shared.h" 17 template <
typename PointType,
typename PairFilterFunctor,
typename Options>
21 using Scalar =
typename PointType::Scalar;
23 using VectorType =
typename PointType::VectorType;
24 using OptionType = Options;
28 OptionType myOptions_;
29 std::vector<PointType>& mySampled_Q_3D_;
30 BaseCoordinates &myBase_3D_;
35 BaseCoordinates& base_3D_,
36 const OptionType &options)
39 ,myOptions_ (options) {}
62 Scalar distance_threshold2,
63 const std::vector <std::pair<
int,
int>> &First_pairs,
64 const std::vector <std::pair<
int,
int>> &Second_pairs,
66 using RangeQuery =
typename gr::KdTree<Scalar>::
template RangeQuery<>;
68 if (quadrilaterals == nullptr)
return false;
70 size_t number_of_points = 2 * First_pairs.size();
75 quadrilaterals->clear();
77 gr::KdTree<Scalar> kdtree(number_of_points);
80 for (size_t i = 0; i < First_pairs.size(); ++i) {
81 const VectorType &p1 = mySampled_Q_3D_[First_pairs[i].first].pos();
82 const VectorType &p2 = mySampled_Q_3D_[First_pairs[i].second].pos();
83 kdtree.add(p1 + invariant1 * (p2 - p1));
89 for (size_t i = 0; i < Second_pairs.size(); ++i) {
90 const VectorType &p1 = mySampled_Q_3D_[Second_pairs[i].first].pos();
91 const VectorType &p2 = mySampled_Q_3D_[Second_pairs[i].second].pos();
94 query.queryPoint = p1 + invariant2 * (p2 - p1);
95 query.sqdist = distance_threshold2;
97 kdtree.doQueryDistProcessIndices(query,
98 [quadrilaterals, i, &First_pairs, &Second_pairs](
int id) {
99 quadrilaterals->push_back(
100 { First_pairs[id].first,
101 First_pairs[id].second,
102 Second_pairs[i].first,
103 Second_pairs[i].second });
107 return quadrilaterals->size() != 0;
124 Scalar pair_normals_angle,
125 Scalar pair_distance_epsilon,
128 PairsVector* pairs)
const {
129 if (pairs == nullptr)
return;
132 pairs->reserve(2 * mySampled_Q_3D_.size());
134 PairFilterFunctor fun;
137 for (size_t j = 0; j < mySampled_Q_3D_.size(); ++j) {
138 const PointType& p = mySampled_Q_3D_[j];
139 for (size_t i = j + 1; i < mySampled_Q_3D_.size(); ++i) {
140 const PointType& q = mySampled_Q_3D_[i];
147 const Scalar distance = (q.pos() - p.pos()).norm();
148 if (std::abs(distance - pair_distance) > pair_distance_epsilon)
continue;
151 std::pair<
bool,
bool> res = fun(p,q, pair_normals_angle, *myBase_3D_[base_point1],*myBase_3D_[base_point2], myOptions_);
153 pairs->emplace_back(i, j);
155 pairs->emplace_back(j, i);
Functor4PCS(std::vector< PointType > &sampled_Q_3D_, BaseCoordinates &base_3D_, const OptionType &options)
Definition: Functor4pcs.h:34
Processing functor for the computation of the 4PCS algorithm.
Definition: Functor4pcs.h:18
bool FindCongruentQuadrilaterals(Scalar invariant1, Scalar invariant2, Scalar, Scalar distance_threshold2, const std::vector< std::pair< int, int >> &First_pairs, const std::vector< std::pair< int, int >> &Second_pairs, typename Traits4pcs< PointType >::Set *quadrilaterals) const
Finds congruent candidates in the set Q, given the invariants and threshold distances. Returns true if a non empty set can be found, false otherwise.
Definition: Functor4pcs.h:58
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 Initialize()
Initializes the data structures and needed values before the match computation.
Definition: Functor4pcs.h:43
void ExtractPairs(Scalar pair_distance, Scalar pair_normals_angle, Scalar pair_distance_epsilon, int base_point1, int base_point2, PairsVector *pairs) const
Constructs pairs of points in Q, corresponding to a single pair in the in basein P.
Definition: Functor4pcs.h:123