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_CONE_H_
00039 #define PCL_SAMPLE_CONSENSUS_MODEL_CONE_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 <pcl/common/common.h>
00045 #include <pcl/common/distances.h>
00046 #include <limits.h>
00047
00048 namespace pcl
00049 {
00051
00065 template <typename PointT, typename PointNT>
00066 class SampleConsensusModelCone : public SampleConsensusModel<PointT>, public SampleConsensusModelFromNormals<PointT, PointNT>
00067 {
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
00075 public:
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<SampleConsensusModelCone> Ptr;
00081
00085 SampleConsensusModelCone (const PointCloudConstPtr &cloud) :
00086 SampleConsensusModel<PointT> (cloud), axis_ (Eigen::Vector3f::Zero ()), eps_angle_ (0), min_angle_ (-std::numeric_limits<double>::max()), max_angle_ (std::numeric_limits<double>::max()),
00087 tmp_inliers_ ()
00088 {
00089 }
00090
00095 SampleConsensusModelCone (const PointCloudConstPtr &cloud, const std::vector<int> &indices) :
00096 SampleConsensusModel<PointT> (cloud, indices),
00097 axis_ (Eigen::Vector3f::Zero ()), eps_angle_ (0), min_angle_ (-std::numeric_limits<double>::max()), max_angle_ (std::numeric_limits<double>::max()),
00098 tmp_inliers_ ()
00099 {
00100 }
00101
00105 SampleConsensusModelCone (const SampleConsensusModelCone &source) :
00106 SampleConsensusModel<PointT> (), axis_ (), eps_angle_ (), min_angle_ (), max_angle_ (), tmp_inliers_ ()
00107 {
00108 *this = source;
00109 }
00110
00114 inline SampleConsensusModelCone&
00115 operator = (const SampleConsensusModelCone &source)
00116 {
00117 SampleConsensusModel<PointT>::operator=(source);
00118 axis_ = source.axis_;
00119 eps_angle_ = source.eps_angle_;
00120 min_angle_ = source.min_angle_;
00121 max_angle_ = source.max_angle_;
00122 tmp_inliers_ = source.tmp_inliers_;
00123 return (*this);
00124 }
00125
00129 inline void
00130 setEpsAngle (double ea) { eps_angle_ = ea; }
00131
00133 inline double
00134 getEpsAngle () const { return (eps_angle_); }
00135
00139 inline void
00140 setAxis (const Eigen::Vector3f &ax) { axis_ = ax; }
00141
00143 inline Eigen::Vector3f
00144 getAxis () const { return (axis_); }
00145
00151 inline void
00152 setMinMaxOpeningAngle (const double &min_angle, const double &max_angle)
00153 {
00154 min_angle_ = min_angle;
00155 max_angle_ = max_angle;
00156 }
00157
00162 inline void
00163 getMinMaxOpeningAngle (double &min_angle, double &max_angle) const
00164 {
00165 min_angle = min_angle_;
00166 max_angle = max_angle_;
00167 }
00168
00175 bool
00176 computeModelCoefficients (const std::vector<int> &samples,
00177 Eigen::VectorXf &model_coefficients);
00178
00183 void
00184 getDistancesToModel (const Eigen::VectorXf &model_coefficients,
00185 std::vector<double> &distances);
00186
00192 void
00193 selectWithinDistance (const Eigen::VectorXf &model_coefficients,
00194 const double threshold,
00195 std::vector<int> &inliers);
00196
00203 virtual int
00204 countWithinDistance (const Eigen::VectorXf &model_coefficients,
00205 const double threshold);
00206
00207
00214 void
00215 optimizeModelCoefficients (const std::vector<int> &inliers,
00216 const Eigen::VectorXf &model_coefficients,
00217 Eigen::VectorXf &optimized_coefficients);
00218
00219
00226 void
00227 projectPoints (const std::vector<int> &inliers,
00228 const Eigen::VectorXf &model_coefficients,
00229 PointCloud &projected_points,
00230 bool copy_data_fields = true);
00231
00237 bool
00238 doSamplesVerifyModel (const std::set<int> &indices,
00239 const Eigen::VectorXf &model_coefficients,
00240 const double threshold);
00241
00243 inline pcl::SacModel
00244 getModelType () const { return (SACMODEL_CONE); }
00245
00246 protected:
00251 double
00252 pointToAxisDistance (const Eigen::Vector4f &pt, const Eigen::VectorXf &model_coefficients);
00253
00255 std::string
00256 getName () const { return ("SampleConsensusModelCone"); }
00257
00258 protected:
00262 bool
00263 isModelValid (const Eigen::VectorXf &model_coefficients);
00264
00269 bool
00270 isSampleGood (const std::vector<int> &samples) const;
00271
00272 private:
00274 Eigen::Vector3f axis_;
00275
00277 double eps_angle_;
00278
00280 double min_angle_;
00281 double max_angle_;
00282
00284 const std::vector<int> *tmp_inliers_;
00285
00286 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00287 #pragma GCC diagnostic ignored "-Weffc++"
00288 #endif
00289
00290 struct OptimizationFunctor : pcl::Functor<float>
00291 {
00297 OptimizationFunctor (int m_data_points, pcl::SampleConsensusModelCone<PointT, PointNT> *model) :
00298 pcl::Functor<float> (m_data_points), model_ (model) {}
00299
00305 int
00306 operator() (const Eigen::VectorXf &x, Eigen::VectorXf &fvec) const
00307 {
00308 Eigen::Vector4f apex (x[0], x[1], x[2], 0);
00309 Eigen::Vector4f axis_dir (x[3], x[4], x[5], 0);
00310 float opening_angle = x[6];
00311
00312 float apexdotdir = apex.dot (axis_dir);
00313 float dirdotdir = 1.0f / axis_dir.dot (axis_dir);
00314
00315 for (int i = 0; i < values (); ++i)
00316 {
00317
00318 Eigen::Vector4f pt (model_->input_->points[(*model_->tmp_inliers_)[i]].x,
00319 model_->input_->points[(*model_->tmp_inliers_)[i]].y,
00320 model_->input_->points[(*model_->tmp_inliers_)[i]].z, 0);
00321
00322
00323 float k = (pt.dot (axis_dir) - apexdotdir) * dirdotdir;
00324 Eigen::Vector4f pt_proj = apex + k * axis_dir;
00325
00326
00327 Eigen::Vector4f height = apex-pt_proj;
00328 float actual_cone_radius = tanf (opening_angle) * height.norm ();
00329
00330 fvec[i] = static_cast<float> (pcl::sqrPointToLineDistance (pt, apex, axis_dir) - actual_cone_radius * actual_cone_radius);
00331 }
00332 return (0);
00333 }
00334
00335 pcl::SampleConsensusModelCone<PointT, PointNT> *model_;
00336 };
00337 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00338 #pragma GCC diagnostic warning "-Weffc++"
00339 #endif
00340 };
00341 }
00342
00343 #endif //#ifndef PCL_SAMPLE_CONSENSUS_MODEL_CONE_H_