00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_
00042 #define PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_
00043
00044 #include <pcl/sample_consensus/eigen.h>
00045 #include <pcl/sample_consensus/sac_model.h>
00046 #include <pcl/sample_consensus/model_types.h>
00047 #include <pcl/common/eigen.h>
00048 #include <pcl/common/centroid.h>
00049 #include <map>
00050
00051 namespace pcl
00052 {
00057 template <typename PointT>
00058 class SampleConsensusModelRegistration : public SampleConsensusModel<PointT>
00059 {
00060 public:
00061 using SampleConsensusModel<PointT>::input_;
00062 using SampleConsensusModel<PointT>::indices_;
00063 using SampleConsensusModel<PointT>::error_sqr_dists_;
00064
00065 typedef typename SampleConsensusModel<PointT>::PointCloud PointCloud;
00066 typedef typename SampleConsensusModel<PointT>::PointCloudPtr PointCloudPtr;
00067 typedef typename SampleConsensusModel<PointT>::PointCloudConstPtr PointCloudConstPtr;
00068
00069 typedef boost::shared_ptr<SampleConsensusModelRegistration> Ptr;
00070
00075 SampleConsensusModelRegistration (const PointCloudConstPtr &cloud,
00076 bool random = false)
00077 : SampleConsensusModel<PointT> (cloud, random)
00078 , target_ ()
00079 , indices_tgt_ ()
00080 , correspondences_ ()
00081 , sample_dist_thresh_ (0)
00082 {
00083
00084 setInputCloud (cloud);
00085 }
00086
00092 SampleConsensusModelRegistration (const PointCloudConstPtr &cloud,
00093 const std::vector<int> &indices,
00094 bool random = false)
00095 : SampleConsensusModel<PointT> (cloud, indices, random)
00096 , target_ ()
00097 , indices_tgt_ ()
00098 , correspondences_ ()
00099 , sample_dist_thresh_ (0)
00100 {
00101 computeOriginalIndexMapping ();
00102 computeSampleDistanceThreshold (cloud, indices);
00103 }
00104
00106 virtual ~SampleConsensusModelRegistration () {}
00107
00111 inline virtual void
00112 setInputCloud (const PointCloudConstPtr &cloud)
00113 {
00114 SampleConsensusModel<PointT>::setInputCloud (cloud);
00115 computeOriginalIndexMapping ();
00116 computeSampleDistanceThreshold (cloud);
00117 }
00118
00122 inline void
00123 setInputTarget (const PointCloudConstPtr &target)
00124 {
00125 target_ = target;
00126 indices_tgt_.reset (new std::vector<int>);
00127
00128 int target_size = static_cast<int> (target->size ());
00129 indices_tgt_->resize (target_size);
00130
00131 for (int i = 0; i < target_size; ++i)
00132 (*indices_tgt_)[i] = i;
00133 computeOriginalIndexMapping ();
00134 }
00135
00140 inline void
00141 setInputTarget (const PointCloudConstPtr &target, const std::vector<int> &indices_tgt)
00142 {
00143 target_ = target;
00144 indices_tgt_.reset (new std::vector<int> (indices_tgt));
00145 computeOriginalIndexMapping ();
00146 }
00147
00152 bool
00153 computeModelCoefficients (const std::vector<int> &samples,
00154 Eigen::VectorXf &model_coefficients);
00155
00160 void
00161 getDistancesToModel (const Eigen::VectorXf &model_coefficients,
00162 std::vector<double> &distances);
00163
00169 void
00170 selectWithinDistance (const Eigen::VectorXf &model_coefficients,
00171 const double threshold,
00172 std::vector<int> &inliers);
00173
00180 virtual int
00181 countWithinDistance (const Eigen::VectorXf &model_coefficients,
00182 const double threshold);
00183
00189 void
00190 optimizeModelCoefficients (const std::vector<int> &inliers,
00191 const Eigen::VectorXf &model_coefficients,
00192 Eigen::VectorXf &optimized_coefficients);
00193
00194 void
00195 projectPoints (const std::vector<int> &,
00196 const Eigen::VectorXf &,
00197 PointCloud &, bool = true)
00198 {
00199 };
00200
00201 bool
00202 doSamplesVerifyModel (const std::set<int> &,
00203 const Eigen::VectorXf &,
00204 const double)
00205 {
00206 return (false);
00207 }
00208
00210 inline pcl::SacModel
00211 getModelType () const { return (SACMODEL_REGISTRATION); }
00212
00213 protected:
00217 inline bool
00218 isModelValid (const Eigen::VectorXf &model_coefficients)
00219 {
00220
00221 if (model_coefficients.size () != 16)
00222 return (false);
00223
00224 return (true);
00225 }
00226
00231 virtual bool
00232 isSampleGood (const std::vector<int> &samples) const;
00233
00238 inline void
00239 computeSampleDistanceThreshold (const PointCloudConstPtr &cloud)
00240 {
00241
00242 Eigen::Vector4f xyz_centroid;
00243 Eigen::Matrix3f covariance_matrix = Eigen::Matrix3f::Zero ();
00244
00245 computeMeanAndCovarianceMatrix (*cloud, covariance_matrix, xyz_centroid);
00246
00247
00248 for (int i = 0; i < 3; ++i)
00249 for (int j = 0; j < 3; ++j)
00250 if (!pcl_isfinite (covariance_matrix.coeffRef (i, j)))
00251 PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] Covariance matrix has NaN values! Is the input cloud finite?\n");
00252
00253 Eigen::Vector3f eigen_values;
00254 pcl::eigen33 (covariance_matrix, eigen_values);
00255
00256
00257 sample_dist_thresh_ = eigen_values.array ().sqrt ().sum () / 3.0;
00258 sample_dist_thresh_ *= sample_dist_thresh_;
00259 PCL_DEBUG ("[pcl::SampleConsensusModelRegistration::setInputCloud] Estimated a sample selection distance threshold of: %f\n", sample_dist_thresh_);
00260 }
00261
00266 inline void
00267 computeSampleDistanceThreshold (const PointCloudConstPtr &cloud,
00268 const std::vector<int> &indices)
00269 {
00270
00271 Eigen::Vector4f xyz_centroid;
00272 Eigen::Matrix3f covariance_matrix;
00273 computeMeanAndCovarianceMatrix (*cloud, indices, covariance_matrix, xyz_centroid);
00274
00275
00276 for (int i = 0; i < 3; ++i)
00277 for (int j = 0; j < 3; ++j)
00278 if (!pcl_isfinite (covariance_matrix.coeffRef (i, j)))
00279 PCL_ERROR ("[pcl::SampleConsensusModelRegistration::computeSampleDistanceThreshold] Covariance matrix has NaN values! Is the input cloud finite?\n");
00280
00281 Eigen::Vector3f eigen_values;
00282 pcl::eigen33 (covariance_matrix, eigen_values);
00283
00284
00285 sample_dist_thresh_ = eigen_values.array ().sqrt ().sum () / 3.0;
00286 sample_dist_thresh_ *= sample_dist_thresh_;
00287 PCL_DEBUG ("[pcl::SampleConsensusModelRegistration::setInputCloud] Estimated a sample selection distance threshold of: %f\n", sample_dist_thresh_);
00288 }
00289
00301 void
00302 estimateRigidTransformationSVD (const pcl::PointCloud<PointT> &cloud_src,
00303 const std::vector<int> &indices_src,
00304 const pcl::PointCloud<PointT> &cloud_tgt,
00305 const std::vector<int> &indices_tgt,
00306 Eigen::VectorXf &transform);
00307
00309 void
00310 computeOriginalIndexMapping ()
00311 {
00312 if (!indices_tgt_ || !indices_ || indices_->empty () || indices_->size () != indices_tgt_->size ())
00313 return;
00314 for (size_t i = 0; i < indices_->size (); ++i)
00315 correspondences_[(*indices_)[i]] = (*indices_tgt_)[i];
00316 }
00317
00319 PointCloudConstPtr target_;
00320
00322 boost::shared_ptr <std::vector<int> > indices_tgt_;
00323
00325 std::map<int, int> correspondences_;
00326
00328 double sample_dist_thresh_;
00329 public:
00330 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00331 };
00332 }
00333
00334 #include <pcl/sample_consensus/impl/sac_model_registration.hpp>
00335
00336 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_REGISTRATION_H_