@@ -64,7 +64,7 @@ void readCloudFromFile(int argc, char** argv, std::vector<htr::Point3D>& points,
6464 if (filenames.size ()<=0 ){
6565 filenames = pcl::console::parse_file_extension_argument (argc, argv, " .xyz" );
6666 if (filenames.size ()<=0 ){
67- std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir>" << std::endl;
67+ std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir> output extension = pcd(default) " << std::endl;
6868 return std::exit (-1 );
6969 }else if (filenames.size () == 1 ){
7070 file_is_xyz = true ;
@@ -79,14 +79,14 @@ void readCloudFromFile(int argc, char** argv, std::vector<htr::Point3D>& points,
7979 else if (filenames.size () == 1 ){
8080 file_is_ply = true ;
8181 }else {
82- std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir>" << std::endl;
82+ std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir> output extension = pcd(default) " << std::endl;
8383 return std::exit (-1 );
8484 }
8585
8686 if (file_is_pcd){
8787 if (pcl::io::loadPCDFile (argv[filenames[0 ]], *cloud) < 0 ){
8888 std::cout << " Error loading point cloud " << argv[filenames[0 ]] << " \n " ;
89- std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir>" << std::endl;
89+ std::cerr << " Usage: ./dbscan <file.txt> <octree resolution> <eps> <minPtsAux> <minPts> <output dir> output extension = pcd(default) " << std::endl;
9090 return std::exit (-1 );
9191 }
9292 pcl::console::print_info (" \n Found pcd file.\n " );
@@ -219,7 +219,7 @@ void readCloudFromFile(int argc, char** argv, std::vector<htr::Point3D>& points,
219219 // calculateCentroid(points);
220220}
221221
222- void init (int argc, char ** argv,bool show){
222+ void init (int argc, char ** argv,bool show,std::string extension ){
223223
224224 std::vector<htr::Point3D> groupA;
225225 dbScanSpace::dbscan dbscan;
@@ -236,11 +236,12 @@ void init(int argc, char** argv,bool show){
236236 // ----------------------------------------------------------------
237237
238238 // ----------------------------------------------------------------
239+ double a;
239240
240241 if (not is_number (octreeResolution_str)){
241242 PCL_ERROR (" \n Error: enter a valid octree resolution\n " );
242243 std::exit (-1 );
243- }else if (not is_number (eps_str)){
244+ }else if (not is_number (eps_str) and not ( std::fmod ( std::atof (eps_str. c_str ()), 1.0 ))){
244245 PCL_ERROR (" \n Error: enter a valid epsilon\n " );
245246 std::exit (-1 ); /* VALIDATION*/
246247 }else if (not is_number (minPtsAux_str)){
@@ -300,51 +301,140 @@ void init(int argc, char** argv,bool show){
300301
301302 }
302303
303- // Save cloud_cluster_#.txt:
304+ // ----------------- Save cloud_cluster_#.txt:-------------------------//
304305
305- for ( auto & cluster : dbscan. getClusters () ){
306+ if (extension == " txt " ){
306307
307- std::string str1 = output_dir;
308- str1 += " /cloud_cluster_" ;
309- str1 += std::to_string (cont);
310- str1 += " .txt" ;
308+ for (auto & cluster : dbscan.getClusters ()){
311309
312- fout.open (str1.c_str ());
310+ std::string str1 = output_dir;
311+ str1 += " /cloud_cluster_" ;
312+ str1 += std::to_string (cont);
313+ str1 += " .txt" ;
313314
314- for ( auto & point:cluster. clusterPoints ){
315+ fout. open (str1. c_str ());
315316
316- uint32_t rgb_ = *reinterpret_cast <int *>(&point.rgb );
317- uint8_t r_, g_, b_;
317+ for (auto & point:cluster.clusterPoints ){
318318
319- r_ = (rgb_ >> 16 ) & 0x0000ff ;
320- g_ = (rgb_ >> 8 ) & 0x0000ff ;
321- b_ = (rgb_) & 0x0000ff ;
319+ uint32_t rgb_ = *reinterpret_cast <int *>(&point.rgb );
320+ uint8_t r_, g_, b_;
322321
323- unsigned int r, g, b;
324- r = *((uint8_t *) &r_);
325- g = *((uint8_t *) &g_);
326- b = *((uint8_t *) &b_);
327-
328- fout << point.x << " " << point.y << " " << point.z << " " << r << " " << g << " " << b << std::endl;
329-
330- }
322+ r_ = (rgb_ >> 16 ) & 0x0000ff ;
323+ g_ = (rgb_ >> 8 ) & 0x0000ff ;
324+ b_ = (rgb_) & 0x0000ff ;
331325
332- fout.close ();
333- cont +=1 ;
334- }
326+ unsigned int r, g, b;
327+ r = *((uint8_t *) &r_);
328+ g = *((uint8_t *) &g_);
329+ b = *((uint8_t *) &b_);
330+
331+ fout << point.x << " " << point.y << " " << point.z << " " << r << " " << g << " " << b << std::endl;
332+
333+ }
334+
335+ fout.close ();
336+ cont +=1 ;
337+ }
335338
336- ofstream fout2;
339+ /* ofstream fout2;
337340 std::string str2 = output_dir;
338341 str2 += "/clusters_number.txt";
339342 fout2.open(str2.c_str());
340343 fout2 << cont << std::endl;
341- fout2.close ();
344+ fout2.close();*/
345+
346+ }else if (extension == " pcd" ){
347+
348+ for (auto & cluster : dbscan.getClusters ()){
349+
350+ std::string str1 = output_dir;
351+ str1 += " /cloud_cluster_" ;
352+ str1 += std::to_string (cont);
353+ str1 += " .pcd" ;
354+
355+ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster_pcd (new pcl::PointCloud<pcl::PointXYZRGB>());
356+
357+ for (auto & point:cluster.clusterPoints ){
358+
359+ pcl::PointXYZRGB pt;
360+
361+ pt.x = point.x ;
362+ pt.y = point.y ;
363+ pt.z = point.z ;
364+
365+ pt.r = point.r ;
366+ pt.g = point.g ;
367+ pt.b = point.b ;
368+
369+ cloud_cluster_pcd->points .push_back (pt);
370+ }
371+
372+ pcl::io::savePCDFileBinary (str1.c_str (), *cloud_cluster_pcd);
373+ cont +=1 ;
374+ }
375+
376+ }else if (extension == " ply" ){
377+
378+ for (auto & cluster : dbscan.getClusters ()){
379+
380+ std::string str1 = output_dir;
381+ str1 += " /cloud_cluster_" ;
382+ str1 += std::to_string (cont);
383+ str1 += " .ply" ;
384+
385+ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster_ply (new pcl::PointCloud<pcl::PointXYZRGB>());
386+
387+ for (auto & point:cluster.clusterPoints ){
388+
389+ pcl::PointXYZRGB pt;
390+
391+ pt.x = point.x ;
392+ pt.y = point.y ;
393+ pt.z = point.z ;
394+
395+ pt.r = point.r ;
396+ pt.g = point.g ;
397+ pt.b = point.b ;
398+
399+ cloud_cluster_ply->points .push_back (pt);
400+ }
401+
402+ pcl::PLYWriter writer;
403+ writer.write (str1.c_str (), *cloud_cluster_ply, false , false );
404+ cont +=1 ;
405+ }
406+
407+ }else if (extension == " xyz" ){
408+
409+ for (auto & cluster : dbscan.getClusters ()){
410+
411+ std::string str1 = output_dir;
412+ str1 += " /cloud_cluster_" ;
413+ str1 += std::to_string (cont);
414+ str1 += " .xyz" ;
415+
416+ fout.open (str1.c_str ());
417+
418+ for (auto & point:cluster.clusterPoints ){
419+
420+ fout << point.x << " " << point.y << " " << point.z << std::endl;
421+
422+ }
423+
424+ fout.close ();
425+ cont +=1 ;
426+ }
427+ }
428+
429+ // -------------------------------------------------------------------//
342430
343431 end = std::chrono::system_clock::now ();
344432
345433 std::chrono::duration<double > elapsed_seconds = end-start;
346434 std::cout << " \n elapsed time: " << elapsed_seconds.count () << " s\n " ;
347435
436+ // -----------------Visualize clusters pcl-visualizer-----------------//
437+
348438 if (show){
349439
350440 // std::cout << "\nPrinting clusters..." << std::endl;
@@ -461,20 +551,41 @@ void init(int argc, char** argv,bool show){
461551
462552int main (int argc, char ** argv){
463553
464- if (argc < 7 or argc > 7 ){
554+ if (argc < 7 or argc > 8 ){
465555
466- std::cerr << " Usage: ./dbscan <file.ply> <octree resolution> <eps> <minPts aux> <minPts> <output dir>" << std::endl;
556+ std::cerr << " Usage: ./dbscan <file.ply> <octree resolution> <eps> <minPts aux> <minPts> <output dir> <output extension = pcd(default)> " << std::endl;
467557 std::cerr << " Support: ply - pcd - txt - xyz" << std::endl;
468558 return -1 ;
469559 }
470-
471- std::cout << " \n *************************************" << std::endl;
472- std::cout << " *** DBSCAN Cluster Segmentation *** " << std::endl;
473- std::cout << " *************************************" << std::endl;
474-
475- bool showClusters = true ;
476560
477- init (argc,argv,showClusters);
561+ std::string extension;
562+
563+ if (argc == 7 ){
564+ extension = " pcd" ;
565+ }else {
566+
567+ std::string temp = argv[7 ];
568+
569+ if (temp == " ply" ){
570+ extension = " ply" ;
571+ }else if (temp == " txt" ){
572+ extension = " txt" ;
573+ }else if (temp == " xyz" ){
574+ extension = " xyz" ;
575+ }else {
576+ std::cout << " output extension must be: ply, txt or xyz (default=pcd)" << std::endl;
577+ std::exit (-1 );
578+ }
579+ }
580+
581+ std::cout << " \n *************************************" << std::endl;
582+ std::cout << " *** DBSCAN Cluster Segmentation *** " << std::endl;
583+ std::cout << " *************************************" << std::endl;
584+
585+ bool showClusters = true ;
586+
587+ init (argc,argv,showClusters,extension);
588+
589+ return 0 ;
478590
479- return 0 ;
480591}
0 commit comments