CGAL学习记录——多种几何形状同时检测

2023-07-08 14:50:41 浏览数 (2)

代码语言:javascript复制
#include <fstream>
#include <iostream>
#include <CGAL/Point_set_3.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/Point_with_normal_3.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
// Type declarations.
typedef CGAL::Exact_predicates_inexact_constructions_kernel  Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::FT                                           FT;
typedef std::pair<Kernel::Point_3, Kernel::Vector_3>         Point_with_normal;
typedef std::vector<Point_with_normal>                       Pwn_vector;
typedef CGAL::First_of_pair_property_map<Point_with_normal>  Point_map;
typedef CGAL::Second_of_pair_property_map<Point_with_normal> Normal_map;
typedef CGAL::Shape_detection::Efficient_RANSAC_traits
<Kernel, Pwn_vector, Point_map, Normal_map>             Traits;
typedef CGAL::Shape_detection::Efficient_RANSAC<Traits> Efficient_ransac;
typedef CGAL::Shape_detection::Cone<Traits>             Cone;
typedef CGAL::Shape_detection::Cylinder<Traits>         Cylinder;
typedef CGAL::Shape_detection::Plane<Traits>            Plane;
typedef CGAL::Shape_detection::Sphere<Traits>           Sphere;
typedef CGAL::Shape_detection::Torus<Traits>            Torus;
typedef CGAL::Point_set_3<Kernel::Point_3> Point_set;

int main(int argc, char** argv) {
    
    //加载点云
    Pwn_vector points;
    if (!CGAL::IO::read_points(((argc > 1) ? argv[1] : CGAL::data_file_path("data/test.xyz")),
        std::back_inserter(points), CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()))) 
    {
        std::cerr << "Error: cannot read file cube.pwn!" << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << points.size() << " points" << std::endl;
  

    //形状检测
    Efficient_ransac ransac;
    ransac.set_input(points);
    ransac.add_shape_factory<Plane>();
    ransac.add_shape_factory<Sphere>();
    ransac.add_shape_factory<Cylinder>();
    ransac.add_shape_factory<Cone>();
    ransac.add_shape_factory<Torus>();

    // 参数设置
    Efficient_ransac::Parameters parameters;
    
    parameters.probability = 0.05;
    parameters.min_points = 200;//最小点数
    parameters.epsilon = 0.002;
    parameters.cluster_epsilon = 0.01;
    parameters.normal_threshold = 0.9;

    
    ransac.detect(parameters);


    // 输出相关信息
    std::cout << ransac.shapes().end() - ransac.shapes().begin()<< " detected shapes, "<< ransac.number_of_unassigned_points()<< " unassigned points." << std::endl;

    //保存
    Efficient_ransac::Shape_range shapes = ransac.shapes();
    Efficient_ransac::Shape_range::iterator it = shapes.begin();
    int count = 0;
    while (it != shapes.end()) {
        if (Plane* plane = dynamic_cast<Plane*>(it->get())) {

                int num = (*it)->indices_of_assigned_points().size();
                Point_set cloud;
                for (int i = 0; i < num; i  )
                {
                    Point temp=points[(*it)->indices_of_assigned_points()[i]].first;
                    cloud.insert(temp);
                }
                CGAL::IO::write_OFF(std::to_string(count) "plane.off",cloud);
                cloud.clear();
         
        }
        else if (Cylinder* cyl = dynamic_cast<Cylinder*>(it->get())) {

            int num = (*it)->indices_of_assigned_points().size();
            Point_set cloud;
            for (int i = 0; i < num; i  )
            {
                Point temp = points[(*it)->indices_of_assigned_points()[i]].first;
                cloud.insert(temp);
            }

            CGAL::IO::write_OFF(std::to_string(count)   "cylinder.off", cloud);
            cloud.clear();
        }
        else {
            std::cout << (*it)->info() << std::endl;
        }
     
        it  ;
        count  ;
    }
    return EXIT_SUCCESS;
}

0 人点赞