Point Cloud Library (PCL) 1.15.1-dev
Loading...
Searching...
No Matches
correspondence_rejection.h
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Point Cloud Library (PCL) - www.pointclouds.org
5 * Copyright (c) 2010-2011, Willow Garage, Inc.
6 * Copyright (c) 2012-, Open Perception, Inc.
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * * Neither the name of the copyright holder(s) nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * $Id$
38 *
39 */
40
41#pragma once
42
43#include <pcl/console/print.h>
44#include <pcl/registration/correspondence_sorting.h>
45#include <pcl/registration/correspondence_types.h>
46#include <pcl/search/auto.h>
47#include <pcl/search/search.h>
48#include <pcl/point_cloud.h>
49#include <pcl/point_types.h> // for PointNormal
50
51namespace pcl {
52namespace registration {
53/** @b CorrespondenceRejector represents the base class for correspondence rejection
54 * methods \author Dirk Holz \ingroup registration
55 */
57public:
58 using Ptr = shared_ptr<CorrespondenceRejector>;
59 using ConstPtr = shared_ptr<const CorrespondenceRejector>;
60
61 /** \brief Empty constructor. */
63
64 /** \brief Empty destructor. */
65 virtual ~CorrespondenceRejector() = default;
66
67 /** \brief Provide a pointer to the vector of the input correspondences.
68 * \param[in] correspondences the const shared pointer to a correspondence vector
69 */
70 virtual inline void
72 {
73 input_correspondences_ = correspondences;
74 };
75
76 /** \brief Get a pointer to the vector of the input correspondences.
77 * \return correspondences the const shared pointer to a correspondence vector
78 */
84
85 /** \brief Run correspondence rejection
86 * \param[out] correspondences Vector of correspondences that have not been rejected.
87 */
88 inline void
90 {
92 return;
93
94 applyRejection(correspondences);
95 }
96
97 /** \brief Get a list of valid correspondences after rejection from the original set
98 * of correspondences. Pure virtual. Compared to \a getCorrespondences this function
99 * is stateless, i.e., input correspondences do not need to be provided beforehand,
100 * but are directly provided in the function call.
101 * \param[in] original_correspondences the set of initial correspondences given
102 * \param[out] remaining_correspondences the resultant filtered set of remaining
103 * correspondences
104 */
105 virtual inline void
106 getRemainingCorrespondences(const pcl::Correspondences& original_correspondences,
107 pcl::Correspondences& remaining_correspondences) = 0;
108
109 /** \brief Determine the indices of query points of
110 * correspondences that have been rejected, i.e., the difference
111 * between the input correspondences (set via \a setInputCorrespondences)
112 * and the given correspondence vector.
113 * \param[in] correspondences Vector of correspondences after rejection
114 * \param[out] indices Vector of query point indices of those correspondences
115 * that have been rejected.
116 */
117 inline void
119 pcl::Indices& indices)
120 {
122 PCL_WARN("[pcl::registration::%s::getRejectedQueryIndices] Input correspondences "
123 "not set (lookup of rejected correspondences _not_ possible).\n",
124 getClassName().c_str());
125 return;
126 }
127
128 pcl::getRejectedQueryIndices(*input_correspondences_, correspondences, indices);
129 }
130
131 /** \brief Get a string representation of the name of this class. */
132 inline const std::string&
134 {
135 return (rejection_name_);
136 }
137
138 /** \brief See if this rejector requires source points */
139 virtual bool
141 {
142 return (false);
143 }
144
145 /** \brief Abstract method for setting the source cloud */
146 virtual void
148 {
149 PCL_WARN("[pcl::registration::%s::setSourcePoints] This class does not require an "
150 "input source cloud\n",
151 getClassName().c_str());
152 }
153
154 /** \brief See if this rejector requires source normals */
155 virtual bool
157 {
158 return (false);
159 }
160
161 /** \brief Abstract method for setting the source normals */
162 virtual void
164 {
165 PCL_WARN("[pcl::registration::%s::setSourceNormals] This class does not require "
166 "input source normals\n",
167 getClassName().c_str());
168 }
169 /** \brief See if this rejector requires a target cloud */
170 virtual bool
172 {
173 return (false);
174 }
175
176 /** \brief Abstract method for setting the target cloud */
177 virtual void
179 {
180 PCL_WARN("[pcl::registration::%s::setTargetPoints] This class does not require an "
181 "input target cloud\n",
182 getClassName().c_str());
183 }
184
185 /** \brief See if this rejector requires target normals */
186 virtual bool
188 {
189 return (false);
190 }
191
192 /** \brief Abstract method for setting the target normals */
193 virtual void
195 {
196 PCL_WARN("[pcl::registration::%s::setTargetNormals] This class does not require "
197 "input target normals\n",
198 getClassName().c_str());
199 }
200
201protected:
202 /** \brief The name of the rejection method. */
203 std::string rejection_name_{};
204
205 /** \brief The input correspondences. */
207
208 /** \brief Abstract rejection method. */
209 virtual void
210 applyRejection(Correspondences& correspondences) = 0;
211};
212
213/** @b DataContainerInterface provides a generic interface for computing correspondence
214 * scores between correspondent points in the input and target clouds
215 * \ingroup registration
216 */
218public:
219 using Ptr = shared_ptr<DataContainerInterface>;
220 using ConstPtr = shared_ptr<const DataContainerInterface>;
221
222 virtual ~DataContainerInterface() = default;
223 virtual double
225 virtual double
227 virtual double
229};
230
231/** @b DataContainer is a container for the input and target point clouds and implements
232 * the interface to compute correspondence scores between correspondent points in the
233 * input and target clouds \ingroup registration
234 */
235template <typename PointT, typename NormalT = pcl::PointNormal>
237 using PointCloud = pcl::PointCloud<PointT>;
238 using PointCloudPtr = typename PointCloud::Ptr;
239 using PointCloudConstPtr = typename PointCloud::ConstPtr;
240
241 using KdTreePtr = typename pcl::search::Search<PointT>::Ptr;
242
244 using NormalsPtr = typename Normals::Ptr;
245 using NormalsConstPtr = typename Normals::ConstPtr;
246
247public:
248 /** \brief Empty constructor. */
249 DataContainer(bool needs_normals = false)
250 : input_()
251 , input_transformed_()
252 , target_()
253 , input_normals_()
254 , input_normals_transformed_()
255 , target_normals_()
256 , class_name_("DataContainer")
257 , needs_normals_(needs_normals)
258 {}
259
260 /** \brief Empty destructor */
261 ~DataContainer() override = default;
262
263 /** \brief Provide a source point cloud dataset (must contain XYZ
264 * data!), used to compute the correspondence distance.
265 * \param[in] cloud a cloud containing XYZ data
266 */
267 inline void
268 setInputSource(const PointCloudConstPtr& cloud)
269 {
270 input_ = cloud;
271 }
272
273 /** \brief Get a pointer to the input point cloud dataset target. */
274 inline PointCloudConstPtr const
276 {
277 return (input_);
278 }
279
280 /** \brief Provide a target point cloud dataset (must contain XYZ
281 * data!), used to compute the correspondence distance.
282 * \param[in] target a cloud containing XYZ data
283 */
284 inline void
285 setInputTarget(const PointCloudConstPtr& target)
286 {
287 target_ = target;
288 target_cloud_updated_ = true;
289 }
290
291 /** \brief Get a pointer to the input point cloud dataset target. */
292 inline PointCloudConstPtr const
294 {
295 return (target_);
296 }
297
298 /** \brief Provide a pointer to the search object used to find correspondences in
299 * the target cloud.
300 * \param[in] tree a pointer to the spatial search object.
301 * \param[in] force_no_recompute If set to true, this tree will NEVER be
302 * recomputed, regardless of calls to setInputTarget. Only use if you are
303 * confident that the tree will be set correctly.
304 */
305 inline void
306 setSearchMethodTarget(const KdTreePtr& tree, bool force_no_recompute = false)
307 {
308 tree_ = tree;
309 force_no_recompute_ = force_no_recompute;
310 target_cloud_updated_ = true;
311 }
312
313 /** \brief Set the normals computed on the input point cloud
314 * \param[in] normals the normals computed for the input cloud
315 */
316 inline void
317 setInputNormals(const NormalsConstPtr& normals)
318 {
319 input_normals_ = normals;
320 }
321
322 /** \brief Get the normals computed on the input point cloud */
323 inline NormalsConstPtr
325 {
326 return (input_normals_);
327 }
328
329 /** \brief Set the normals computed on the target point cloud
330 * \param[in] normals the normals computed for the input cloud
331 */
332 inline void
333 setTargetNormals(const NormalsConstPtr& normals)
334 {
335 target_normals_ = normals;
336 }
337
338 /** \brief Get the normals computed on the target point cloud */
339 inline NormalsConstPtr
341 {
342 return (target_normals_);
343 }
344
345 /** \brief Get the correspondence score for a point in the input cloud
346 * \param[in] index index of the point in the input cloud
347 */
348 inline double
349 getCorrespondenceScore(int index) override
350 {
351 if (target_cloud_updated_ && !force_no_recompute_) {
352 if (!tree_ || !tree_->setInputCloud(target_))
353 tree_.reset(pcl::search::autoSelectMethod<PointT>(
354 target_, false, pcl::search::Purpose::one_knn_search));
355 target_cloud_updated_ = false;
356 }
357 pcl::Indices indices(1);
358 std::vector<float> distances(1);
359 if (tree_->nearestKSearch((*input_)[index], 1, indices, distances))
360 return (distances[0]);
361 return (std::numeric_limits<double>::max());
362 }
363
364 /** \brief Get the correspondence score for a given pair of correspondent points
365 * \param[in] corr Correspondent points
366 */
367 inline double
369 {
370 // Get the source and the target feature from the list
371 const PointT& src = (*input_)[corr.index_query];
372 const PointT& tgt = (*target_)[corr.index_match];
373
374 return ((src.getVector4fMap() - tgt.getVector4fMap()).squaredNorm());
375 }
376
377 /** \brief Get the correspondence score for a given pair of correspondent points based
378 * on the angle between the normals. The normmals for the in put and target clouds
379 * must be set before using this function \param[in] corr Correspondent points
380 */
381 inline double
383 {
384 // assert ( (input_normals_->size () != 0) && (target_normals_->size () != 0) &&
385 // "Normals are not set for the input and target point clouds");
386 assert(input_normals_ && target_normals_ &&
387 "Normals are not set for the input and target point clouds");
388 const NormalT& src = (*input_normals_)[corr.index_query];
389 const NormalT& tgt = (*target_normals_)[corr.index_match];
390 return (static_cast<double>((src.normal[0] * tgt.normal[0]) +
391 (src.normal[1] * tgt.normal[1]) +
392 (src.normal[2] * tgt.normal[2])));
393 }
394
395private:
396 /** \brief The input point cloud dataset */
397 PointCloudConstPtr input_;
398
399 /** \brief The input transformed point cloud dataset */
400 PointCloudPtr input_transformed_;
401
402 /** \brief The target point cloud dataset. */
403 PointCloudConstPtr target_;
404
405 /** \brief Normals to the input point cloud */
406 NormalsConstPtr input_normals_;
407
408 /** \brief Normals to the input point cloud */
409 NormalsPtr input_normals_transformed_;
410
411 /** \brief Normals to the target point cloud */
412 NormalsConstPtr target_normals_;
413
414 /** \brief A pointer to the spatial search object. */
415 KdTreePtr tree_;
416
417 /** \brief The name of the rejection method. */
418 std::string class_name_;
419
420 /** \brief Should the current data container use normals? */
421 bool needs_normals_;
422
423 /** \brief Variable that stores whether we have a new target cloud, meaning we need to
424 * pre-process it again. This way, we avoid rebuilding the kd-tree */
425 bool target_cloud_updated_{true};
426
427 /** \brief A flag which, if set, means the tree operating on the target cloud
428 * will never be recomputed*/
429 bool force_no_recompute_{false};
430
431 /** \brief Get a string representation of the name of this class. */
432 inline const std::string&
433 getClassName() const
434 {
435 return (class_name_);
436 }
437};
438} // namespace registration
439} // namespace pcl
PointCloud represents the base class in PCL for storing collections of 3D points.
shared_ptr< PointCloud< PointT > > Ptr
shared_ptr< const PointCloud< PointT > > ConstPtr
CorrespondenceRejector represents the base class for correspondence rejection methods
virtual bool requiresSourceNormals() const
See if this rejector requires source normals.
CorrespondenceRejector()=default
Empty constructor.
virtual void setSourceNormals(pcl::PCLPointCloud2::ConstPtr)
Abstract method for setting the source normals.
virtual void getRemainingCorrespondences(const pcl::Correspondences &original_correspondences, pcl::Correspondences &remaining_correspondences)=0
Get a list of valid correspondences after rejection from the original set of correspondences.
virtual void setSourcePoints(pcl::PCLPointCloud2::ConstPtr)
Abstract method for setting the source cloud.
virtual void setTargetNormals(pcl::PCLPointCloud2::ConstPtr)
Abstract method for setting the target normals.
shared_ptr< const CorrespondenceRejector > ConstPtr
virtual void applyRejection(Correspondences &correspondences)=0
Abstract rejection method.
void getCorrespondences(pcl::Correspondences &correspondences)
Run correspondence rejection.
virtual bool requiresSourcePoints() const
See if this rejector requires source points.
CorrespondencesConstPtr input_correspondences_
The input correspondences.
void getRejectedQueryIndices(const pcl::Correspondences &correspondences, pcl::Indices &indices)
Determine the indices of query points of correspondences that have been rejected, i....
shared_ptr< CorrespondenceRejector > Ptr
virtual bool requiresTargetPoints() const
See if this rejector requires a target cloud.
virtual bool requiresTargetNormals() const
See if this rejector requires target normals.
std::string rejection_name_
The name of the rejection method.
virtual ~CorrespondenceRejector()=default
Empty destructor.
const std::string & getClassName() const
Get a string representation of the name of this class.
CorrespondencesConstPtr getInputCorrespondences()
Get a pointer to the vector of the input correspondences.
virtual void setTargetPoints(pcl::PCLPointCloud2::ConstPtr)
Abstract method for setting the target cloud.
virtual void setInputCorrespondences(const CorrespondencesConstPtr &correspondences)
Provide a pointer to the vector of the input correspondences.
DataContainer is a container for the input and target point clouds and implements the interface to co...
NormalsConstPtr getTargetNormals()
Get the normals computed on the target point cloud.
void setInputTarget(const PointCloudConstPtr &target)
Provide a target point cloud dataset (must contain XYZ data!), used to compute the correspondence dis...
PointCloudConstPtr const getInputSource()
Get a pointer to the input point cloud dataset target.
double getCorrespondenceScore(int index) override
Get the correspondence score for a point in the input cloud.
double getCorrespondenceScore(const pcl::Correspondence &corr) override
Get the correspondence score for a given pair of correspondent points.
NormalsConstPtr getInputNormals()
Get the normals computed on the input point cloud.
void setInputSource(const PointCloudConstPtr &cloud)
Provide a source point cloud dataset (must contain XYZ data!), used to compute the correspondence dis...
void setTargetNormals(const NormalsConstPtr &normals)
Set the normals computed on the target point cloud.
double getCorrespondenceScoreFromNormals(const pcl::Correspondence &corr) override
Get the correspondence score for a given pair of correspondent points based on the angle between the ...
void setSearchMethodTarget(const KdTreePtr &tree, bool force_no_recompute=false)
Provide a pointer to the search object used to find correspondences in the target cloud.
DataContainer(bool needs_normals=false)
Empty constructor.
void setInputNormals(const NormalsConstPtr &normals)
Set the normals computed on the input point cloud.
PointCloudConstPtr const getInputTarget()
Get a pointer to the input point cloud dataset target.
~DataContainer() override=default
Empty destructor.
DataContainerInterface provides a generic interface for computing correspondence scores between corre...
virtual double getCorrespondenceScore(int index)=0
shared_ptr< const DataContainerInterface > ConstPtr
shared_ptr< DataContainerInterface > Ptr
virtual double getCorrespondenceScore(const pcl::Correspondence &)=0
virtual double getCorrespondenceScoreFromNormals(const pcl::Correspondence &)=0
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition search.h:84
Defines all the PCL implemented PointT point type structures.
@ one_knn_search
The search method will mainly be used for nearestKSearch where k is 1.
shared_ptr< const Correspondences > CorrespondencesConstPtr
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition types.h:133
void getRejectedQueryIndices(const pcl::Correspondences &correspondences_before, const pcl::Correspondences &correspondences_after, Indices &indices, bool presorting_required=true)
Get the query points of correspondences that are present in one correspondence vector but not in the ...
Correspondence represents a match between two entities (e.g., points, descriptors,...
index_t index_query
Index of the query (source) point.
index_t index_match
Index of the matching (target) point.
A point structure representing normal coordinates and the surface curvature estimate.
shared_ptr< const ::pcl::PCLPointCloud2 > ConstPtr
A point structure representing Euclidean xyz coordinates, and the RGB color.