00001
00002
00003
00004
00005
00006
00007
00008 #ifndef SPHERESEGMENTATION_H_
00009 #define SPHERESEGMENTATION_H_
00010
00011 #include <pcl/point_cloud.h>
00012 #include <pcl/point_types.h>
00013 #include <pcl/ModelCoefficients.h>
00014 #include <pcl/io/pcd_io.h>
00015 #include <pcl/point_types.h>
00016 #include <pcl/filters/extract_indices.h>
00017 #include <pcl/filters/passthrough.h>
00018 #include <pcl/features/normal_3d.h>
00019 #include <pcl/sample_consensus/method_types.h>
00020 #include <pcl/sample_consensus/model_types.h>
00021 #include <pcl/segmentation/sac_segmentation.h>
00022 #include <sensor_msgs/PointCloud.h>
00023 #include <ros/ros.h>
00024 #include <tf/transform_listener.h>
00025 #include <arm_navigation_msgs/CollisionObject.h>
00026 #include <tabletop_object_detector/TabletopSegmentation.h>
00027
00028 using namespace tabletop_object_detector;
00029 typedef pcl::PointCloud<pcl::PointXYZ> Cloud3D;
00030
00031 class SphereSegmentation
00032 {
00033 public:
00034 struct Parameters
00035 {
00036 public:
00037 Parameters()
00038 :WorldFrameId("base_link"),
00039 KNearestNeighbors(50),
00040 MaxIterations(100),
00041 SacMethod(pcl::SAC_RANSAC),
00042 NormalDistanceWeight(0.1f),
00043 DistanceThreshold(0.05f),
00044 MaxRadius(0.02),
00045 MinFitnessScore(0.0f),
00046 AlignToTopCentroid(true),
00047 Xmax(1.5),
00048 Xmin(0.5),
00049 Ymin(-1.2),
00050 Ymax(1.2),
00051 Zmin(-0.1),
00052 Zmax(0.5)
00053 {
00054
00055 }
00056
00057 void fetchParameters(std::string nameSpace = "")
00058 {
00059 ros::param::get(nameSpace + "/world_frame_id",WorldFrameId);
00060 ros::param::get(nameSpace + "/k_nearest",KNearestNeighbors);
00061 ros::param::get(nameSpace + "/max_iterations",MaxIterations);
00062 ros::param::get(nameSpace + "/sac_method",SacMethod);
00063 ros::param::get(nameSpace + "/normal_distance_weight",NormalDistanceWeight);
00064 ros::param::get(nameSpace + "/distance_threshold",DistanceThreshold);
00065 ros::param::get(nameSpace + "/max_radius",MaxRadius);
00066 ros::param::get(nameSpace + "/min_fitness_score",MinFitnessScore);
00067 ros::param::get(nameSpace + "/x_max",Xmax);
00068 ros::param::get(nameSpace + "/x_min",Xmin);
00069 ros::param::get(nameSpace + "/y_max",Ymax);
00070 ros::param::get(nameSpace + "/y_min",Ymin);
00071 ros::param::get(nameSpace + "/z_max",Zmax);
00072 ros::param::get(nameSpace + "/z_min",Zmin);
00073 ros::param::get(nameSpace + "/align_to_top_centroid",AlignToTopCentroid);
00074 }
00075
00076
00077 std::string WorldFrameId;
00078 int KNearestNeighbors;
00079 int MaxIterations;
00080 int SacMethod;
00081 double NormalDistanceWeight;
00082 double DistanceThreshold;
00083 double MaxRadius;
00084 double MinFitnessScore;
00085 bool AlignToTopCentroid;
00086
00087
00088 double Xmin;
00089 double Xmax;
00090 double Ymin;
00091 double Ymax;
00092 double Zmin;
00093 double Zmax;
00094 };
00095
00096 public:
00097 SphereSegmentation();
00098 virtual ~SphereSegmentation();
00099
00100 void setParameters(const Parameters ¶meters);
00101 Parameters getParameters();
00102
00103
00104 void fetchParameters(std::string nameSpace = "");
00105
00106
00107
00108
00109 bool segment(const sensor_msgs::PointCloud &cloudMsg,arm_navigation_msgs::CollisionObject &obj);
00110 bool segment(const sensor_msgs::PointCloud2 &cloudMsg,arm_navigation_msgs::CollisionObject &obj);
00111 bool segment(const std::vector<sensor_msgs::PointCloud> &clusters,arm_navigation_msgs::CollisionObject &obj,int &bestClusterIndex);
00112 bool segment(const Cloud3D &cluster,arm_navigation_msgs::CollisionObject &obj);
00113
00114
00115 void getSphereCluster(sensor_msgs::PointCloud &cluster);
00116
00117 protected:
00118
00119
00120
00121
00122 bool findSphereUsingTopPoint(const Cloud3D &cloud,pcl::ModelCoefficients::Ptr coefficients,pcl::PointIndices::Ptr inliers);
00123
00124 bool findTopCentroid(const Cloud3D &cloud,pcl::PointXYZ &topCentroid);
00125
00126
00127
00128 bool performSphereSegmentation(const Cloud3D &cloud,pcl::ModelCoefficients::Ptr coefficients,pcl::PointIndices::Ptr inliers);
00129
00130 void filterBounds(Cloud3D &cloud);
00131
00132
00133 void filterWithPolygonalPrism(Cloud3D &cloud,pcl::PointXYZ &point,int nSides,double radius,double heightMax,double heightMin);
00134
00135 void concatenateClouds(const std::vector<sensor_msgs::PointCloud> &clusters,Cloud3D &cluster);
00136
00137 void createObject(const pcl::ModelCoefficients &coeffs,arm_navigation_msgs::CollisionObject &obj);
00138
00139
00140 Parameters _Parameters;
00141
00142
00143 tf::TransformListener _TfListener;
00144
00145
00146 double _LastSegmentationScore;
00147 pcl::PointIndices _LastIndices;
00148 pcl::ModelCoefficients _LastCoefficients;
00149 Cloud3D _LastSphereSegCluster;
00150 bool _LastSphereSegSuccess;
00151
00152 };
00153
00154 #endif