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 #include <boost/thread/thread.hpp>
00037 #include <boost/date_time/posix_time/posix_time.hpp>
00038
00039 #include <pcl/apps/dominant_plane_segmentation.h>
00040 #include <pcl/visualization/pcl_visualizer.h>
00041 #include <pcl/features/integral_image_normal.h>
00042 #include <pcl/common/time.h>
00043
00044 template<typename PointType> void
00045 pcl::apps::DominantPlaneSegmentation<PointType>::compute_table_plane ()
00046 {
00047
00048 if (!input_)
00049 {
00050 PCL_WARN ("[pcl::apps::DominantPlaneSegmentation] No input dataset given!\n");
00051 return;
00052 }
00053
00054 CloudConstPtr cloud_;
00055 CloudPtr cloud_filtered_ (new Cloud ());
00056 CloudPtr cloud_downsampled_ (new Cloud ());
00057 pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ (new pcl::PointCloud<pcl::Normal> ());
00058 pcl::PointIndices::Ptr table_inliers_ (new pcl::PointIndices ());
00059 pcl::ModelCoefficients::Ptr table_coefficients_ (new pcl::ModelCoefficients ());
00060 CloudPtr table_projected_ (new Cloud ());
00061 CloudPtr table_hull_ (new Cloud ());
00062
00063 typename pcl::search::KdTree<PointType>::Ptr normals_tree_ (new pcl::search::KdTree<PointType>);
00064
00065
00066 n3d_.setKSearch (k_);
00067 n3d_.setSearchMethod (normals_tree_);
00068
00069
00070 seg_.setDistanceThreshold (sac_distance_threshold_);
00071 seg_.setMaxIterations (2000);
00072 seg_.setNormalDistanceWeight (0.1);
00073 seg_.setOptimizeCoefficients (true);
00074 seg_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00075 seg_.setMethodType (pcl::SAC_RANSAC);
00076 seg_.setProbability (0.99);
00077
00078 proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00079 bb_cluster_proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00080
00081
00082 pass_.setFilterLimits (min_z_bounds_, max_z_bounds_);
00083 pass_.setFilterFieldName ("z");
00084 pass_.setInputCloud (input_);
00085 pass_.filter (*cloud_filtered_);
00086
00087 if (int (cloud_filtered_->points.size ()) < k_)
00088 {
00089 PCL_WARN ("[DominantPlaneSegmentation] Filtering returned %zu points! Aborting.",
00090 cloud_filtered_->points.size ());
00091 return;
00092 }
00093
00094
00095 grid_.setLeafSize (downsample_leaf_, downsample_leaf_, downsample_leaf_);
00096 grid_.setDownsampleAllData (false);
00097 grid_.setInputCloud (cloud_filtered_);
00098 grid_.filter (*cloud_downsampled_);
00099
00100
00101 n3d_.setInputCloud (cloud_downsampled_);
00102 n3d_.compute (*cloud_normals_);
00103
00104
00105 seg_.setInputCloud (cloud_downsampled_);
00106 seg_.setInputNormals (cloud_normals_);
00107 seg_.segment (*table_inliers_, *table_coefficients_);
00108
00109 if (table_inliers_->indices.size () == 0)
00110 {
00111 PCL_WARN ("[DominantPlaneSegmentation] No Plane Inliers points! Aborting.");
00112 return;
00113 }
00114
00115
00116 proj_.setInputCloud (cloud_downsampled_);
00117 proj_.setIndices (table_inliers_);
00118 proj_.setModelCoefficients (table_coefficients_);
00119 proj_.filter (*table_projected_);
00120
00121
00122 std::vector<pcl::Vertices> polygons;
00123 CloudPtr table_hull (new Cloud ());
00124 hull_.setInputCloud (table_projected_);
00125 hull_.reconstruct (*table_hull, polygons);
00126
00127
00128 Eigen::Vector4f model_coefficients;
00129 EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
00130
00131 model_coefficients[0] = table_coefficients_->values[0];
00132 model_coefficients[1] = table_coefficients_->values[1];
00133 model_coefficients[2] = table_coefficients_->values[2];
00134 model_coefficients[3] = table_coefficients_->values[3];
00135
00136
00137 Eigen::Vector4f vp (0, 0, 0, 0);
00138
00139 vp -= table_hull->points[0].getVector4fMap ();
00140 vp[3] = 0;
00141
00142 float cos_theta = vp.dot (model_coefficients);
00143
00144 if (cos_theta < 0)
00145 {
00146 model_coefficients *= -1;
00147 model_coefficients[3] = 0;
00148
00149 model_coefficients[3] = -1 * (model_coefficients.dot (table_hull->points[0].getVector4fMap ()));
00150 }
00151
00152
00153 table_coeffs_ = model_coefficients;
00154 }
00155
00156 template<typename PointType> void
00157 pcl::apps::DominantPlaneSegmentation<PointType>::compute_fast (std::vector<CloudPtr> & clusters)
00158 {
00159
00160 if (!input_)
00161 {
00162 PCL_WARN ("[pcl::apps::DominantPlaneSegmentation] No input dataset given!\n");
00163 return;
00164 }
00165
00166
00167 if (input_->is_dense)
00168 {
00169 PCL_WARN ("[pcl::apps::DominantPlaneSegmentation] compute_fast can only be used with organized point clouds!\n");
00170 return;
00171 }
00172
00173 CloudConstPtr cloud_;
00174 CloudPtr cloud_filtered_ (new Cloud ());
00175 CloudPtr cloud_downsampled_ (new Cloud ());
00176 pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ (new pcl::PointCloud<pcl::Normal> ());
00177 pcl::PointIndices::Ptr table_inliers_ (new pcl::PointIndices ());
00178 pcl::ModelCoefficients::Ptr table_coefficients_ (new pcl::ModelCoefficients ());
00179 CloudPtr table_projected_ (new Cloud ());
00180 CloudPtr table_hull_ (new Cloud ());
00181 CloudPtr cloud_objects_ (new Cloud ());
00182 CloudPtr cluster_object_ (new Cloud ());
00183
00184 typename pcl::search::KdTree<PointType>::Ptr normals_tree_ (new pcl::search::KdTree<PointType>);
00185 typename pcl::search::KdTree<PointType>::Ptr clusters_tree_ (new pcl::search::KdTree<PointType>);
00186 clusters_tree_->setEpsilon (1);
00187
00188
00189 n3d_.setKSearch (k_);
00190 n3d_.setSearchMethod (normals_tree_);
00191
00192
00193 seg_.setDistanceThreshold (sac_distance_threshold_);
00194 seg_.setMaxIterations (2000);
00195 seg_.setNormalDistanceWeight (0.1);
00196 seg_.setOptimizeCoefficients (true);
00197 seg_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00198 seg_.setMethodType (pcl::SAC_RANSAC);
00199 seg_.setProbability (0.99);
00200
00201 proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00202 bb_cluster_proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00203
00204 prism_.setHeightLimits (object_min_height_, object_max_height_);
00205
00206
00207 cluster_.setClusterTolerance (object_cluster_tolerance_);
00208 cluster_.setMinClusterSize (object_cluster_min_size_);
00209 cluster_.setSearchMethod (clusters_tree_);
00210
00211
00212 pass_.setFilterLimits (min_z_bounds_, max_z_bounds_);
00213 pass_.setFilterFieldName ("z");
00214 pass_.setInputCloud (input_);
00215 pass_.filter (*cloud_filtered_);
00216
00217 if (int (cloud_filtered_->points.size ()) < k_)
00218 {
00219 PCL_WARN ("[DominantPlaneSegmentation] Filtering returned %zu points! Aborting.",
00220 cloud_filtered_->points.size ());
00221 return;
00222 }
00223
00224
00225 grid_.setLeafSize (downsample_leaf_, downsample_leaf_, downsample_leaf_);
00226 grid_.setDownsampleAllData (false);
00227 grid_.setInputCloud (cloud_filtered_);
00228 grid_.filter (*cloud_downsampled_);
00229
00230
00231 n3d_.setInputCloud (cloud_downsampled_);
00232 n3d_.compute (*cloud_normals_);
00233
00234
00235 seg_.setInputCloud (cloud_downsampled_);
00236 seg_.setInputNormals (cloud_normals_);
00237 seg_.segment (*table_inliers_, *table_coefficients_);
00238
00239 if (table_inliers_->indices.size () == 0)
00240 {
00241 PCL_WARN ("[DominantPlaneSegmentation] No Plane Inliers points! Aborting.");
00242 return;
00243 }
00244
00245
00246 proj_.setInputCloud (cloud_downsampled_);
00247 proj_.setIndices (table_inliers_);
00248 proj_.setModelCoefficients (table_coefficients_);
00249 proj_.filter (*table_projected_);
00250
00251
00252 std::vector<pcl::Vertices> polygons;
00253 CloudPtr table_hull (new Cloud ());
00254 hull_.setInputCloud (table_projected_);
00255 hull_.reconstruct (*table_hull, polygons);
00256
00257
00258 Eigen::Vector4f model_coefficients;
00259 EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
00260
00261 model_coefficients[0] = table_coefficients_->values[0];
00262 model_coefficients[1] = table_coefficients_->values[1];
00263 model_coefficients[2] = table_coefficients_->values[2];
00264 model_coefficients[3] = table_coefficients_->values[3];
00265
00266
00267 Eigen::Vector4f vp (0, 0, 0, 0);
00268
00269 vp -= table_hull->points[0].getVector4fMap ();
00270 vp[3] = 0;
00271
00272 float cos_theta = vp.dot (model_coefficients);
00273
00274 if (cos_theta < 0)
00275 {
00276 model_coefficients *= -1;
00277 model_coefficients[3] = 0;
00278
00279 model_coefficients[3] = -1 * (model_coefficients.dot (table_hull->points[0].getVector4fMap ()));
00280 }
00281
00282
00283 table_coeffs_ = model_coefficients;
00284
00285
00286 pcl::PointIndices cloud_object_indices;
00287 prism_.setInputCloud (input_);
00288 prism_.setInputPlanarHull (table_hull);
00289 prism_.segment (cloud_object_indices);
00290
00291 pcl::ExtractIndices<PointType> extract_object_indices;
00292 extract_object_indices.setInputCloud (input_);
00293 extract_object_indices.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
00294 extract_object_indices.filter (*cloud_objects_);
00295
00296
00297 pcl::PointCloud<pcl::PointXYZI>::Ptr binary_cloud (new pcl::PointCloud<pcl::PointXYZI>);
00298
00299 {
00300 binary_cloud->width = input_->width;
00301 binary_cloud->height = input_->height;
00302 binary_cloud->points.resize (input_->points.size ());
00303 binary_cloud->is_dense = input_->is_dense;
00304
00305 size_t idx;
00306 for (size_t i = 0; i < cloud_object_indices.indices.size (); ++i)
00307 {
00308 idx = cloud_object_indices.indices[i];
00309 binary_cloud->points[idx].getVector4fMap () = input_->points[idx].getVector4fMap ();
00310 binary_cloud->points[idx].intensity = 1.0;
00311 }
00312 }
00313
00314
00315
00316 std::map<float, float> connected_labels;
00317 float c_intensity = 0.1f;
00318 float intensity_incr = 0.1f;
00319
00320 {
00321
00322 int wsize = wsize_;
00323 for (int i = 0; i < int (binary_cloud->width); i++)
00324 {
00325 for (int j = 0; j < int (binary_cloud->height); j++)
00326 {
00327 if (binary_cloud->at (i, j).intensity != 0)
00328 {
00329
00330
00331
00332 if ((i - 1) < 0 && (j - 1) < 0)
00333 {
00334
00335 (*binary_cloud) (i, j).intensity = c_intensity;
00336 }
00337 else
00338 {
00339 if ((j - 1) < 0)
00340 {
00341
00342 int left = check ((*binary_cloud) (i - 1, j), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00343 if (left)
00344 {
00345
00346
00347 bool found = false;
00348 for (int kk = 2; kk < wsize && !found; kk++)
00349 {
00350 if ((i - kk) < 0)
00351 continue;
00352
00353 int left = check ((*binary_cloud) (i - kk, j), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00354 if (left == 0)
00355 {
00356 found = true;
00357 }
00358 }
00359
00360 if (!found)
00361 {
00362 c_intensity += intensity_incr;
00363 (*binary_cloud) (i, j).intensity = c_intensity;
00364 }
00365
00366 }
00367 }
00368 else
00369 {
00370 if ((i - 1) == 0)
00371 {
00372
00373 int top = check ((*binary_cloud) (i, j - 1), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00374 if (top)
00375 {
00376 bool found = false;
00377 for (int kk = 2; kk < wsize && !found; kk++)
00378 {
00379 if ((j - kk) < 0)
00380 continue;
00381
00382 int top = check ((*binary_cloud) (i, j - kk), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00383 if (top == 0)
00384 {
00385 found = true;
00386 }
00387 }
00388
00389 if (!found)
00390 {
00391 c_intensity += intensity_incr;
00392 (*binary_cloud) (i, j).intensity = c_intensity;
00393 }
00394 }
00395
00396 }
00397 else
00398 {
00399
00400 int left = check ((*binary_cloud) (i - 1, j), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00401 int top = check ((*binary_cloud) (i, j - 1), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00402
00403 if (left == 0 && top == 0)
00404 {
00405
00406
00407
00408 if ((*binary_cloud) (i - 1, j).intensity != (*binary_cloud) (i, j - 1).intensity)
00409 {
00410 float smaller_intensity = (*binary_cloud) (i - 1, j).intensity;
00411 float bigger_intensity = (*binary_cloud) (i, j - 1).intensity;
00412
00413 if ((*binary_cloud) (i - 1, j).intensity > (*binary_cloud) (i, j - 1).intensity)
00414 {
00415 smaller_intensity = (*binary_cloud) (i, j - 1).intensity;
00416 bigger_intensity = (*binary_cloud) (i - 1, j).intensity;
00417 }
00418
00419 connected_labels[bigger_intensity] = smaller_intensity;
00420 (*binary_cloud) (i, j).intensity = smaller_intensity;
00421 }
00422 }
00423
00424 if (left == 1 && top == 1)
00425 {
00426
00427
00428 bool found = false;
00429 for (int dist = 2; dist < wsize && !found; dist++)
00430 {
00431 if (((i - dist) < 0) || ((j - dist) < 0))
00432 continue;
00433
00434 int left = check ((*binary_cloud) (i - dist, j), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00435 int top = check ((*binary_cloud) (i, j - dist), (*binary_cloud) (i, j), c_intensity, object_cluster_tolerance_);
00436
00437 if (left == 0 && top == 0)
00438 {
00439 if ((*binary_cloud) (i - dist, j).intensity != (*binary_cloud) (i, j - dist).intensity)
00440 {
00441 float smaller_intensity = (*binary_cloud) (i - dist, j).intensity;
00442 float bigger_intensity = (*binary_cloud) (i, j - dist).intensity;
00443
00444 if ((*binary_cloud) (i - dist, j).intensity > (*binary_cloud) (i, j - dist).intensity)
00445 {
00446 smaller_intensity = (*binary_cloud) (i, j - dist).intensity;
00447 bigger_intensity = (*binary_cloud) (i - dist, j).intensity;
00448 }
00449
00450 connected_labels[bigger_intensity] = smaller_intensity;
00451 (*binary_cloud) (i, j).intensity = smaller_intensity;
00452 found = true;
00453 }
00454 }
00455 else if (left == 0 || top == 0)
00456 {
00457
00458 found = true;
00459 }
00460 }
00461
00462 if (!found)
00463 {
00464
00465 c_intensity += intensity_incr;
00466 (*binary_cloud) (i, j).intensity = c_intensity;
00467 }
00468 }
00469 }
00470 }
00471 }
00472
00473 }
00474 }
00475 }
00476 }
00477
00478 std::map<float, pcl::PointIndices> clusters_map;
00479
00480 {
00481 std::map<float, float>::iterator it;
00482
00483 for (int i = 0; i < int (binary_cloud->width); i++)
00484 {
00485 for (int j = 0; j < int (binary_cloud->height); j++)
00486 {
00487 if (binary_cloud->at (i, j).intensity != 0)
00488 {
00489
00490 it = connected_labels.find (binary_cloud->at (i, j).intensity);
00491 while (it != connected_labels.end ())
00492 {
00493
00494 (*binary_cloud) (i, j).intensity = (*it).second;
00495 it = connected_labels.find (binary_cloud->at (i, j).intensity);
00496 }
00497
00498 std::map<float, pcl::PointIndices>::iterator it_indices;
00499 it_indices = clusters_map.find (binary_cloud->at (i, j).intensity);
00500 if (it_indices == clusters_map.end ())
00501 {
00502 pcl::PointIndices indices;
00503 clusters_map[binary_cloud->at (i, j).intensity] = indices;
00504 }
00505
00506 clusters_map[binary_cloud->at (i, j).intensity].indices.push_back (static_cast<int> (j * binary_cloud->width + i));
00507 }
00508 }
00509 }
00510 }
00511
00512 clusters.resize (clusters_map.size ());
00513
00514 std::map<float, pcl::PointIndices>::iterator it_indices;
00515 int k = 0;
00516 for (it_indices = clusters_map.begin (); it_indices != clusters_map.end (); it_indices++)
00517 {
00518
00519 if (int ((*it_indices).second.indices.size ()) >= object_cluster_min_size_)
00520 {
00521
00522 clusters[k] = CloudPtr (new Cloud ());
00523 pcl::copyPointCloud (*input_, (*it_indices).second.indices, *clusters[k]);
00524 k++;
00525 indices_clusters_.push_back((*it_indices).second);
00526 }
00527 }
00528
00529 clusters.resize (k);
00530
00531 }
00532
00533 template<typename PointType> void
00534 pcl::apps::DominantPlaneSegmentation<PointType>::compute (std::vector<CloudPtr> & clusters)
00535 {
00536
00537
00538 if (!input_)
00539 {
00540 PCL_WARN ("[pcl::apps::DominantPlaneSegmentation] No input dataset given!\n");
00541 return;
00542 }
00543
00544 CloudConstPtr cloud_;
00545 CloudPtr cloud_filtered_ (new Cloud ());
00546 CloudPtr cloud_downsampled_ (new Cloud ());
00547 pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ (new pcl::PointCloud<pcl::Normal> ());
00548 pcl::PointIndices::Ptr table_inliers_ (new pcl::PointIndices ());
00549 pcl::ModelCoefficients::Ptr table_coefficients_ (new pcl::ModelCoefficients ());
00550 CloudPtr table_projected_ (new Cloud ());
00551 CloudPtr table_hull_ (new Cloud ());
00552 CloudPtr cloud_objects_ (new Cloud ());
00553 CloudPtr cluster_object_ (new Cloud ());
00554
00555 typename pcl::search::KdTree<PointType>::Ptr normals_tree_ (new pcl::search::KdTree<PointType>);
00556 typename pcl::search::KdTree<PointType>::Ptr clusters_tree_ (new pcl::search::KdTree<PointType>);
00557 clusters_tree_->setEpsilon (1);
00558
00559
00560 n3d_.setKSearch (k_);
00561 n3d_.setSearchMethod (normals_tree_);
00562
00563
00564 seg_.setDistanceThreshold (sac_distance_threshold_);
00565 seg_.setMaxIterations (2000);
00566 seg_.setNormalDistanceWeight (0.1);
00567 seg_.setOptimizeCoefficients (true);
00568 seg_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00569 seg_.setMethodType (pcl::SAC_RANSAC);
00570 seg_.setProbability (0.99);
00571
00572 proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00573 bb_cluster_proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00574
00575 prism_.setHeightLimits (object_min_height_, object_max_height_);
00576
00577
00578 cluster_.setClusterTolerance (object_cluster_tolerance_);
00579 cluster_.setMinClusterSize (object_cluster_min_size_);
00580 cluster_.setSearchMethod (clusters_tree_);
00581
00582
00583 pass_.setFilterLimits (min_z_bounds_, max_z_bounds_);
00584 pass_.setFilterFieldName ("z");
00585 pass_.setInputCloud (input_);
00586 pass_.filter (*cloud_filtered_);
00587
00588 if (int (cloud_filtered_->points.size ()) < k_)
00589 {
00590 PCL_WARN ("[DominantPlaneSegmentation] Filtering returned %zu points! Aborting.",
00591 cloud_filtered_->points.size ());
00592 return;
00593 }
00594
00595
00596 grid_.setLeafSize (downsample_leaf_, downsample_leaf_, downsample_leaf_);
00597 grid_.setDownsampleAllData (false);
00598 grid_.setInputCloud (cloud_filtered_);
00599 grid_.filter (*cloud_downsampled_);
00600
00601 PCL_INFO ("[DominantPlaneSegmentation] Number of points left after filtering (%f -> %f): %zu out of %zu\n",
00602 min_z_bounds_, max_z_bounds_, cloud_downsampled_->points.size (), input_->points.size ());
00603
00604
00605 n3d_.setInputCloud (cloud_downsampled_);
00606 n3d_.compute (*cloud_normals_);
00607
00608 PCL_INFO ("[DominantPlaneSegmentation] %zu normals estimated. \n", cloud_normals_->points.size ());
00609
00610
00611 seg_.setInputCloud (cloud_downsampled_);
00612 seg_.setInputNormals (cloud_normals_);
00613 seg_.segment (*table_inliers_, *table_coefficients_);
00614
00615 if (table_inliers_->indices.size () == 0)
00616 {
00617 PCL_WARN ("[DominantPlaneSegmentation] No Plane Inliers points! Aborting.");
00618 return;
00619 }
00620
00621
00622 proj_.setInputCloud (cloud_downsampled_);
00623 proj_.setIndices (table_inliers_);
00624 proj_.setModelCoefficients (table_coefficients_);
00625 proj_.filter (*table_projected_);
00626
00627
00628 std::vector<pcl::Vertices> polygons;
00629 CloudPtr table_hull (new Cloud ());
00630 hull_.setInputCloud (table_projected_);
00631 hull_.reconstruct (*table_hull, polygons);
00632
00633
00634 Eigen::Vector4f model_coefficients;
00635 EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
00636
00637 model_coefficients[0] = table_coefficients_->values[0];
00638 model_coefficients[1] = table_coefficients_->values[1];
00639 model_coefficients[2] = table_coefficients_->values[2];
00640 model_coefficients[3] = table_coefficients_->values[3];
00641
00642
00643 Eigen::Vector4f vp (0, 0, 0, 0);
00644
00645 vp -= table_hull->points[0].getVector4fMap ();
00646 vp[3] = 0;
00647
00648 float cos_theta = vp.dot (model_coefficients);
00649
00650 if (cos_theta < 0)
00651 {
00652 model_coefficients *= -1;
00653 model_coefficients[3] = 0;
00654
00655 model_coefficients[3] = -1 * (model_coefficients.dot (table_hull->points[0].getVector4fMap ()));
00656 }
00657
00658
00659 table_coeffs_ = model_coefficients;
00660
00661
00662 pcl::PointIndices cloud_object_indices;
00663 prism_.setInputCloud (cloud_downsampled_);
00664 prism_.setInputPlanarHull (table_hull);
00665 prism_.segment (cloud_object_indices);
00666
00667 pcl::ExtractIndices<PointType> extract_object_indices;
00668 extract_object_indices.setInputCloud (cloud_downsampled_);
00669 extract_object_indices.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
00670 extract_object_indices.filter (*cloud_objects_);
00671
00672 if (cloud_objects_->points.size () == 0)
00673 return;
00674
00675
00676
00677
00678 std::vector<pcl::PointIndices> clusters2;
00679 cluster_.setInputCloud (cloud_downsampled_);
00680 cluster_.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
00681 cluster_.extract (clusters2);
00682
00683 PCL_INFO ("[DominantPlaneSegmentation::compute()] Number of clusters found matching the given constraints: %zu.\n",
00684 clusters2.size ());
00685
00686 clusters.resize (clusters2.size ());
00687
00688 for (size_t i = 0; i < clusters2.size (); ++i)
00689 {
00690 clusters[i] = CloudPtr (new Cloud ());
00691 pcl::copyPointCloud (*cloud_downsampled_, clusters2[i].indices, *clusters[i]);
00692 }
00693 }
00694
00695 template<typename PointType>
00696 void
00697 pcl::apps::DominantPlaneSegmentation<PointType>::compute_full (std::vector<CloudPtr> & clusters)
00698 {
00699
00700
00701 if (!input_)
00702 {
00703 PCL_WARN ("[pcl::apps::DominantPlaneSegmentation] No input dataset given!\n");
00704 return;
00705 }
00706
00707 CloudConstPtr cloud_;
00708 CloudPtr cloud_filtered_ (new Cloud ());
00709 CloudPtr cloud_downsampled_ (new Cloud ());
00710 pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ (new pcl::PointCloud<pcl::Normal> ());
00711 pcl::PointIndices::Ptr table_inliers_ (new pcl::PointIndices ());
00712 pcl::ModelCoefficients::Ptr table_coefficients_ (new pcl::ModelCoefficients ());
00713 CloudPtr table_projected_ (new Cloud ());
00714 CloudPtr table_hull_ (new Cloud ());
00715 CloudPtr cloud_objects_ (new Cloud ());
00716 CloudPtr cluster_object_ (new Cloud ());
00717
00718 typename pcl::search::KdTree<PointType>::Ptr normals_tree_ (new pcl::search::KdTree<PointType>);
00719 typename pcl::search::KdTree<PointType>::Ptr clusters_tree_ (new pcl::search::KdTree<PointType>);
00720 clusters_tree_->setEpsilon (1);
00721
00722
00723 n3d_.setKSearch (10);
00724 n3d_.setSearchMethod (normals_tree_);
00725
00726
00727 seg_.setDistanceThreshold (sac_distance_threshold_);
00728 seg_.setMaxIterations (2000);
00729 seg_.setNormalDistanceWeight (0.1);
00730 seg_.setOptimizeCoefficients (true);
00731 seg_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00732 seg_.setMethodType (pcl::SAC_MSAC);
00733 seg_.setProbability (0.98);
00734
00735 proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00736 bb_cluster_proj_.setModelType (pcl::SACMODEL_NORMAL_PLANE);
00737
00738 prism_.setHeightLimits (object_min_height_, object_max_height_);
00739
00740
00741 cluster_.setClusterTolerance (object_cluster_tolerance_);
00742 cluster_.setMinClusterSize (object_cluster_min_size_);
00743 cluster_.setSearchMethod (clusters_tree_);
00744
00745
00746 pass_.setFilterLimits (min_z_bounds_, max_z_bounds_);
00747 pass_.setFilterFieldName ("z");
00748 pass_.setInputCloud (input_);
00749 pass_.filter (*cloud_filtered_);
00750
00751 if (int (cloud_filtered_->points.size ()) < k_)
00752 {
00753 PCL_WARN ("[DominantPlaneSegmentation] Filtering returned %zu points! Aborting.",
00754 cloud_filtered_->points.size ());
00755 return;
00756 }
00757
00758
00759 grid_.setLeafSize (downsample_leaf_, downsample_leaf_, downsample_leaf_);
00760 grid_.setDownsampleAllData (false);
00761 grid_.setInputCloud (cloud_filtered_);
00762 grid_.filter (*cloud_downsampled_);
00763
00764 PCL_INFO ("[DominantPlaneSegmentation] Number of points left after filtering&downsampling (%f -> %f): %zu out of %zu\n",
00765 min_z_bounds_, max_z_bounds_, cloud_downsampled_->points.size (), input_->points.size ());
00766
00767
00768 n3d_.setInputCloud (cloud_downsampled_);
00769 n3d_.compute (*cloud_normals_);
00770
00771 PCL_INFO ("[DominantPlaneSegmentation] %zu normals estimated. \n", cloud_normals_->points.size ());
00772
00773
00774 seg_.setInputCloud (cloud_downsampled_);
00775 seg_.setInputNormals (cloud_normals_);
00776 seg_.segment (*table_inliers_, *table_coefficients_);
00777
00778 if (table_inliers_->indices.size () == 0)
00779 {
00780 PCL_WARN ("[DominantPlaneSegmentation] No Plane Inliers points! Aborting.");
00781 return;
00782 }
00783
00784
00785 proj_.setInputCloud (cloud_downsampled_);
00786 proj_.setIndices (table_inliers_);
00787 proj_.setModelCoefficients (table_coefficients_);
00788 proj_.filter (*table_projected_);
00789
00790
00791 std::vector<pcl::Vertices> polygons;
00792 CloudPtr table_hull (new Cloud ());
00793 hull_.setInputCloud (table_projected_);
00794 hull_.reconstruct (*table_hull, polygons);
00795
00796
00797 Eigen::Vector4f model_coefficients;
00798 EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
00799
00800 model_coefficients[0] = table_coefficients_->values[0];
00801 model_coefficients[1] = table_coefficients_->values[1];
00802 model_coefficients[2] = table_coefficients_->values[2];
00803 model_coefficients[3] = table_coefficients_->values[3];
00804
00805
00806 Eigen::Vector4f vp (0, 0, 0, 0);
00807
00808 vp -= table_hull->points[0].getVector4fMap ();
00809 vp[3] = 0;
00810
00811 float cos_theta = vp.dot (model_coefficients);
00812
00813 if (cos_theta < 0)
00814 {
00815 model_coefficients *= -1;
00816 model_coefficients[3] = 0;
00817
00818 model_coefficients[3] = -1 * (model_coefficients.dot (table_hull->points[0].getVector4fMap ()));
00819 }
00820
00821
00822 table_coeffs_ = model_coefficients;
00823
00824
00825 pcl::PointIndices cloud_object_indices;
00826 prism_.setInputCloud (cloud_filtered_);
00827 prism_.setInputPlanarHull (table_hull);
00828 prism_.segment (cloud_object_indices);
00829
00830 pcl::ExtractIndices<PointType> extract_object_indices;
00831 extract_object_indices.setInputCloud (cloud_downsampled_);
00832 extract_object_indices.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
00833 extract_object_indices.filter (*cloud_objects_);
00834
00835 if (cloud_objects_->points.size () == 0)
00836 return;
00837
00838
00839 std::vector<pcl::PointIndices> clusters2;
00840 cluster_.setInputCloud (cloud_filtered_);
00841 cluster_.setIndices (boost::make_shared<const pcl::PointIndices> (cloud_object_indices));
00842 cluster_.extract (clusters2);
00843
00844 PCL_INFO ("[DominantPlaneSegmentation::compute_full()] Number of clusters found matching the given constraints: %zu.\n",
00845 clusters2.size ());
00846
00847 clusters.resize (clusters2.size ());
00848
00849 for (size_t i = 0; i < clusters2.size (); ++i)
00850 {
00851 clusters[i] = CloudPtr (new Cloud ());
00852 pcl::copyPointCloud (*cloud_filtered_, clusters2[i].indices, *clusters[i]);
00853 }
00854 }
00855
00856 #define PCL_INSTANTIATE_DominantPlaneSegmentation(T) template class PCL_EXPORTS pcl::apps::DominantPlaneSegmentation<T>;