# -*- coding: utf-8 -*- # Conditional Euclidean Clustering # http://pointclouds.org/documentation/tutorials/conditional_euclidean_clustering.php#conditional-euclidean-clustering import pcl # #include # #include # #include # #include # #include # #include typedef pcl::PointXYZI PointTypeIO; typedef pcl::PointXYZINormal PointTypeFull; bool enforceIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance) { if (fabs (point_a.intensity - point_b.intensity) < 5.0f) return (true); else return (false); } bool enforceCurvatureOrIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance) { Eigen::Map point_a_normal = point_a.normal, point_b_normal = point_b.normal; if (fabs (point_a.intensity - point_b.intensity) < 5.0f) return (true); if (fabs (point_a_normal.dot (point_b_normal)) < 0.05) return (true); return (false); } bool customRegionGrowing (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance) { Eigen::Map point_a_normal = point_a.normal, point_b_normal = point_b.normal; if (squared_distance < 10000) { if (fabs (point_a.intensity - point_b.intensity) < 8.0f) return (true); if (fabs (point_a_normal.dot (point_b_normal)) < 0.06) return (true); } else { if (fabs (point_a.intensity - point_b.intensity) < 3.0f) return (true); } return (false); } # int main (int argc, char** argv) # { # // Data containers used # pcl::PointCloud::Ptr cloud_in (new pcl::PointCloud), cloud_out (new pcl::PointCloud); # pcl::PointCloud::Ptr cloud_with_normals (new pcl::PointCloud); # pcl::IndicesClustersPtr clusters (new pcl::IndicesClusters), small_clusters (new pcl::IndicesClusters), large_clusters (new pcl::IndicesClusters); # pcl::search::KdTree::Ptr search_tree (new pcl::search::KdTree); # pcl::console::TicToc tt; # # // Load the input point cloud # std::cerr << "Loading...\n", tt.tic (); # pcl::io::loadPCDFile ("./examples/pcldata/tutorials/Statues_4.pcd", *cloud_in); # std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_in->points.size () << " points\n"; ### cloud_in = pcl.load_XYZI('./examples/pcldata/tutorials/Statues_4.pcd') # // Downsample the cloud using a Voxel Grid class # std::cerr << "Downsampling...\n", tt.tic (); # pcl::VoxelGrid vg; # vg.setInputCloud (cloud_in); # vg.setLeafSize (80.0, 80.0, 80.0); # vg.setDownsampleAllData (true); # vg.filter (*cloud_out); # std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_out->points.size () << " points\n"; ### vg = cloud_in.make_VoxelGrid() vg.set_LeafSize (80.0, 80.0, 80.0) vg.set_DownsampleAllData (True) cloud_out = vg.filter () print('>> Done: ' + tt.toc () + ' ms, ' + cloud_out.size + ' points\n') # // Set up a Normal Estimation class and merge data in cloud_with_normals # std::cerr << "Computing normals...\n", tt.tic (); # pcl::copyPointCloud (*cloud_out, *cloud_with_normals); # pcl::NormalEstimation ne; # ne.setInputCloud (cloud_out); # ne.setSearchMethod (search_tree); # ne.setRadiusSearch (300.0); # ne.compute (*cloud_with_normals); # std::cerr << ">> Done: " << tt.toc () << " ms\n"; ### ne = cloud_out.make_NormalEstimation() ne.set_SearchMethod (search_tree); ne.set_RadiusSearch (300.0) cloud_with_normals = ne.compute () print(">> Done: ' + ' ms\n') # // Set up a Conditional Euclidean Clustering class # std::cerr << "Segmenting to clusters...\n", tt.tic (); # pcl::ConditionalEuclideanClustering cec (true); # cec.setInputCloud (cloud_with_normals); # cec.setConditionFunction (&customRegionGrowing); # cec.setClusterTolerance (500.0); # cec.setMinClusterSize (cloud_with_normals->points.size () / 1000); # cec.setMaxClusterSize (cloud_with_normals->points.size () / 5); # cec.segment (*clusters); # cec.getRemovedClusters (small_clusters, large_clusters); # std::cerr << ">> Done: " << tt.toc () << " ms\n"; ### # // Using the intensity channel for lazy visualization of the output # for (int i = 0; i < small_clusters->size (); ++i) # for (int j = 0; j < (*small_clusters)[i].indices.size (); ++j) # cloud_out->points[(*small_clusters)[i].indices[j]].intensity = -2.0; # for (int i = 0; i < large_clusters->size (); ++i) # for (int j = 0; j < (*large_clusters)[i].indices.size (); ++j) # cloud_out->points[(*large_clusters)[i].indices[j]].intensity = +10.0; # for (int i = 0; i < clusters->size (); ++i) # { # int label = rand () % 8; # for (int j = 0; j < (*clusters)[i].indices.size (); ++j) # cloud_out->points[(*clusters)[i].indices[j]].intensity = label; # } ### # // Save the output point cloud # std::cerr << "Saving...\n", tt.tic (); # pcl::io::savePCDFile ("output.pcd", *cloud_out); # std::cerr << ">> Done: " << tt.toc () << " ms\n"; ###