Go to the documentation of this file.00001 #include "plane_segmentation_pcl_rgb_alg.h"
00002
00003 PlaneSegmentationPclRgbAlgorithm::PlaneSegmentationPclRgbAlgorithm(void)
00004 {
00005 }
00006
00007 PlaneSegmentationPclRgbAlgorithm::~PlaneSegmentationPclRgbAlgorithm(void)
00008 {
00009 }
00010
00011 void PlaneSegmentationPclRgbAlgorithm::config_update(Config& new_cfg, uint32_t level)
00012 {
00013 this->lock();
00014
00015 this->pointcloud_downsample = new_cfg.pointcloud_downsample;
00016 this->pointcloud_downsample_size = new_cfg.pointcloud_downsample_size;
00017 this->choose_plane_by_distance = new_cfg.choose_plane_by_distance;
00018 this->choose_nearest_plane = new_cfg.choose_nearest_plane;
00019 this->plane_size_thresh = new_cfg.plane_size_thresh;
00020 this->plane_min_height = new_cfg.plane_min_height;
00021 this->plane_max_height = new_cfg.plane_max_height;
00022 this->plane_segm_iterations = new_cfg.plane_segm_iterations;
00023 this->plane_clustering = new_cfg.plane_clustering;
00024 this->plane_min_cluster_size = new_cfg.plane_min_cluster_size;
00025 this->plane_min_cluster_distance = new_cfg.plane_min_cluster_distance;
00026 this->plane_segm_probability = new_cfg.plane_segm_probability;
00027
00028
00029 this->config_=new_cfg;
00030
00031 this->unlock();
00032 }
00033
00034
00035 pcl::PointCloud<pcl::PointXYZRGB>::Ptr PlaneSegmentationPclRgbAlgorithm::segmentBiggestPlane (pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_rgb_orig,
00036 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_orig,
00037 pcl::ModelCoefficients::Ptr coefficients)
00038 {
00039 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_rgb_dst (new pcl::PointCloud<pcl::PointXYZRGB>);
00040
00041
00042 *cloud_rgb_dst = *cloud_rgb_orig;
00043
00044
00045 pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
00046
00047
00048 if (pointcloud_downsample)
00049 getBiggestPlaneInliersDownsampling(inliers, coefficients, cloud_orig);
00050 else
00051 getBiggestPlaneInliers(inliers, coefficients, cloud_orig);
00052
00053
00054
00055 for (size_t i = 0; i < cloud_rgb_dst->size(); ++i)
00056 {
00057 cloud_rgb_dst->at(i).rgb = 0;
00058 }
00059
00060 for (size_t i = 0; i < inliers->indices.size(); ++i)
00061 {
00062 cloud_rgb_dst->at(inliers->indices[i]).rgb = cloud_rgb_orig->at(inliers->indices[i]).rgb;
00063 }
00064
00065
00066 fixPlaneCoefficientsOrientation(coefficients);
00067
00068 return cloud_rgb_dst;
00069 }
00070
00071
00072 void PlaneSegmentationPclRgbAlgorithm::getBiggestPlaneInliersDownsampling(pcl::PointIndices::Ptr inliers,
00073 pcl::ModelCoefficients::Ptr coefficients,
00074 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
00075 {
00076 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled (new pcl::PointCloud<pcl::PointXYZ>);
00077 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_seg (new pcl::PointCloud<pcl::PointXYZ>);
00078 pcl::PointCloud<pcl::PointXYZ>::Ptr ground_hull (new pcl::PointCloud<pcl::PointXYZ>);
00079
00080
00081 pcl::VoxelGrid<pcl::PointXYZ> grid_objects_;
00082 grid_objects_.setLeafSize (pointcloud_downsample_size, pointcloud_downsample_size, pointcloud_downsample_size);
00083 grid_objects_.setDownsampleAllData (false);
00084
00085 grid_objects_.setInputCloud (cloud);
00086 grid_objects_.filter (*cloud_downsampled);
00087
00088
00089 if (choose_plane_by_distance)
00090 getNearestBigPlaneInliers(inliers, coefficients, cloud_downsampled);
00091 else
00092 getBiggestPlaneInliers(inliers, coefficients, cloud_downsampled);
00093
00094
00095 if (inliers->indices.size() == 0) {
00096
00097 ROS_WARN_STREAM("Plane segmentation: couldn't find plane.");
00098 return;
00099 }
00100
00101
00102 pcl::ProjectInliers<pcl::PointXYZ> proj;
00103 proj.setModelType(pcl::SACMODEL_PLANE);
00104 proj.setInputCloud(cloud_downsampled);
00105 proj.setModelCoefficients(coefficients);
00106 proj.setIndices (inliers);
00107 proj.filter(*cloud_seg);
00108
00109
00110 pcl::PassThrough<pcl::PointXYZ> pass;
00111 pass.setInputCloud (cloud_seg);
00112 pass.filter (*cloud_seg);
00113
00114
00115 if (plane_clustering)
00116 cloud_seg = getBiggestClusterPC(cloud_seg);
00117
00118
00119 pcl::ConvexHull<pcl::PointXYZ> chull;
00120 chull.setInputCloud(cloud_seg);
00121 chull.setDimension(2);
00122 chull.reconstruct(*ground_hull);
00123
00124
00125
00126 pcl::PointIndices::Ptr object_indices (new pcl::PointIndices);
00127 pcl::ExtractPolygonalPrismData<pcl::PointXYZ> hull_limiter;
00128 hull_limiter.setInputCloud(cloud);
00129 hull_limiter.setInputPlanarHull(ground_hull);
00130 hull_limiter.setHeightLimits(plane_min_height, plane_max_height);
00131 hull_limiter.segment(*object_indices);
00132
00133 *inliers = *object_indices;
00134 }
00135
00136
00137 void PlaneSegmentationPclRgbAlgorithm::getNearestBigPlaneInliers(pcl::PointIndices::Ptr inliers,
00138 pcl::ModelCoefficients::Ptr coefficients,
00139 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_orig)
00140 {
00141 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_seg (new pcl::PointCloud<pcl::PointXYZ>);
00142 pcl::PointIndices::Ptr inliers_first (new pcl::PointIndices ());
00143 pcl::PointIndices::Ptr inliers_second (new pcl::PointIndices ());
00144 pcl::ModelCoefficients::Ptr coefficients_first (new pcl::ModelCoefficients);
00145 pcl::ModelCoefficients::Ptr coefficients_second (new pcl::ModelCoefficients);
00146 pcl::ExtractIndices<pcl::PointXYZ> extract;
00147 float dist1, dist2;
00148 pcl::PointXYZ p_orig = pcl::PointXYZ(0,0,0);
00149 ROS_DEBUG("Get nearest big plane.");
00150
00151
00152 getBiggestPlaneInliers(inliers_first, coefficients_first, cloud_orig);
00153
00154
00155 if (inliers_first->indices.size () == 0)
00156 return;
00157
00158
00159 dist1 = pointToPlaneDistance(p_orig, coefficients_first->values);
00160
00161
00162 extract.setInputCloud (cloud_orig);
00163 extract.setIndices (inliers_first);
00164 extract.setNegative (true);
00165 extract.filter (*cloud_seg);
00166
00167
00168 getBiggestPlaneInliers(inliers_second, coefficients_second, cloud_seg);
00169
00170
00171 if (inliers_second->indices.size () == 0) {
00172 ROS_INFO_STREAM("Plane segmentation: couldn't find a second plane. Choosing biggest one.");
00173 *inliers = *inliers_first;
00174 *coefficients = *coefficients_first;
00175 return;
00176 }
00177
00178
00179 dist2 = pointToPlaneDistance(p_orig, coefficients_second->values);
00180
00181 ROS_DEBUG_STREAM("Dist 1 is "<<dist1);
00182 ROS_DEBUG_STREAM("Dist 2 is "<<dist2);
00183
00184
00185 if ( ( (dist1 < dist2) && choose_nearest_plane ) || ( (dist1 > dist2) && !choose_nearest_plane ) ) {
00186 ROS_DEBUG("Chose biggest plane.");
00187 *inliers = *inliers_first;
00188 *coefficients = *coefficients_first;
00189 }
00190 else {
00191 ROS_DEBUG("Chose second biggest plane.");
00192 *inliers = *inliers_second;
00193 *coefficients = *coefficients_second;
00194 *cloud_orig = *cloud_seg;
00195 }
00196
00197
00198 }
00199
00200
00201 void PlaneSegmentationPclRgbAlgorithm::getBiggestPlaneInliers(pcl::PointIndices::Ptr inliers,
00202 pcl::ModelCoefficients::Ptr coefficients,
00203 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
00204 {
00205
00206 pcl::SACSegmentation<pcl::PointXYZ> seg;
00207
00208 seg.setOptimizeCoefficients (true);
00209
00210 seg.setMaxIterations (plane_segm_iterations);
00211
00212 seg.setProbability (plane_segm_probability);
00213
00214 seg.setModelType (pcl::SACMODEL_PLANE);
00215 seg.setMethodType (pcl::SAC_RANSAC);
00216 seg.setDistanceThreshold (plane_size_thresh);
00217
00218
00219 seg.setInputCloud (cloud);
00220 seg.segment (*inliers, *coefficients);
00221 }
00222
00223
00224 void PlaneSegmentationPclRgbAlgorithm::fixPlaneCoefficientsOrientation(pcl::ModelCoefficients::Ptr coefs)
00225 {
00226 if (coefs->values.size() == 0) {
00227 coefs->values.resize(4);
00228 coefs->values[0] = 0;
00229 coefs->values[1] = 0;
00230 coefs->values[2] = 0;
00231 coefs->values[3] = 0;
00232 }
00233 else if (coefs->values[2] < 0) {
00234 coefs->values[0] = -coefs->values[0];
00235 coefs->values[1] = -coefs->values[1];
00236 coefs->values[2] = -coefs->values[2];
00237 coefs->values[3] = -coefs->values[3];
00238 }
00239 }
00240
00241
00242 pcl::PointCloud<pcl::PointXYZ>::Ptr PlaneSegmentationPclRgbAlgorithm::getBiggestClusterPC (pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_orig)
00243 {
00244 pcl::EuclideanClusterExtraction<pcl::PointXYZ> pcl_cluster;
00245
00246 pcl_cluster.setClusterTolerance (plane_min_cluster_distance);
00247
00248 pcl_cluster.setMinClusterSize (plane_min_cluster_size);
00249
00250 ROS_DEBUG("Clustering");
00251
00252 ROS_DEBUG_STREAM("Original pointcloud size is" << cloud_orig->points.size());
00253
00254 std::vector<pcl::PointIndices> clusters;
00255 pcl_cluster.setInputCloud (cloud_orig);
00256 pcl_cluster.extract (clusters);
00257
00258
00259 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
00260
00261 ROS_DEBUG_STREAM("Number of clusters is " << clusters.size());
00262
00263 if ((int)clusters.size () > 0 ) {
00264
00265 size_t biggest_cluster = 0;
00266 for (size_t j = 1; j < clusters.size (); ++j) {
00267 if (clusters[biggest_cluster].indices.size () < clusters[j].indices.size ())
00268 biggest_cluster = j;
00269 }
00270
00271 ROS_DEBUG_STREAM("Biggest cluster is " << clusters[biggest_cluster].indices.size());
00272 cloud_cluster->points.resize (clusters[biggest_cluster].indices.size ());
00273 for (size_t j = 0; j < cloud_cluster->points.size (); ++j)
00274 {
00275 cloud_cluster->points[j].x = cloud_orig->points[clusters[biggest_cluster].indices[j]].x;
00276 cloud_cluster->points[j].y = cloud_orig->points[clusters[biggest_cluster].indices[j]].y;
00277 cloud_cluster->points[j].z = cloud_orig->points[clusters[biggest_cluster].indices[j]].z;
00278 }
00279 }
00280 else
00281 *cloud_cluster = *cloud_orig;
00282
00283 return cloud_cluster;
00284 }