CGAL学习记录——Geometry Processing(几何处理)-Point Set Processing -1

功能实现

链接: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> // defines std::pair
#include <vector>
#include <fstream>
#include <iostream>

# include <CGAL/Point_set_3.h>

// types
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>
// Types
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
// Data type := index, followed by the point, followed by three integers that
// define the Red Green Blue color of the 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; // set index value of tuple to i
        points[i].get<2>() = 0; // set RGB color to black
        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>()));
    //CGAL::IO::write_OFF("copy_off.off",points, CGAL::parameters::point_map(CGAL::Nth_of_tuple_property_map<1, IndexedPointWithColorTuple>()));
   // CGAL::IO::write_points("copy.xyz", points, CGAL::parameters::point_map(CGAL::Nth_of_tuple_property_map<1, IndexedPointWithColorTuple>()));

    //计算平均距离
    const unsigned int nb_neighbors = 6; // 1 ring
    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; // 1 ring
    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>
// Concurrency
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
// Types
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;
    // read input
    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;
    }
    // estimate k scale
    task_timer.start();
    std::size_t k_scale = CGAL::estimate_global_k_neighbor_scale(points);
    task_timer.stop();
    // Example: use estimated k as scale for jet smoothing
    CGAL::jet_smooth_point_set<Concurrency_tag>(points, static_cast<unsigned int>(k_scale));

    CGAL::IO::write_points("knn.xyz",points);


    // estimate range scale
    task_timer.start();
    FT range_scale = CGAL::estimate_global_range_scale(points);
    task_timer.stop();
    // Example: use estimated range for grid simplification
    points.erase(CGAL::grid_simplify_point_set(points, range_scale), points.end());

    CGAL::IO::write_points("rnn.xyz", points);
    // print some informations on runtime
    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;
}

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片