Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sac_model_registration.h
Go to the documentation of this file.
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  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id: sac_model_registration.h 6144 2012-07-04 22:06:28Z rusu $
37  *
38  */
39 
40 #ifndef PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_
41 #define PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_
42 
43 #include <boost/unordered_map.hpp>
44 #include <Eigen/Core>
47 #include <pcl/common/eigen.h>
48 #include <pcl/common/centroid.h>
49 
50 namespace pcl
51 {
56  template <typename PointT>
58  {
61 
62  public:
66 
67  typedef boost::shared_ptr<SampleConsensusModelRegistration> Ptr;
68 
74  target_ (),
75  indices_tgt_ (),
76  correspondences_ (),
77  sample_dist_thresh_ (0)
78  {
79  // Call our own setInputCloud
80  setInputCloud (cloud);
81  }
82 
88  const std::vector<int> &indices) :
89  SampleConsensusModel<PointT> (cloud, indices),
90  target_ (),
91  indices_tgt_ (),
92  correspondences_ (),
93  sample_dist_thresh_ (0)
94  {
95  computeOriginalIndexMapping ();
96  computeSampleDistanceThreshold (cloud, indices);
97  }
98 
102  inline virtual void
104  {
106  computeOriginalIndexMapping ();
107  computeSampleDistanceThreshold (cloud);
108  }
109 
113  inline void
115  {
116  target_ = target;
117  indices_tgt_.reset (new std::vector<int>);
118  // Cache the size and fill the target indices
119  int target_size = static_cast<int> (target->size ());
120  indices_tgt_->resize (target_size);
121 
122  for (int i = 0; i < target_size; ++i)
123  (*indices_tgt_)[i] = i;
124  computeOriginalIndexMapping ();
125  }
126 
131  inline void
132  setInputTarget (const PointCloudConstPtr &target, const std::vector<int> &indices_tgt)
133  {
134  target_ = target;
135  indices_tgt_.reset (new std::vector<int> (indices_tgt));
136  computeOriginalIndexMapping ();
137  }
138 
143  bool
144  computeModelCoefficients (const std::vector<int> &samples,
145  Eigen::VectorXf &model_coefficients);
146 
151  void
152  getDistancesToModel (const Eigen::VectorXf &model_coefficients,
153  std::vector<double> &distances);
154 
160  void
161  selectWithinDistance (const Eigen::VectorXf &model_coefficients,
162  const double threshold,
163  std::vector<int> &inliers);
164 
171  virtual int
172  countWithinDistance (const Eigen::VectorXf &model_coefficients,
173  const double threshold);
174 
180  void
181  optimizeModelCoefficients (const std::vector<int> &inliers,
182  const Eigen::VectorXf &model_coefficients,
183  Eigen::VectorXf &optimized_coefficients);
184 
185  void
186  projectPoints (const std::vector<int> &,
187  const Eigen::VectorXf &,
188  PointCloud &, bool = true)
189  {
190  };
191 
192  bool
193  doSamplesVerifyModel (const std::set<int> &,
194  const Eigen::VectorXf &,
195  const double)
196  {
197  return (false);
198  }
199 
201  inline pcl::SacModel
202  getModelType () const { return (SACMODEL_REGISTRATION); }
203 
204  protected:
208  inline bool
209  isModelValid (const Eigen::VectorXf &model_coefficients)
210  {
211  // Needs a valid model coefficients
212  if (model_coefficients.size () != 16)
213  return (false);
214 
215  return (true);
216  }
217 
222  bool
223  isSampleGood (const std::vector<int> &samples) const;
224 
229  inline void
230  computeSampleDistanceThreshold (const PointCloudConstPtr &cloud)
231  {
232  // Compute the principal directions via PCA
233  Eigen::Vector4f xyz_centroid;
234  Eigen::Matrix3f covariance_matrix = Eigen::Matrix3f::Zero ();
235 
236  computeMeanAndCovarianceMatrix (*cloud, covariance_matrix, xyz_centroid);
237 
238  // Check if the covariance matrix is finite or not.
239  for (int i = 0; i < 3; ++i)
240  for (int j = 0; j < 3; ++j)
241  if (!pcl_isfinite (covariance_matrix.coeffRef (i, j)))
242  PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] Covariance matrix has NaN values! Is the input cloud finite?\n");
243 
244  Eigen::Vector3f eigen_values;
245  pcl::eigen33 (covariance_matrix, eigen_values);
246 
247  // Compute the distance threshold for sample selection
248  sample_dist_thresh_ = eigen_values.array ().sqrt ().sum () / 3.0;
249  sample_dist_thresh_ *= sample_dist_thresh_;
250  PCL_DEBUG ("[pcl::SampleConsensusModelRegistration::setInputCloud] Estimated a sample selection distance threshold of: %f\n", sample_dist_thresh_);
251  }
252 
257  inline void
258  computeSampleDistanceThreshold (const PointCloudConstPtr &cloud,
259  const std::vector<int> &indices)
260  {
261  // Compute the principal directions via PCA
262  Eigen::Vector4f xyz_centroid;
263  Eigen::Matrix3f covariance_matrix;
264  computeMeanAndCovarianceMatrix (*cloud, indices, covariance_matrix, xyz_centroid);
265 
266  // Check if the covariance matrix is finite or not.
267  for (int i = 0; i < 3; ++i)
268  for (int j = 0; j < 3; ++j)
269  if (!pcl_isfinite (covariance_matrix.coeffRef (i, j)))
270  PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] Covariance matrix has NaN values! Is the input cloud finite?\n");
271 
272  Eigen::Vector3f eigen_values;
273  pcl::eigen33 (covariance_matrix, eigen_values);
274 
275  // Compute the distance threshold for sample selection
276  sample_dist_thresh_ = eigen_values.array ().sqrt ().sum () / 3.0;
277  sample_dist_thresh_ *= sample_dist_thresh_;
278  PCL_DEBUG ("[pcl::SampleConsensusModelRegistration::setInputCloud] Estimated a sample selection distance threshold of: %f\n", sample_dist_thresh_);
279  }
280 
281  private:
282 
294  void
295  estimateRigidTransformationSVD (const pcl::PointCloud<PointT> &cloud_src,
296  const std::vector<int> &indices_src,
297  const pcl::PointCloud<PointT> &cloud_tgt,
298  const std::vector<int> &indices_tgt,
299  Eigen::VectorXf &transform);
300 
302  void
303  computeOriginalIndexMapping ()
304  {
305  if (!indices_tgt_ || !indices_ || indices_->empty () || indices_->size () != indices_tgt_->size ())
306  return;
307  for (size_t i = 0; i < indices_->size (); ++i)
308  correspondences_[(*indices_)[i]] = (*indices_tgt_)[i];
309  }
310 
312  PointCloudConstPtr target_;
313 
315  boost::shared_ptr <std::vector<int> > indices_tgt_;
316 
318  boost::unordered_map<int, int> correspondences_;
319 
321  double sample_dist_thresh_;
322  public:
323  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
324  };
325 }
326 
328 
329 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_