Point Cloud Library (PCL)
1.7.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * Copyright (c) 2012-, Open Perception, Inc. 00007 * 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 00014 * * Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * * Redistributions in binary form must reproduce the above 00017 * copyright notice, this list of conditions and the following 00018 * disclaimer in the documentation and/or other materials provided 00019 * with the distribution. 00020 * * Neither the name of the copyright holder(s) nor the names of its 00021 * contributors may be used to endorse or promote products derived 00022 * from this software without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00026 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00027 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00028 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00029 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00030 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00031 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00033 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00034 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00035 * POSSIBILITY OF SUCH DAMAGE. 00036 * 00037 * $Id$ 00038 * 00039 */ 00040 00041 #ifndef PCL_REGISTRATION_H_ 00042 #define PCL_REGISTRATION_H_ 00043 00044 // PCL includes 00045 #include <pcl/pcl_base.h> 00046 #include <pcl/common/transforms.h> 00047 #include <pcl/pcl_macros.h> 00048 #include <pcl/search/kdtree.h> 00049 #include <pcl/kdtree/kdtree_flann.h> 00050 #include <pcl/registration/boost.h> 00051 #include <pcl/registration/transformation_estimation.h> 00052 #include <pcl/registration/correspondence_estimation.h> 00053 #include <pcl/registration/correspondence_rejection.h> 00054 00055 namespace pcl 00056 { 00057 /** \brief @b Registration represents the base registration class for general purpose, ICP-like methods. 00058 * \author Radu B. Rusu, Michael Dixon 00059 * \ingroup registration 00060 */ 00061 template <typename PointSource, typename PointTarget, typename Scalar = float> 00062 class Registration : public PCLBase<PointSource> 00063 { 00064 public: 00065 typedef Eigen::Matrix<Scalar, 4, 4> Matrix4; 00066 00067 // using PCLBase<PointSource>::initCompute; 00068 using PCLBase<PointSource>::deinitCompute; 00069 using PCLBase<PointSource>::input_; 00070 using PCLBase<PointSource>::indices_; 00071 00072 typedef boost::shared_ptr< Registration<PointSource, PointTarget, Scalar> > Ptr; 00073 typedef boost::shared_ptr< const Registration<PointSource, PointTarget, Scalar> > ConstPtr; 00074 00075 typedef typename pcl::registration::CorrespondenceRejector::Ptr CorrespondenceRejectorPtr; 00076 typedef pcl::search::KdTree<PointTarget> KdTree; 00077 typedef typename pcl::search::KdTree<PointTarget>::Ptr KdTreePtr; 00078 00079 typedef pcl::search::KdTree<PointSource> KdTreeReciprocal; 00080 typedef typename KdTree::Ptr KdTreeReciprocalPtr; 00081 00082 typedef pcl::PointCloud<PointSource> PointCloudSource; 00083 typedef typename PointCloudSource::Ptr PointCloudSourcePtr; 00084 typedef typename PointCloudSource::ConstPtr PointCloudSourceConstPtr; 00085 00086 typedef pcl::PointCloud<PointTarget> PointCloudTarget; 00087 typedef typename PointCloudTarget::Ptr PointCloudTargetPtr; 00088 typedef typename PointCloudTarget::ConstPtr PointCloudTargetConstPtr; 00089 00090 typedef typename KdTree::PointRepresentationConstPtr PointRepresentationConstPtr; 00091 00092 typedef typename pcl::registration::TransformationEstimation<PointSource, PointTarget, Scalar> TransformationEstimation; 00093 typedef typename TransformationEstimation::Ptr TransformationEstimationPtr; 00094 typedef typename TransformationEstimation::ConstPtr TransformationEstimationConstPtr; 00095 00096 typedef typename pcl::registration::CorrespondenceEstimationBase<PointSource, PointTarget, Scalar> CorrespondenceEstimation; 00097 typedef typename CorrespondenceEstimation::Ptr CorrespondenceEstimationPtr; 00098 typedef typename CorrespondenceEstimation::ConstPtr CorrespondenceEstimationConstPtr; 00099 00100 /** \brief Empty constructor. */ 00101 Registration () 00102 : reg_name_ () 00103 , tree_ (new KdTree) 00104 , tree_reciprocal_ (new KdTreeReciprocal) 00105 , nr_iterations_ (0) 00106 , max_iterations_ (10) 00107 , ransac_iterations_ (0) 00108 , target_ () 00109 , final_transformation_ (Matrix4::Identity ()) 00110 , transformation_ (Matrix4::Identity ()) 00111 , previous_transformation_ (Matrix4::Identity ()) 00112 , transformation_epsilon_ (0.0) 00113 , euclidean_fitness_epsilon_ (-std::numeric_limits<double>::max ()) 00114 , corr_dist_threshold_ (std::sqrt (std::numeric_limits<double>::max ())) 00115 , inlier_threshold_ (0.05) 00116 , converged_ (false) 00117 , min_number_correspondences_ (3) 00118 , correspondences_ (new Correspondences) 00119 , transformation_estimation_ () 00120 , correspondence_estimation_ () 00121 , correspondence_rejectors_ () 00122 , target_cloud_updated_ (true) 00123 , source_cloud_updated_ (true) 00124 , force_no_recompute_ (false) 00125 , force_no_recompute_reciprocal_ (false) 00126 , update_visualizer_ (NULL) 00127 , point_representation_ () 00128 { 00129 } 00130 00131 /** \brief destructor. */ 00132 virtual ~Registration () {} 00133 00134 /** \brief Provide a pointer to the transformation estimation object. 00135 * (e.g., SVD, point to plane etc.) 00136 * 00137 * \param[in] te is the pointer to the corresponding transformation estimation object 00138 * 00139 * Code example: 00140 * 00141 * \code 00142 * TransformationEstimationPointToPlaneLLS<PointXYZ, PointXYZ>::Ptr trans_lls (new TransformationEstimationPointToPlaneLLS<PointXYZ, PointXYZ>); 00143 * icp.setTransformationEstimation (trans_lls); 00144 * // or... 00145 * TransformationEstimationSVD<PointXYZ, PointXYZ>::Ptr trans_svd (new TransformationEstimationSVD<PointXYZ, PointXYZ>); 00146 * icp.setTransformationEstimation (trans_svd); 00147 * \endcode 00148 */ 00149 void 00150 setTransformationEstimation (const TransformationEstimationPtr &te) { transformation_estimation_ = te; } 00151 00152 /** \brief Provide a pointer to the correspondence estimation object. 00153 * (e.g., regular, reciprocal, normal shooting etc.) 00154 * 00155 * \param[in] ce is the pointer to the corresponding correspondence estimation object 00156 * 00157 * Code example: 00158 * 00159 * \code 00160 * CorrespondenceEstimation<PointXYZ, PointXYZ>::Ptr ce (new CorrespondenceEstimation<PointXYZ, PointXYZ>); 00161 * ce->setInputSource (source); 00162 * ce->setInputTarget (target); 00163 * icp.setCorrespondenceEstimation (ce); 00164 * // or... 00165 * CorrespondenceEstimationNormalShooting<PointNormal, PointNormal, PointNormal>::Ptr cens (new CorrespondenceEstimationNormalShooting<PointNormal, PointNormal>); 00166 * ce->setInputSource (source); 00167 * ce->setInputTarget (target); 00168 * ce->setSourceNormals (source); 00169 * ce->setTargetNormals (target); 00170 * icp.setCorrespondenceEstimation (cens); 00171 * \endcode 00172 */ 00173 void 00174 setCorrespondenceEstimation (const CorrespondenceEstimationPtr &ce) { correspondence_estimation_ = ce; } 00175 00176 /** \brief Provide a pointer to the input source 00177 * (e.g., the point cloud that we want to align to the target) 00178 * 00179 * \param[in] cloud the input point cloud source 00180 */ 00181 PCL_DEPRECATED (void setInputCloud (const PointCloudSourceConstPtr &cloud), "[pcl::registration::Registration::setInputCloud] setInputCloud is deprecated. Please use setInputSource instead."); 00182 00183 /** \brief Get a pointer to the input point cloud dataset target. */ 00184 PCL_DEPRECATED (PointCloudSourceConstPtr const getInputCloud (), "[pcl::registration::Registration::getInputCloud] getInputCloud is deprecated. Please use getInputSource instead."); 00185 00186 /** \brief Provide a pointer to the input source 00187 * (e.g., the point cloud that we want to align to the target) 00188 * 00189 * \param[in] cloud the input point cloud source 00190 */ 00191 virtual void 00192 setInputSource (const PointCloudSourceConstPtr &cloud) 00193 { 00194 source_cloud_updated_ = true; 00195 PCLBase<PointSource>::setInputCloud (cloud); 00196 } 00197 00198 /** \brief Get a pointer to the input point cloud dataset target. */ 00199 inline PointCloudSourceConstPtr const 00200 getInputSource () { return (input_ ); } 00201 00202 /** \brief Provide a pointer to the input target (e.g., the point cloud that we want to align the input source to) 00203 * \param[in] cloud the input point cloud target 00204 */ 00205 virtual inline void 00206 setInputTarget (const PointCloudTargetConstPtr &cloud); 00207 00208 /** \brief Get a pointer to the input point cloud dataset target. */ 00209 inline PointCloudTargetConstPtr const 00210 getInputTarget () { return (target_ ); } 00211 00212 00213 /** \brief Provide a pointer to the search object used to find correspondences in 00214 * the target cloud. 00215 * \param[in] tree a pointer to the spatial search object. 00216 * \param[in] force_no_recompute If set to true, this tree will NEVER be 00217 * recomputed, regardless of calls to setInputTarget. Only use if you are 00218 * confident that the tree will be set correctly. 00219 */ 00220 inline void 00221 setSearchMethodTarget (const KdTreePtr &tree, 00222 bool force_no_recompute = false) 00223 { 00224 tree_ = tree; 00225 if (force_no_recompute) 00226 { 00227 force_no_recompute_ = true; 00228 } 00229 // Since we just set a new tree, we need to check for updates 00230 target_cloud_updated_ = true; 00231 } 00232 00233 /** \brief Get a pointer to the search method used to find correspondences in the 00234 * target cloud. */ 00235 inline KdTreePtr 00236 getSearchMethodTarget () const 00237 { 00238 return (tree_); 00239 } 00240 00241 /** \brief Provide a pointer to the search object used to find correspondences in 00242 * the source cloud (usually used by reciprocal correspondence finding). 00243 * \param[in] tree a pointer to the spatial search object. 00244 * \param[in] force_no_recompute If set to true, this tree will NEVER be 00245 * recomputed, regardless of calls to setInputSource. Only use if you are 00246 * extremely confident that the tree will be set correctly. 00247 */ 00248 inline void 00249 setSearchMethodSource (const KdTreeReciprocalPtr &tree, 00250 bool force_no_recompute = false) 00251 { 00252 tree_reciprocal_ = tree; 00253 if ( force_no_recompute ) 00254 { 00255 force_no_recompute_reciprocal_ = true; 00256 } 00257 // Since we just set a new tree, we need to check for updates 00258 source_cloud_updated_ = true; 00259 } 00260 00261 /** \brief Get a pointer to the search method used to find correspondences in the 00262 * source cloud. */ 00263 inline KdTreeReciprocalPtr 00264 getSearchMethodSource () const 00265 { 00266 return (tree_reciprocal_); 00267 } 00268 00269 /** \brief Get the final transformation matrix estimated by the registration method. */ 00270 inline Matrix4 00271 getFinalTransformation () { return (final_transformation_); } 00272 00273 /** \brief Get the last incremental transformation matrix estimated by the registration method. */ 00274 inline Matrix4 00275 getLastIncrementalTransformation () { return (transformation_); } 00276 00277 /** \brief Set the maximum number of iterations the internal optimization should run for. 00278 * \param[in] nr_iterations the maximum number of iterations the internal optimization should run for 00279 */ 00280 inline void 00281 setMaximumIterations (int nr_iterations) { max_iterations_ = nr_iterations; } 00282 00283 /** \brief Get the maximum number of iterations the internal optimization should run for, as set by the user. */ 00284 inline int 00285 getMaximumIterations () { return (max_iterations_); } 00286 00287 /** \brief Set the number of iterations RANSAC should run for. 00288 * \param[in] ransac_iterations is the number of iterations RANSAC should run for 00289 */ 00290 inline void 00291 setRANSACIterations (int ransac_iterations) { ransac_iterations_ = ransac_iterations; } 00292 00293 /** \brief Get the number of iterations RANSAC should run for, as set by the user. */ 00294 inline double 00295 getRANSACIterations () { return (ransac_iterations_); } 00296 00297 /** \brief Set the inlier distance threshold for the internal RANSAC outlier rejection loop. 00298 * 00299 * The method considers a point to be an inlier, if the distance between the target data index and the transformed 00300 * source index is smaller than the given inlier distance threshold. 00301 * The value is set by default to 0.05m. 00302 * \param[in] inlier_threshold the inlier distance threshold for the internal RANSAC outlier rejection loop 00303 */ 00304 inline void 00305 setRANSACOutlierRejectionThreshold (double inlier_threshold) { inlier_threshold_ = inlier_threshold; } 00306 00307 /** \brief Get the inlier distance threshold for the internal outlier rejection loop as set by the user. */ 00308 inline double 00309 getRANSACOutlierRejectionThreshold () { return (inlier_threshold_); } 00310 00311 /** \brief Set the maximum distance threshold between two correspondent points in source <-> target. If the 00312 * distance is larger than this threshold, the points will be ignored in the alignment process. 00313 * \param[in] distance_threshold the maximum distance threshold between a point and its nearest neighbor 00314 * correspondent in order to be considered in the alignment process 00315 */ 00316 inline void 00317 setMaxCorrespondenceDistance (double distance_threshold) { corr_dist_threshold_ = distance_threshold; } 00318 00319 /** \brief Get the maximum distance threshold between two correspondent points in source <-> target. If the 00320 * distance is larger than this threshold, the points will be ignored in the alignment process. 00321 */ 00322 inline double 00323 getMaxCorrespondenceDistance () { return (corr_dist_threshold_); } 00324 00325 /** \brief Set the transformation epsilon (maximum allowable difference between two consecutive 00326 * transformations) in order for an optimization to be considered as having converged to the final 00327 * solution. 00328 * \param[in] epsilon the transformation epsilon in order for an optimization to be considered as having 00329 * converged to the final solution. 00330 */ 00331 inline void 00332 setTransformationEpsilon (double epsilon) { transformation_epsilon_ = epsilon; } 00333 00334 /** \brief Get the transformation epsilon (maximum allowable difference between two consecutive 00335 * transformations) as set by the user. 00336 */ 00337 inline double 00338 getTransformationEpsilon () { return (transformation_epsilon_); } 00339 00340 /** \brief Set the maximum allowed Euclidean error between two consecutive steps in the ICP loop, before 00341 * the algorithm is considered to have converged. 00342 * The error is estimated as the sum of the differences between correspondences in an Euclidean sense, 00343 * divided by the number of correspondences. 00344 * \param[in] epsilon the maximum allowed distance error before the algorithm will be considered to have 00345 * converged 00346 */ 00347 00348 inline void 00349 setEuclideanFitnessEpsilon (double epsilon) { euclidean_fitness_epsilon_ = epsilon; } 00350 00351 /** \brief Get the maximum allowed distance error before the algorithm will be considered to have converged, 00352 * as set by the user. See \ref setEuclideanFitnessEpsilon 00353 */ 00354 inline double 00355 getEuclideanFitnessEpsilon () { return (euclidean_fitness_epsilon_); } 00356 00357 /** \brief Provide a boost shared pointer to the PointRepresentation to be used when comparing points 00358 * \param[in] point_representation the PointRepresentation to be used by the k-D tree 00359 */ 00360 inline void 00361 setPointRepresentation (const PointRepresentationConstPtr &point_representation) 00362 { 00363 point_representation_ = point_representation; 00364 } 00365 00366 /** \brief Register the user callback function which will be called from registration thread 00367 * in order to update point cloud obtained after each iteration 00368 * \param[in] visualizerCallback reference of the user callback function 00369 */ 00370 template<typename FunctionSignature> inline bool 00371 registerVisualizationCallback (boost::function<FunctionSignature> &visualizerCallback) 00372 { 00373 if (visualizerCallback != NULL) 00374 { 00375 update_visualizer_ = visualizerCallback; 00376 return (true); 00377 } 00378 else 00379 return (false); 00380 } 00381 00382 /** \brief Obtain the Euclidean fitness score (e.g., sum of squared distances from the source to the target) 00383 * \param[in] max_range maximum allowable distance between a point and its correspondence in the target 00384 * (default: double::max) 00385 */ 00386 inline double 00387 getFitnessScore (double max_range = std::numeric_limits<double>::max ()); 00388 00389 /** \brief Obtain the Euclidean fitness score (e.g., sum of squared distances from the source to the target) 00390 * from two sets of correspondence distances (distances between source and target points) 00391 * \param[in] distances_a the first set of distances between correspondences 00392 * \param[in] distances_b the second set of distances between correspondences 00393 */ 00394 inline double 00395 getFitnessScore (const std::vector<float> &distances_a, const std::vector<float> &distances_b); 00396 00397 /** \brief Return the state of convergence after the last align run */ 00398 inline bool 00399 hasConverged () { return (converged_); } 00400 00401 /** \brief Call the registration algorithm which estimates the transformation and returns the transformed source 00402 * (input) as \a output. 00403 * \param[out] output the resultant input transfomed point cloud dataset 00404 */ 00405 inline void 00406 align (PointCloudSource &output); 00407 00408 /** \brief Call the registration algorithm which estimates the transformation and returns the transformed source 00409 * (input) as \a output. 00410 * \param[out] output the resultant input transfomed point cloud dataset 00411 * \param[in] guess the initial gross estimation of the transformation 00412 */ 00413 inline void 00414 align (PointCloudSource &output, const Matrix4& guess); 00415 00416 /** \brief Abstract class get name method. */ 00417 inline const std::string& 00418 getClassName () const { return (reg_name_); } 00419 00420 /** \brief Internal computation initalization. */ 00421 bool 00422 initCompute (); 00423 00424 /** \brief Internal computation when reciprocal lookup is needed */ 00425 bool 00426 initComputeReciprocal (); 00427 00428 /** \brief Add a new correspondence rejector to the list 00429 * \param[in] rejector the new correspondence rejector to concatenate 00430 * 00431 * Code example: 00432 * 00433 * \code 00434 * CorrespondenceRejectorDistance rej; 00435 * rej.setInputCloud<PointXYZ> (keypoints_src); 00436 * rej.setInputTarget<PointXYZ> (keypoints_tgt); 00437 * rej.setMaximumDistance (1); 00438 * rej.setInputCorrespondences (all_correspondences); 00439 * 00440 * // or... 00441 * 00442 * \endcode 00443 */ 00444 inline void 00445 addCorrespondenceRejector (const CorrespondenceRejectorPtr &rejector) 00446 { 00447 correspondence_rejectors_.push_back (rejector); 00448 } 00449 00450 /** \brief Get the list of correspondence rejectors. */ 00451 inline std::vector<CorrespondenceRejectorPtr> 00452 getCorrespondenceRejectors () 00453 { 00454 return (correspondence_rejectors_); 00455 } 00456 00457 /** \brief Remove the i-th correspondence rejector in the list 00458 * \param[in] i the position of the correspondence rejector in the list to remove 00459 */ 00460 inline bool 00461 removeCorrespondenceRejector (unsigned int i) 00462 { 00463 if (i >= correspondence_rejectors_.size ()) 00464 return (false); 00465 correspondence_rejectors_.erase (correspondence_rejectors_.begin () + i); 00466 return (true); 00467 } 00468 00469 /** \brief Clear the list of correspondence rejectors. */ 00470 inline void 00471 clearCorrespondenceRejectors () 00472 { 00473 correspondence_rejectors_.clear (); 00474 } 00475 00476 protected: 00477 /** \brief The registration method name. */ 00478 std::string reg_name_; 00479 00480 /** \brief A pointer to the spatial search object. */ 00481 KdTreePtr tree_; 00482 00483 /** \brief A pointer to the spatial search object of the source. */ 00484 KdTreeReciprocalPtr tree_reciprocal_; 00485 00486 /** \brief The number of iterations the internal optimization ran for (used internally). */ 00487 int nr_iterations_; 00488 00489 /** \brief The maximum number of iterations the internal optimization should run for. 00490 * The default value is 10. 00491 */ 00492 int max_iterations_; 00493 00494 /** \brief The number of iterations RANSAC should run for. */ 00495 int ransac_iterations_; 00496 00497 /** \brief The input point cloud dataset target. */ 00498 PointCloudTargetConstPtr target_; 00499 00500 /** \brief The final transformation matrix estimated by the registration method after N iterations. */ 00501 Matrix4 final_transformation_; 00502 00503 /** \brief The transformation matrix estimated by the registration method. */ 00504 Matrix4 transformation_; 00505 00506 /** \brief The previous transformation matrix estimated by the registration method (used internally). */ 00507 Matrix4 previous_transformation_; 00508 00509 /** \brief The maximum difference between two consecutive transformations in order to consider convergence 00510 * (user defined). 00511 */ 00512 double transformation_epsilon_; 00513 00514 /** \brief The maximum allowed Euclidean error between two consecutive steps in the ICP loop, before the 00515 * algorithm is considered to have converged. The error is estimated as the sum of the differences between 00516 * correspondences in an Euclidean sense, divided by the number of correspondences. 00517 */ 00518 double euclidean_fitness_epsilon_; 00519 00520 /** \brief The maximum distance threshold between two correspondent points in source <-> target. If the 00521 * distance is larger than this threshold, the points will be ignored in the alignement process. 00522 */ 00523 double corr_dist_threshold_; 00524 00525 /** \brief The inlier distance threshold for the internal RANSAC outlier rejection loop. 00526 * The method considers a point to be an inlier, if the distance between the target data index and the transformed 00527 * source index is smaller than the given inlier distance threshold. The default value is 0.05. 00528 */ 00529 double inlier_threshold_; 00530 00531 /** \brief Holds internal convergence state, given user parameters. */ 00532 bool converged_; 00533 00534 /** \brief The minimum number of correspondences that the algorithm needs before attempting to estimate the 00535 * transformation. The default value is 3. 00536 */ 00537 int min_number_correspondences_; 00538 00539 /** \brief The set of correspondences determined at this ICP step. */ 00540 CorrespondencesPtr correspondences_; 00541 00542 /** \brief A TransformationEstimation object, used to calculate the 4x4 rigid transformation. */ 00543 TransformationEstimationPtr transformation_estimation_; 00544 00545 /** \brief A CorrespondenceEstimation object, used to estimate correspondences between the source and the target cloud. */ 00546 CorrespondenceEstimationPtr correspondence_estimation_; 00547 00548 /** \brief The list of correspondence rejectors to use. */ 00549 std::vector<CorrespondenceRejectorPtr> correspondence_rejectors_; 00550 00551 /** \brief Variable that stores whether we have a new target cloud, meaning we need to pre-process it again. 00552 * This way, we avoid rebuilding the kd-tree for the target cloud every time the determineCorrespondences () method 00553 * is called. */ 00554 bool target_cloud_updated_; 00555 /** \brief Variable that stores whether we have a new source cloud, meaning we need to pre-process it again. 00556 * This way, we avoid rebuilding the reciprocal kd-tree for the source cloud every time the determineCorrespondences () method 00557 * is called. */ 00558 bool source_cloud_updated_; 00559 /** \brief A flag which, if set, means the tree operating on the target cloud 00560 * will never be recomputed*/ 00561 bool force_no_recompute_; 00562 00563 /** \brief A flag which, if set, means the tree operating on the source cloud 00564 * will never be recomputed*/ 00565 bool force_no_recompute_reciprocal_; 00566 00567 /** \brief Callback function to update intermediate source point cloud position during it's registration 00568 * to the target point cloud. 00569 */ 00570 boost::function<void(const pcl::PointCloud<PointSource> &cloud_src, 00571 const std::vector<int> &indices_src, 00572 const pcl::PointCloud<PointTarget> &cloud_tgt, 00573 const std::vector<int> &indices_tgt)> update_visualizer_; 00574 00575 /** \brief Search for the closest nearest neighbor of a given point. 00576 * \param cloud the point cloud dataset to use for nearest neighbor search 00577 * \param index the index of the query point 00578 * \param indices the resultant vector of indices representing the k-nearest neighbors 00579 * \param distances the resultant distances from the query point to the k-nearest neighbors 00580 */ 00581 inline bool 00582 searchForNeighbors (const PointCloudSource &cloud, int index, 00583 std::vector<int> &indices, std::vector<float> &distances) 00584 { 00585 int k = tree_->nearestKSearch (cloud, index, 1, indices, distances); 00586 if (k == 0) 00587 return (false); 00588 return (true); 00589 } 00590 00591 /** \brief Abstract transformation computation method with initial guess */ 00592 virtual void 00593 computeTransformation (PointCloudSource &output, const Matrix4& guess) = 0; 00594 00595 private: 00596 /** \brief The point representation used (internal). */ 00597 PointRepresentationConstPtr point_representation_; 00598 public: 00599 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00600 }; 00601 } 00602 00603 #include <pcl/registration/impl/registration.hpp> 00604 00605 #endif //#ifndef PCL_REGISTRATION_H_