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 #ifndef PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_
00041 #define PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_
00042
00043 #include <pcl/sample_consensus/sac_model.h>
00044 #include <pcl/sample_consensus/model_types.h>
00045 #include <pcl/common/common.h>
00046 #include <pcl/common/distances.h>
00047
00048 namespace pcl
00049 {
00063 template <typename PointT, typename PointNT>
00064 class SampleConsensusModelCylinder : public SampleConsensusModel<PointT>, public SampleConsensusModelFromNormals<PointT, PointNT>
00065 {
00066 using SampleConsensusModel<PointT>::input_;
00067 using SampleConsensusModel<PointT>::indices_;
00068 using SampleConsensusModel<PointT>::radius_min_;
00069 using SampleConsensusModel<PointT>::radius_max_;
00070 using SampleConsensusModelFromNormals<PointT, PointNT>::normals_;
00071 using SampleConsensusModelFromNormals<PointT, PointNT>::normal_distance_weight_;
00072
00073 public:
00074 typedef typename SampleConsensusModel<PointT>::PointCloud PointCloud;
00075 typedef typename SampleConsensusModel<PointT>::PointCloudPtr PointCloudPtr;
00076 typedef typename SampleConsensusModel<PointT>::PointCloudConstPtr PointCloudConstPtr;
00077
00078 typedef boost::shared_ptr<SampleConsensusModelCylinder> Ptr;
00079
00083 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud) :
00084 SampleConsensusModel<PointT> (cloud),
00085 axis_ (Eigen::Vector3f::Zero ()),
00086 eps_angle_ (0),
00087 tmp_inliers_ ()
00088 {
00089 }
00090
00095 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud, const std::vector<int> &indices) :
00096 SampleConsensusModel<PointT> (cloud, indices),
00097 axis_ (Eigen::Vector3f::Zero ()),
00098 eps_angle_ (0),
00099 tmp_inliers_ ()
00100 {
00101 }
00102
00106 SampleConsensusModelCylinder (const SampleConsensusModelCylinder &source) :
00107 SampleConsensusModel<PointT> (),
00108 axis_ (Eigen::Vector3f::Zero ()),
00109 eps_angle_ (0),
00110 tmp_inliers_ ()
00111 {
00112 *this = source;
00113 }
00114
00118 inline SampleConsensusModelCylinder&
00119 operator = (const SampleConsensusModelCylinder &source)
00120 {
00121 SampleConsensusModel<PointT>::operator=(source);
00122 axis_ = source.axis_;
00123 eps_angle_ = source.eps_angle_;
00124 tmp_inliers_ = source.tmp_inliers_;
00125 return (*this);
00126 }
00127
00131 inline void
00132 setEpsAngle (const double ea) { eps_angle_ = ea; }
00133
00135 inline double
00136 getEpsAngle () { return (eps_angle_); }
00137
00141 inline void
00142 setAxis (const Eigen::Vector3f &ax) { axis_ = ax; }
00143
00145 inline Eigen::Vector3f
00146 getAxis () { return (axis_); }
00147
00154 bool
00155 computeModelCoefficients (const std::vector<int> &samples,
00156 Eigen::VectorXf &model_coefficients);
00157
00162 void
00163 getDistancesToModel (const Eigen::VectorXf &model_coefficients,
00164 std::vector<double> &distances);
00165
00171 void
00172 selectWithinDistance (const Eigen::VectorXf &model_coefficients,
00173 const double threshold,
00174 std::vector<int> &inliers);
00175
00182 virtual int
00183 countWithinDistance (const Eigen::VectorXf &model_coefficients,
00184 const double threshold);
00185
00192 void
00193 optimizeModelCoefficients (const std::vector<int> &inliers,
00194 const Eigen::VectorXf &model_coefficients,
00195 Eigen::VectorXf &optimized_coefficients);
00196
00197
00204 void
00205 projectPoints (const std::vector<int> &inliers,
00206 const Eigen::VectorXf &model_coefficients,
00207 PointCloud &projected_points,
00208 bool copy_data_fields = true);
00209
00215 bool
00216 doSamplesVerifyModel (const std::set<int> &indices,
00217 const Eigen::VectorXf &model_coefficients,
00218 const double threshold);
00219
00221 inline pcl::SacModel
00222 getModelType () const { return (SACMODEL_CYLINDER); }
00223
00224 protected:
00229 double
00230 pointToLineDistance (const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients);
00231
00238 inline void
00239 projectPointToLine (const Eigen::Vector4f &pt,
00240 const Eigen::Vector4f &line_pt,
00241 const Eigen::Vector4f &line_dir,
00242 Eigen::Vector4f &pt_proj)
00243 {
00244 float k = (pt.dot (line_dir) - line_pt.dot (line_dir)) / line_dir.dot (line_dir);
00245
00246 pt_proj = line_pt + k * line_dir;
00247 }
00248
00255 void
00256 projectPointToCylinder (const Eigen::Vector4f &pt,
00257 const Eigen::VectorXf &model_coefficients,
00258 Eigen::Vector4f &pt_proj);
00259
00261 std::string
00262 getName () const { return ("SampleConsensusModelCylinder"); }
00263
00264 protected:
00268 bool
00269 isModelValid (const Eigen::VectorXf &model_coefficients);
00270
00275 bool
00276 isSampleGood (const std::vector<int> &samples) const;
00277
00278 private:
00280 Eigen::Vector3f axis_;
00281
00283 double eps_angle_;
00284
00286 const std::vector<int> *tmp_inliers_;
00287
00288 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00289 #pragma GCC diagnostic ignored "-Weffc++"
00290 #endif
00291
00292 struct OptimizationFunctor : pcl::Functor<float>
00293 {
00299 OptimizationFunctor (int m_data_points, pcl::SampleConsensusModelCylinder<PointT, PointNT> *model) :
00300 pcl::Functor<float> (m_data_points), model_ (model) {}
00301
00307 int
00308 operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
00309 {
00310 Eigen::Vector4f line_pt (x[0], x[1], x[2], 0);
00311 Eigen::Vector4f line_dir (x[3], x[4], x[5], 0);
00312
00313 for (int i = 0; i < values (); ++i)
00314 {
00315
00316 Eigen::Vector4f pt (model_->input_->points[(*model_->tmp_inliers_)[i]].x,
00317 model_->input_->points[(*model_->tmp_inliers_)[i]].y,
00318 model_->input_->points[(*model_->tmp_inliers_)[i]].z, 0);
00319
00320 fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, line_pt, line_dir) - x[6]*x[6]);
00321 }
00322 return (0);
00323 }
00324
00325 pcl::SampleConsensusModelCylinder<PointT, PointNT> *model_;
00326 };
00327 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00328 #pragma GCC diagnostic warning "-Weffc++"
00329 #endif
00330 };
00331 }
00332
00333 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_