int main(int argc, char** argv) { // initialize PointClouds pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr final (new pcl::PointCloud<pcl::PointXYZ>); // populate our PointCloud with points cloud->width = 500; cloud->height = 1; cloud->is_dense = false; cloud->points.resize (cloud->width * cloud->height); for (size_t i = 0; i < cloud->points.size (); ++i) { if (pcl::console::find_argument (argc, argv, "-s") >= 0 || pcl::console::find_argument (argc, argv, "-sf") >= 0) { cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0); if (i % 5 == 0) cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0); else if(i % 2 == 0) cloud->points[i].z = sqrt( 1 - (cloud->points[i].x * cloud->points[i].x) - (cloud->points[i].y * cloud->points[i].y)); else cloud->points[i].z = - sqrt( 1 - (cloud->points[i].x * cloud->points[i].x) - (cloud->points[i].y * cloud->points[i].y)); } else { cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0); if( i % 2 == 0) cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0); else cloud->points[i].z = -1 * (cloud->points[i].x + cloud->points[i].y); } } std::vector<int> inliers; // created RandomSampleConsensus object and compute the appropriated model pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (cloud)); pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr model_p (new pcl::SampleConsensusModelPlane<pcl::PointXYZ> (cloud)); if(pcl::console::find_argument (argc, argv, "-f") >= 0) { pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_p); ransac.setDistanceThreshold (.01); ransac.computeModel(); ransac.getInliers(inliers); } else if (pcl::console::find_argument (argc, argv, "-sf") >= 0 ) { pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s); ransac.setDistanceThreshold (.01); ransac.computeModel(); ransac.getInliers(inliers); } // copies all inliers of the model computed to another PointCloud pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final); // creates the visualization object and adds either our orignial cloud or all of the inliers // depending on the command line arguments specified. boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer; if (pcl::console::find_argument (argc, argv, "-f") >= 0 || pcl::console::find_argument (argc, argv, "-sf") >= 0) viewer = simpleVis(final); else
int main(int argc, char** argv) { //check if number of arguments is proper if(argc!=3){ help(); exit(0); } // initialize PointClouds pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr final(new pcl::PointCloud<pcl::PointXYZ>); if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) == -1) //* load the file { cerr << "Couldn't read file :" << argv[1] << "\n"; return (-1); } std::vector<int> inliers; // created RandomSampleConsensus object and compute the appropriated model pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud)); pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr model_p(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud)); //RANSAC for Line model pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<PointT>()); if (pcl::console::find_argument(argc, argv, "-l") >= 0) { pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients); pcl::PointIndices::Ptr inliers_l(new pcl::PointIndices); // Create the segmentation object pcl::SACSegmentation<pcl::PointXYZ> seg; // Optional seg.setOptimizeCoefficients(true); // Mandatory seg.setModelType(pcl::SACMODEL_LINE); seg.setMethodType(pcl::SAC_RANSAC); seg.setDistanceThreshold(0.05); seg.setInputCloud(cloud); seg.segment(*inliers_l, *coefficients); // Write the line inliers to disk pcl::ExtractIndices<PointT> extract; extract.setInputCloud(cloud); extract.setIndices(inliers_l); extract.setNegative(false); extract.filter(*cloud_line); } if (pcl::console::find_argument(argc, argv, "-f") >= 0) { //RANSAC for Plane model pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_p); ransac.setDistanceThreshold(.01); ransac.computeModel(); ransac.getInliers(inliers); } else if (pcl::console::find_argument(argc, argv, "-sf") >= 0) { //RANSAC for Sphere model pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_s); ransac.setDistanceThreshold(.01); ransac.computeModel(); ransac.getInliers(inliers); } // copies all inliers of the model computed to another PointCloud pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final); // creates the visualization object and adds either our orignial cloud or all of the inliers // depending on the command line arguments specified. boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer; if (pcl::console::find_argument(argc, argv, "-f") >= 0 || pcl::console::find_argument(argc, argv, "-sf") >= 0) { viewer = simpleVis(final); } else if (pcl::console::find_argument(argc, argv, "-l") >= 0) {
void callback(const sensor_msgs::PointCloud2::ConstPtr& cloud) { ros::Time whole_start = ros::Time::now(); ros::Time declare_types_start = ros::Time::now(); // filter pcl::VoxelGrid<sensor_msgs::PointCloud2> voxel_grid; pcl::PassThrough<sensor_msgs::PointCloud2> pass; pcl::ExtractIndices<pcl::PointXYZ> extract_indices; // Create the segmentation object pcl::SACSegmentation<pcl::PointXYZ> seg; std::vector<int> inliers; // The plane and sphere coefficients pcl::ModelCoefficients::Ptr coefficients_sphere (new pcl::ModelCoefficients ()); // The plane and sphere inliers pcl::PointIndices::Ptr inliers_sphere (new pcl::PointIndices ()); // The point clouds sensor_msgs::PointCloud2::Ptr voxelgrid_filtered (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr passthrough_filtered (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr sphere_output_cloud (new sensor_msgs::PointCloud2); // The PointCloud pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_output (new pcl::PointCloud<pcl::PointXYZ>); ros::Time declare_types_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * Create Voxel grid Filtering */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // voxel_grid.setInputCloud (cloud); // voxel_grid.setLeafSize (0.01, 0.01, 0.01); // voxel_grid.filter (*voxelgrid_filtered); // // // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud // pcl::fromROSMsg (*voxelgrid_filtered, *transformed_cloud); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * Pass through Filtering */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time pass_start = ros::Time::now(); pass.setInputCloud (cloud); pass.setFilterFieldName ("z"); pass.setFilterLimits (0, 3.5); pass.filter (*passthrough_filtered); pass.setInputCloud (passthrough_filtered); pass.setFilterFieldName ("y"); pass.setFilterLimits (-0.1, 0.3); pass.filter (*passthrough_filtered); passthrough_pub.publish(passthrough_filtered); ros::Time pass_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * for sphere features */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud pcl::fromROSMsg (*passthrough_filtered, *sphere_cloud); ros::Time sphere_start = ros::Time::now(); // created RandomSampleConsensus object and compute the appropriated model pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (sphere_cloud)); pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s); ransac.setDistanceThreshold (.01); ransac.computeModel(); ransac.getInliers(inliers); // copies all inliers of the model computed to another PointCloud pcl::copyPointCloud<pcl::PointXYZ>(*sphere_cloud, inliers, *sphere_output); pcl::toROSMsg (*sphere_output, *sphere_output_cloud); sphere_pub.publish(sphere_output_cloud); // // Optional // seg.setOptimizeCoefficients (true); // // Mandatory // seg.setModelType (pcl::SACMODEL_SPHERE); // seg.setMethodType (pcl::SAC_RANSAC); // seg.setMaxIterations (10000); // seg.setDistanceThreshold (0.05); // seg.setRadiusLimits (0, 0.15); // seg.setInputCloud (sphere_cloud); // seg.segment (*inliers_sphere, *coefficients_sphere); // //std::cerr << "Sphere coefficients: " << *coefficients_sphere << std::endl; // // // extract_indices.setInputCloud(sphere_cloud); // extract_indices.setIndices(inliers_sphere); // extract_indices.setNegative(false); // extract_indices.filter(*sphere_output); // // if (sphere_output->points.empty ()) // std::cerr << "Can't find the sphere component." << std::endl; // // pcl::toROSMsg (*sphere_output, *sphere_output_cloud); // sphere_pub.publish(sphere_output_cloud); ros::Time sphere_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * visualize normals */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // pcl::visualization::PCLVisualizer viewer("PCL Viewer"); // viewer.setBackgroundColor (0.0, 0.0, 0.5); // viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(sphere_cloud, cloud_normals3); // viewer.spin(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time whole_end = ros::Time::now(); std::cout << "cloud size : " << cloud->width * cloud->height << std::endl; std::cout << "pass_th size : " << passthrough_filtered->width * passthrough_filtered->height << std::endl; std::cout << "sphere size : " << sphere_output_cloud->width * sphere_output_cloud->height << std::endl; printf("\n"); std::cout << "whole time : " << whole_end - whole_start << " sec" << std::endl; std::cout << "declare types time : " << declare_types_end - declare_types_start << " sec" << std::endl; std::cout << "passthrough time : " << pass_end - pass_start << " sec" << std::endl; std::cout << "sphere time : " << sphere_end - sphere_start << " sec" << std::endl; printf("\n----------------------------------------------------------------------------\n"); printf("\n"); }
void callback(const sensor_msgs::PointCloud2::ConstPtr& cloud) { ros::Time whole_start = ros::Time::now(); ros::Time declare_types_start = ros::Time::now(); // filter pcl::VoxelGrid<sensor_msgs::PointCloud2> voxel_grid; pcl::PassThrough<sensor_msgs::PointCloud2> pass; pcl::ExtractIndices<pcl::PointXYZ> extract_indices; pcl::ExtractIndices<pcl::PointXYZ> extract_indices2; // Create the segmentation object pcl::SACSegmentation<pcl::PointXYZ> seg; // The plane and sphere coefficients pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients ()); pcl::ModelCoefficients::Ptr coefficients_sphere (new pcl::ModelCoefficients ()); // The plane and sphere inliers pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices ()); pcl::PointIndices::Ptr inliers_sphere (new pcl::PointIndices ()); // The point clouds sensor_msgs::PointCloud2::Ptr passthrough_filtered (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr plane_seg_output_cloud (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr sphere_RANSAC_output_cloud (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr rest_whole_cloud (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr rest_cloud_filtered (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr sphere_output_cloud (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr whole_pc (new sensor_msgs::PointCloud2); sensor_msgs::PointCloud2::Ptr ball_candidate_output_cloud (new sensor_msgs::PointCloud2); // The PointCloud pcl::PointCloud<pcl::PointXYZ>::Ptr plane_seg_cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr plane_seg_output (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr remove_plane_cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_output (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_RANSAC_output (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr remove_false_ball_candidate (new pcl::PointCloud<pcl::PointXYZ>); std::vector<int> inliers; ros::Time declare_types_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * Pass through Filtering */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time pass_start = ros::Time::now(); pass.setInputCloud (cloud); pass.setFilterFieldName ("z"); pass.setFilterLimits (0, 2.5); pass.filter (*passthrough_filtered); passthrough_pub.publish(passthrough_filtered); ros::Time pass_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * for plane features pcl::SACSegmentation */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time plane_seg_start = ros::Time::now(); // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud pcl::fromROSMsg (*passthrough_filtered, *plane_seg_cloud); // Optional seg.setOptimizeCoefficients (true); seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE); seg.setMethodType (pcl::SAC_RANSAC); seg.setAxis(Eigen::Vector3f (0, -1, 0)); // best plane should be perpendicular to z-axis seg.setMaxIterations (40); seg.setDistanceThreshold (0.05); seg.setInputCloud (plane_seg_cloud); seg.segment (*inliers_plane, *coefficients_plane); extract_indices.setInputCloud(plane_seg_cloud); extract_indices.setIndices(inliers_plane); extract_indices.setNegative(false); extract_indices.filter(*plane_seg_output); pcl::toROSMsg (*plane_seg_output, *plane_seg_output_cloud); plane_pub.publish(plane_seg_output_cloud); ros::Time plane_seg_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * Extract rest plane and passthrough filtering */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time rest_pass_start = ros::Time::now(); // Create the filtering object // Remove the planar inliers, extract the rest extract_indices.setNegative (true); extract_indices.filter (*remove_plane_cloud); plane_seg_cloud.swap (remove_plane_cloud); // publish result of Removal the planar inliers, extract the rest pcl::toROSMsg (*plane_seg_cloud, *rest_whole_cloud); rest_whole_pub.publish(rest_whole_cloud); // 'rest_whole_cloud' substituted whole_pc ros::Time rest_pass_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time find_ball_start = ros::Time::now(); int iter = 0; while(iter < 5) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * for sphere features pcl::SACSegmentation */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud pcl::fromROSMsg (*rest_whole_cloud, *sphere_cloud); ros::Time sphere_start = ros::Time::now(); // Optional seg.setOptimizeCoefficients (false); // Mandatory seg.setModelType (pcl::SACMODEL_SPHERE); seg.setMethodType (pcl::SAC_RANSAC); seg.setMaxIterations (10000); seg.setDistanceThreshold (0.03); seg.setRadiusLimits (0.12, 0.16); seg.setInputCloud (sphere_cloud); seg.segment (*inliers_sphere, *coefficients_sphere); //std::cerr << "Sphere coefficients: " << *coefficients_sphere << std::endl; if (inliers_sphere->indices.empty()) std::cerr << "[[--Can't find the Sphere Candidate.--]]" << std::endl; else { extract_indices.setInputCloud(sphere_cloud); extract_indices.setIndices(inliers_sphere); extract_indices.setNegative(false); extract_indices.filter(*sphere_output); pcl::toROSMsg (*sphere_output, *sphere_output_cloud); sphere_seg_pub.publish(sphere_output_cloud); // 'sphere_output_cloud' means ball candidate point cloud } ros::Time sphere_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * for sphere features pcl::SampleConsensusModelSphere */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time sphere_RANSAC_start = ros::Time::now(); // created RandomSampleConsensus object and compute the appropriated model pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (sphere_output)); pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s); ransac.setDistanceThreshold (.01); ransac.computeModel(); ransac.getInliers(inliers); // copies all inliers of the model computed to another PointCloud pcl::copyPointCloud<pcl::PointXYZ>(*sphere_output, inliers, *sphere_RANSAC_output); pcl::toROSMsg (*sphere_RANSAC_output, *sphere_RANSAC_output_cloud); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * To discriminate a ball */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// double w = 0; w = double(sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height) /double(sphere_output_cloud->width * sphere_output_cloud->height); if (w > 0.9) { BALL = true; std::cout << "can find a ball" << std::endl; true_ball_pub.publish(sphere_RANSAC_output_cloud); break; } else { BALL = false; std::cout << "can not find a ball" << std::endl; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * Exclude false ball candidate */ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ros::Time rest_pass_start = ros::Time::now(); // Create the filtering object // Remove the planar inliers, extract the rest extract_indices2.setInputCloud(plane_seg_cloud); extract_indices2.setIndices(inliers_sphere); extract_indices2.setNegative (true); extract_indices2.filter (*remove_false_ball_candidate); sphere_RANSAC_output.swap (remove_false_ball_candidate); // publish result of Removal the planar inliers, extract the rest pcl::toROSMsg (*sphere_RANSAC_output, *ball_candidate_output_cloud); rest_ball_candidate_pub.publish(ball_candidate_output_cloud); rest_whole_cloud = ball_candidate_output_cloud; } iter++; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time sphere_RANSAC_end = ros::Time::now(); } ros::Time find_ball_end = ros::Time::now(); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ros::Time whole_end = ros::Time::now(); std::cout << "cloud size : " << cloud->width * cloud->height << std::endl; std::cout << "plane size : " << plane_seg_output_cloud->width * plane_seg_output_cloud->height << std::endl; std::cout << "rest size : " << rest_whole_cloud->width * rest_whole_cloud->height << std::endl; std::cout << "sphere size : " << sphere_output_cloud->width * sphere_output_cloud->height << std::endl; std::cout << "sphere RANSAC size : " << sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height << " " << sphere_RANSAC_output->points.size() << std::endl; std::cout << "sphereness : " << double(sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height) /double(sphere_output_cloud->width * sphere_output_cloud->height) << std::endl; std::cout << "model coefficient : " << coefficients_plane->values[0] << " " << coefficients_plane->values[1] << " " << coefficients_plane->values[2] << " " << coefficients_plane->values[3] << " " << std::endl; printf("\n"); std::cout << "whole time : " << whole_end - whole_start << " sec" << std::endl; std::cout << "declare types time : " << declare_types_end - declare_types_start << " sec" << std::endl; std::cout << "passthrough time : " << pass_end - pass_start << " sec" << std::endl; std::cout << "plane time : " << plane_seg_end - plane_seg_start << " sec" << std::endl; std::cout << "rest and pass time : " << rest_pass_end - rest_pass_start << " sec" << std::endl; std::cout << "find a ball time : " << find_ball_end - find_ball_start << " sec" << std::endl; //std::cout << "sphere time : " << sphere_end - sphere_start << " sec" << std::endl; //std::cout << "sphere ransac time : " << sphere_RANSAC_end - sphere_RANSAC_start << " sec" << std::endl; printf("\n----------------------------------------------------------------------------\n"); printf("\n"); }