功能实现
链接:CGAL中点云处理
主要时CGAL网格处理库中处理点云部分,今天学习记录一下;
代码实现:
2、点云体素采样(indices)
这样实现其实蛮复杂的,可能CGAL官方文档这一块主要说明其可以添加不同属性等。其主要实现代码只要grid_simplify_point_set() 即可。
grid_simplify_indices
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/property_map.h>
#include <vector>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
int main(int argc, char** argv)
{
std::vector<Point> points;
std::vector<Vector> normals;
std::ifstream stream(argv[1]);
Point p;
Vector v;
while (stream >> p >> v)
{
points.push_back(p);
normals.push_back(v);
}
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;
}
std::vector<std::size_t>::iterator end;
end = CGAL::grid_simplify_point_set(indices,0.05,CGAL::parameters::point_map(CGAL::make_property_map(points)));
std::size_t k = end - indices.begin();
std::cerr << "Keep" << k <<"points" << std::endl;
{
std::vector<Point>tmp_points(k);
std::vector<Vector> tmp_normals(k);
for (std::size_t i = 0; i < k; i++)
{
tmp_points[i] = points[indices[i]];
tmp_normals[i] = normals[indices[i]];
}
points.swap(tmp_points);
normals.swap(tmp_normals);
}
std::cout << "体素滤波后点的个数" << points.size() << std::endl;
system("pause");
return 0;
}
3、输入、输出(可以参考官方文档)
读取保存XYZ格式点云
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/property_map.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_xyz_points.h>
#include <utility>
#include <vector>
#include <fstream>
#include <iostream>
# include <CGAL/Point_set_3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
typedef std::pair<Point, Vector> Pwn;
int main(int argc, char* argv[])
{
const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("test.xyz");
std::vector<Pwn> points;
if (!CGAL::IO::read_XYZ(fname,
std::back_inserter(points),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>())
.normal_map(CGAL::Second_of_pair_property_map<Pwn>())))
{
std::cerr << "Error: cannot read file " << fname << std::endl;
return EXIT_FAILURE;
}
if (!CGAL::IO::write_XYZ("test_copy.xyz", points,
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>())
.normal_map(CGAL::Second_of_pair_property_map<Pwn>())
.stream_precision(17)))
return EXIT_FAILURE;
Point_set cloud;
CGAL::IO::read_XYZ(argv[1], cloud);
CGAL::IO::write_XYZ("test_copy",cloud, CGAL::parameters::stream_precision(17));
return EXIT_SUCCESS;
}
4 、点云平均距离求解
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <vector>
#include <fstream>
#include <boost/tuple/tuple.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef boost::tuple<int, Point, int, int, int> IndexedPointWithColorTuple;
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
int main(int argc, char* argv[])
{
const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("test.xyz");
std::vector<IndexedPointWithColorTuple> points;
if (!CGAL::IO::read_points(fname, std::back_inserter(points),
CGAL::parameters::point_map(CGAL::Nth_of_tuple_property_map<1, IndexedPointWithColorTuple>())))
{
std::cerr << "Error: cannot read file " << fname << std::endl;
return EXIT_FAILURE;
}
for (unsigned int i = 0; i < points.size(); i++)
{
points[i].get<0>() = i;
points[i].get<2>() = 0;
points[i].get<3>() = 0;
points[i].get<4>() = 0;
}
CGAL::IO::write_XYZ("copy_xyz.xyz", points, CGAL::parameters::point_map(CGAL::Nth_of_tuple_property_map<1, IndexedPointWithColorTuple>()));
const unsigned int nb_neighbors = 6;
FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(
points, nb_neighbors,
CGAL::parameters::point_map(CGAL::Nth_of_tuple_property_map<1, IndexedPointWithColorTuple>()));
std::cout << "Average spacing: " << average_spacing << std::endl;
return EXIT_SUCCESS;
}
//上述代码太繁琐,可以直接简化,如下
Point_set cloud;
CGAL::IO::read_XYZ(argv[1],cloud);
CGAL::IO::write_XYZ("copy_xyz.xyz", cloud);
const unsigned int nb_neighbors = 6;
FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(cloud, nb_neighbors, CGAL::parameters::point_map(cloud.point_map()));
std::cout << "Average spacing: " << average_spacing << std::endl;
return EXIT_SUCCESS;
5.1 估计全局k邻域与R邻域
利用k邻域平滑点云,用R邻域体素采样
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <CGAL/estimate_scale.h>
#include <CGAL/jet_smooth_point_set.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <vector>
#include <fstream>
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point_3;
int main(int argc, char** argv)
{
const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("test.xyz");
CGAL::Timer task_timer;
std::vector<Point_3> points;
if (!CGAL::IO::read_points(fname, std::back_inserter(points)))
{
std::cerr << "Error: can't read input file" << std::endl;
return EXIT_FAILURE;
}
task_timer.start();
std::size_t k_scale = CGAL::estimate_global_k_neighbor_scale(points);
task_timer.stop();
CGAL::jet_smooth_point_set<Concurrency_tag>(points, static_cast<unsigned int>(k_scale));
CGAL::IO::write_points("knn.xyz",points);
task_timer.start();
FT range_scale = CGAL::estimate_global_range_scale(points);
task_timer.stop();
points.erase(CGAL::grid_simplify_point_set(points, range_scale), points.end());
CGAL::IO::write_points("rnn.xyz", points);
std::size_t memory = CGAL::Memory_sizer().virtual_size();
double time = task_timer.time();
std::cout << "Scales computed in " << time << " second(s) using "
<< (memory >> 20) << " MiB of memory:" << std::endl;
std::cout << " * Global K scale: " << k_scale << std::endl;
std::cout << " * Global range scale: " << range_scale << std::endl;
return EXIT_SUCCESS;
}
|