Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/registration/include/pcl/registration/registration.h
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_