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 #ifndef PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_
00039 #define PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_
00040
00041 #include <pcl/sample_consensus/sac_model.h>
00042 #include <pcl/sample_consensus/model_types.h>
00043 #include <boost/thread/mutex.hpp>
00044 #include <cminpack.h>
00045 #include <pcl/common/common.h>
00046
00047 namespace pcl
00048 {
00050
00053 template <typename PointT, typename PointNT>
00054 class SampleConsensusModelCylinder : public SampleConsensusModel<PointT>, public SampleConsensusModelFromNormals<PointT, PointNT>
00055 {
00056 using SampleConsensusModel<PointT>::input_;
00057 using SampleConsensusModel<PointT>::indices_;
00058 using SampleConsensusModel<PointT>::radius_min_;
00059 using SampleConsensusModel<PointT>::radius_max_;
00060 using SampleConsensusModelFromNormals<PointT, PointNT>::normals_;
00061 using SampleConsensusModelFromNormals<PointT, PointNT>::normal_distance_weight_;
00062
00063 public:
00064 typedef typename SampleConsensusModel<PointT>::PointCloud PointCloud;
00065 typedef typename SampleConsensusModel<PointT>::PointCloudPtr PointCloudPtr;
00066 typedef typename SampleConsensusModel<PointT>::PointCloudConstPtr PointCloudConstPtr;
00067
00068 typedef boost::shared_ptr<SampleConsensusModelCylinder> Ptr;
00069
00073 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud) : SampleConsensusModel<PointT> (cloud), eps_angle_ (0)
00074 {
00075 axis_.setZero ();
00076 }
00077
00082 SampleConsensusModelCylinder (const PointCloudConstPtr &cloud, const std::vector<int> &indices) : SampleConsensusModel<PointT> (cloud, indices), eps_angle_ (0)
00083 {
00084 axis_.setZero ();
00085 }
00086
00090 inline void setEpsAngle (double ea) { eps_angle_ = ea; }
00091
00093 inline double getEpsAngle () { return (eps_angle_); }
00094
00098 inline void setAxis (const Eigen::Vector3f &ax) { axis_ = ax; }
00099
00101 inline Eigen::Vector3f getAxis () { return (axis_); }
00102
00108 void getSamples (int &iterations, std::vector<int> &samples);
00109
00116 bool computeModelCoefficients (const std::vector<int> &samples, Eigen::VectorXf &model_coefficients);
00117
00122 void getDistancesToModel (const Eigen::VectorXf &model_coefficients, std::vector<double> &distances);
00123
00129 void selectWithinDistance (const Eigen::VectorXf &model_coefficients, double threshold, std::vector<int> &inliers);
00130
00137 void optimizeModelCoefficients (const std::vector<int> &inliers, const Eigen::VectorXf &model_coefficients, Eigen::VectorXf &optimized_coefficients);
00138
00139
00147 void projectPoints (const std::vector<int> &inliers, const Eigen::VectorXf &model_coefficients, PointCloud &projected_points, bool copy_data_fields = true);
00148
00154 bool doSamplesVerifyModel (const std::set<int> &indices, const Eigen::VectorXf &model_coefficients, double threshold);
00155
00157 inline pcl::SacModel getModelType () const { return (SACMODEL_CYLINDER); }
00158
00159 protected:
00164 double pointToLineDistance (const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients);
00165
00172 inline void
00173 projectPointToLine (const Eigen::Vector4f &pt, const Eigen::Vector4f &line_pt, const Eigen::Vector4f &line_dir,
00174 Eigen::Vector4f &pt_proj)
00175 {
00176 double k = (pt.dot (line_dir) - line_pt.dot (line_dir)) / line_dir.dot (line_dir);
00177
00178 pt_proj = line_pt + k * line_dir;
00179 }
00180
00187 void projectPointToCylinder(const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients, Eigen::Vector4f &pt_proj);
00188
00190 std::string getName () const { return ("SampleConsensusModelCylinder"); }
00191
00192 protected:
00196 bool isModelValid (const Eigen::VectorXf &model_coefficients);
00197
00198 private:
00200 Eigen::Vector3f axis_;
00201
00203 double eps_angle_;
00204
00206 boost::mutex tmp_mutex_;
00207
00209 const std::vector<int> *tmp_inliers_;
00210
00212 const static int MAX_ITERATIONS_COLLINEAR = 1000;
00213
00222 static int functionToOptimize (void *p, int m, int n, const double *x, double *fvec, int iflag);
00223 };
00224 }
00225
00226 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_CYLINDER_H_