一、概述
每个体素中选取一个点代替体素内所有的点。
1、主要函数
头文件
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
函数
PointRange::iterator CGAL::grid_simplify_point_set ( PointRange & points,
double epsilon,
const NamedParameters & np = parameters::default_values()
)
二、代码实现
1、方式一
#include <fstream>
#include <cstdlib>
#include <vector>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
int main(int argc, char* argv[])
{
// ---------------------------读取点云--------------------------------
CGAL::Point_set_3<Point_3> points;
std::string fname = CGAL::data_file_path("cgal//kitten.xyz");
std::ifstream stream(fname, std::ios_base::binary);
if (!stream)
{
std::cerr << "Error: cannot read file " << fname << std::endl;
return -1;
}
stream >> points;
if (points.empty())
{
return -1;
}
std::cout << "Read " << points.size() << " point(s)" << std::endl;
// ---------------------------体素滤波-----------------------------
auto gsim_it = CGAL::grid_simplify_point_set(points, 0.02);
points.remove(gsim_it, points.end());
std::cout << points.number_of_removed_points()
<< " point(s) removed after simplification." << std::endl;
points.collect_garbage();
return 0;
}
2、方式二
#include <vector>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/property_map.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
int main(int argc, char* argv[])
{
// ---------------------------------加载点云--------------------------------------
std::vector<Kernel::Point_3> points;
if (CGAL::IO::read_points("cgal//fin90_with_PCA_normals.xyz", std::back_inserter(points)) == -1)
{
std::cerr << "Error: cannot read file" << std::endl;
return -1;
}
std::cout << "从文件中读取" << points.size() << "个点。" << std::endl;
// ------------------------------体素滤波(返回索引)-----------------------------
std::vector<std::size_t> indices(points.size());
for (std::size_t i = 0; i < points.size(); ++i)
{
indices[i] = i;
}
double cell_size = 0.05; // 格网大小
auto end = CGAL::grid_simplify_point_set(indices, cell_size,
CGAL::parameters::point_map(CGAL::make_property_map(points)));
std::size_t k = end - indices.begin();
// 根据索引获取滤波后的点
std::vector<Kernel::Point_3> out_points(k);
for (size_t i = 0; i < k; ++i)
{
out_points[i] = points[indices[i]];
}
std::cout << "滤波后点的个数为:" << out_points.size() << std::endl;
// ----------------------------------保存结果--------------------------------
CGAL::IO::write_points("cgal//voxel.xyz", out_points, CGAL::parameters::stream_precision(6));
return 0;
}
3、方式三
#include <vector>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/property_map.h>
#include <CGAL/grid_simplify_point_set.h> // 体素滤波
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
int main(int argc, char* argv[])
{
// ------------------------------加载点云---------------------------------
std::vector<Kernel::Point_3> points;
if (CGAL::IO::read_points("cgal//CSite.xyz", std::back_inserter(points)) == -1)
{
std::cerr << "Error: cannot read file" << std::endl;
return -1;
}
std::cout << "从文件中读取" << points.size() << "个点。" << std::endl;
double gridSize = 0.2; // 体素大小
// ------------------------------体素滤波-------------------------------
points.erase(CGAL::grid_simplify_point_set(points, gridSize), points.end());
std::cout << "采样后的点:" << points.size() << std::endl;
// ------------------------------保存结果-------------------------------
CGAL::IO::write_points("cgal//CSite1_voxel.xyz", points, CGAL::parameters::stream_precision(6));
return 0;
}
三、结果展示
1、滤波前
2、滤波后