一、算法原理
二维点集的边界提取。
1、主要函数
头文件
#include <CGAL/Alpha_shape_2.h>
2、参考文献
[1]张鹤,李东升,陈爱军.Alpha-Shapes分段改进算法在三维模拟树枝体积扫描测量中的应用[J].中国测试,2021,47(03):49-58.
二、代码实现
#include <vector>
#include <pcl/io/pcd_io.h> // PCL读取PCD
#include <pcl/point_types.h> // PCL点类型
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Alpha_shape_2.h>
#include <CGAL/Alpha_shape_vertex_base_2.h>
#include <CGAL/Alpha_shape_face_base_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/algorithm.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_2 Point;
typedef K::Segment_2 Segment;
typedef CGAL::Alpha_shape_vertex_base_2<K> Vb;
typedef CGAL::Alpha_shape_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Triangulation_2;
typedef CGAL::Alpha_shape_2<Triangulation_2> Alpha_shape_2;
typedef Alpha_shape_2::Alpha_shape_edges_iterator Alpha_shape_edges_iterator;
template <class OutputIterator>
void alpha_edges(const Alpha_shape_2& A, OutputIterator out)
{
Alpha_shape_edges_iterator it = A.alpha_shape_edges_begin(),
end = A.alpha_shape_edges_end();
for (; it != end; ++it)
*out++ = A.segment(*it);
}
int main()
{
//-------------------------加载二维PCD点云数据------------------------------
pcl::PointCloud<pcl::PointXY>::Ptr cloud(new pcl::PointCloud<pcl::PointXY>);
if (pcl::io::loadPCDFile<pcl::PointXY>("cgal//cloud.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
return -1;
}
// ------------------------转为CGAL支持的格式------------------------------
std::vector<Point> points;
for (size_t i = 0; i < cloud->size(); ++i)
{
double px = cloud->points[i].x;
double py = cloud->points[i].y;
points.push_back(Point(px, py));
}
Alpha_shape_2 A(points.begin(), points.end(),
FT(10000),
Alpha_shape_2::GENERAL);
std::vector<Segment> segments;
alpha_edges(A, std::back_inserter(segments));
std::cout << "Alpha Shape computed" << std::endl;
std::cout << segments.size() << " alpha shape edges" << std::endl;
std::cout << "Optimal alpha: " << *A.find_optimal_alpha(1) << std::endl;
// -----------------------------保存点云-------------------------------
const std::string output_filename("cgal//CSite_random.xyz");
if (!CGAL::IO::write_points(output_filename, segments, CGAL::parameters::stream_precision(17)))
return -1;
return 0;
}