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_CYLINDER_H_
00042 #define PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_
00043
00044 #include <pcl/sample_consensus/sac_model.h>
00045 #include <pcl/sample_consensus/model_types.h>
00046 #include <pcl/common/common.h>
00047 #include <pcl/common/distances.h>
00048
00049 namespace pcl
00050 {
00064 template <typename PointT, typename PointNT>
00065 class SampleConsensusModelCylinder : public SampleConsensusModel<PointT>, public SampleConsensusModelFromNormals<PointT, PointNT>
00066 {
00067 public:
00068 using SampleConsensusModel<PointT>::input_;
00069 using SampleConsensusModel<PointT>::indices_;
00070 using SampleConsensusModel<PointT>::radius_min_;
00071 using SampleConsensusModel<PointT>::radius_max_;
00072 using SampleConsensusModelFromNormals<PointT, PointNT>::normals_;
00073 using SampleConsensusModelFromNormals<PointT, PointNT>::normal_distance_weight_;
00074 using SampleConsensusModel<PointT>::error_sqr_dists_;
00075
00076 typedef typename SampleConsensusModel<PointT>::PointCloud PointCloud;
00077 typedef typename SampleConsensusModel<PointT>::PointCloudPtr PointCloudPtr;
00078 typedef typename SampleConsensusModel<PointT>::PointCloudConstPtr PointCloudConstPtr;
00079
00080 typedef boost::shared_ptr<SampleConsensusModelCylinder> Ptr;
00081
00086 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud, bool random = false)
00087 : SampleConsensusModel<PointT> (cloud, random)
00088 , SampleConsensusModelFromNormals<PointT, PointNT> ()
00089 , axis_ (Eigen::Vector3f::Zero ())
00090 , eps_angle_ (0)
00091 , tmp_inliers_ ()
00092 {
00093 }
00094
00100 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud,
00101 const std::vector<int> &indices,
00102 bool random = false)
00103 : SampleConsensusModel<PointT> (cloud, indices, random)
00104 , SampleConsensusModelFromNormals<PointT, PointNT> ()
00105 , axis_ (Eigen::Vector3f::Zero ())
00106 , eps_angle_ (0)
00107 , tmp_inliers_ ()
00108 {
00109 }
00110
00114 SampleConsensusModelCylinder (const SampleConsensusModelCylinder &source) :
00115 SampleConsensusModel<PointT> (),
00116 SampleConsensusModelFromNormals<PointT, PointNT> (),
00117 axis_ (Eigen::Vector3f::Zero ()),
00118 eps_angle_ (0),
00119 tmp_inliers_ ()
00120 {
00121 *this = source;
00122 }
00123
00125 virtual ~SampleConsensusModelCylinder () {}
00126
00130 inline SampleConsensusModelCylinder&
00131 operator = (const SampleConsensusModelCylinder &source)
00132 {
00133 SampleConsensusModel<PointT>::operator=(source);
00134 axis_ = source.axis_;
00135 eps_angle_ = source.eps_angle_;
00136 tmp_inliers_ = source.tmp_inliers_;
00137 return (*this);
00138 }
00139
00143 inline void
00144 setEpsAngle (const double ea) { eps_angle_ = ea; }
00145
00147 inline double
00148 getEpsAngle () { return (eps_angle_); }
00149
00153 inline void
00154 setAxis (const Eigen::Vector3f &ax) { axis_ = ax; }
00155
00157 inline Eigen::Vector3f
00158 getAxis () { return (axis_); }
00159
00166 bool
00167 computeModelCoefficients (const std::vector<int> &samples,
00168 Eigen::VectorXf &model_coefficients);
00169
00174 void
00175 getDistancesToModel (const Eigen::VectorXf &model_coefficients,
00176 std::vector<double> &distances);
00177
00183 void
00184 selectWithinDistance (const Eigen::VectorXf &model_coefficients,
00185 const double threshold,
00186 std::vector<int> &inliers);
00187
00194 virtual int
00195 countWithinDistance (const Eigen::VectorXf &model_coefficients,
00196 const double threshold);
00197
00204 void
00205 optimizeModelCoefficients (const std::vector<int> &inliers,
00206 const Eigen::VectorXf &model_coefficients,
00207 Eigen::VectorXf &optimized_coefficients);
00208
00209
00216 void
00217 projectPoints (const std::vector<int> &inliers,
00218 const Eigen::VectorXf &model_coefficients,
00219 PointCloud &projected_points,
00220 bool copy_data_fields = true);
00221
00227 bool
00228 doSamplesVerifyModel (const std::set<int> &indices,
00229 const Eigen::VectorXf &model_coefficients,
00230 const double threshold);
00231
00233 inline pcl::SacModel
00234 getModelType () const { return (SACMODEL_CYLINDER); }
00235
00236 protected:
00241 double
00242 pointToLineDistance (const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients);
00243
00250 inline void
00251 projectPointToLine (const Eigen::Vector4f &pt,
00252 const Eigen::Vector4f &line_pt,
00253 const Eigen::Vector4f &line_dir,
00254 Eigen::Vector4f &pt_proj)
00255 {
00256 float k = (pt.dot (line_dir) - line_pt.dot (line_dir)) / line_dir.dot (line_dir);
00257
00258 pt_proj = line_pt + k * line_dir;
00259 }
00260
00267 void
00268 projectPointToCylinder (const Eigen::Vector4f &pt,
00269 const Eigen::VectorXf &model_coefficients,
00270 Eigen::Vector4f &pt_proj);
00271
00273 std::string
00274 getName () const { return ("SampleConsensusModelCylinder"); }
00275
00276 protected:
00280 bool
00281 isModelValid (const Eigen::VectorXf &model_coefficients);
00282
00287 bool
00288 isSampleGood (const std::vector<int> &samples) const;
00289
00290 private:
00292 Eigen::Vector3f axis_;
00293
00295 double eps_angle_;
00296
00298 const std::vector<int> *tmp_inliers_;
00299
00300 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00301 #pragma GCC diagnostic ignored "-Weffc++"
00302 #endif
00303
00304 struct OptimizationFunctor : pcl::Functor<float>
00305 {
00311 OptimizationFunctor (int m_data_points, pcl::SampleConsensusModelCylinder<PointT, PointNT> *model) :
00312 pcl::Functor<float> (m_data_points), model_ (model) {}
00313
00319 int
00320 operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
00321 {
00322 Eigen::Vector4f line_pt (x[0], x[1], x[2], 0);
00323 Eigen::Vector4f line_dir (x[3], x[4], x[5], 0);
00324
00325 for (int i = 0; i < values (); ++i)
00326 {
00327
00328 Eigen::Vector4f pt (model_->input_->points[(*model_->tmp_inliers_)[i]].x,
00329 model_->input_->points[(*model_->tmp_inliers_)[i]].y,
00330 model_->input_->points[(*model_->tmp_inliers_)[i]].z, 0);
00331
00332 fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, line_pt, line_dir) - x[6]*x[6]);
00333 }
00334 return (0);
00335 }
00336
00337 pcl::SampleConsensusModelCylinder<PointT, PointNT> *model_;
00338 };
00339 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00340 #pragma GCC diagnostic warning "-Weffc++"
00341 #endif
00342 };
00343 }
00344
00345 #ifdef PCL_NO_PRECOMPILE
00346 #include <pcl/sample_consensus/impl/sac_model_cylinder.hpp>
00347 #endif
00348
00349 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_