CGAL学习之路(三):CGAL读写点云

1 CGAL创建点云

1.1 insert方式

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));

	cout << "->点云的点数为:" << point_set.size() << endl;

	return 0;
}

输出结果:

->点云的点数为:3

1.2 迭代器方式

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	Point_set point_set;							//创建一个三维点云容器
	//迭代器方式插入每一点坐标
	point_set.resize(3);							//设置容器大小
	Point_set::iterator it = point_set.begin();		//设置迭代器初始位置
	point_set.point(*it + 0) = Point(1, 2, 3);
	point_set.point(*it + 1) = Point(4, 5, 6);
	point_set.point(*it + 2) = Point(7, 8, 9);

	cout << "->点云的点数为:" << point_set.size() << endl;

	return 0;
}

输出结果:

->点云的点数为:3

2 CGAL读点云

2.1 读取XYZ点云

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	Point_set point_set;		//创建一个三维点云容器
	if (!CGAL::IO::read_XYZ("oni.xyz", point_set))
	{
    
    
		cerr << "\a->点云文件不存在!\n" << endl;
		return -1;
	}
	cout << "->加载点云的点数:" << point_set.size() << endl;

	return 0;
}

输出结果:

->加载点云的点数:1435

2.2 读取PLY点云

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	Point_set point_set;		//创建一个三维点云容器
	if (!CGAL::IO::read_PLY("oni.ply", point_set))
	{
    
    
		cerr << "\a->点云文件不存在!\n" << endl;
		return -1;
	}
	cout << "->加载点云的点数:" << point_set.size() << endl;

	return 0;
}

输出结果:

->加载点云的点数:1435

2.3 ifstream读取XYZ \ PLY点云

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	//--------- 读取XYZ点云 ----------
	Point_set point_set_xyz;		//创建一个三维XYZ点云容器
	ifstream ifs_xyz("oni.xyz", std::ios_base::binary);
	if (!ifs_xyz)
	{
    
    
		cerr << "\a->点云文件不存在!\n" << endl;
		return -1;
	}
	ifs_xyz >> point_set_xyz;
	ifs_xyz.close();
	cout << "->加载XYZ点云的点数:" << point_set_xyz.size() << endl;

	//--------- 读取PLY点云 ----------
	Point_set point_set_ply;		//创建一个三维PLY点云容器
	ifstream ifs_ply("oni.ply", std::ios_base::binary);
	if (!ifs_ply)
	{
    
    
		cerr << "\a->点云文件不存在!\n" << endl;
		return -1;
	}
	ifs_ply >> point_set_ply;
	ifs_ply.close();
	cout << "->加载PLY点云的点数:" << point_set_ply.size() << endl;

	return 0;
}

输出结果:

->加载XYZ点云的点数:1435
->加载PLY点云的点数:1435

3 CGAL输出点坐标

CGAL采用迭代器的方式输出点云坐标。

3.1 输出点云所有坐标

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//迭代器方式插入每一点坐标
	point_set.resize(5);							//设置容器大小
	Point_set::iterator it = point_set.begin();		//设置迭代器初始位置
	point_set.point(*it + 0) = Point(1, 2, 3);
	point_set.point(*it + 1) = Point(4, 5, 6);
	point_set.point(*it + 2) = Point(7, 8, 9);

	cout << "->点云的点数为:" << point_set.size() << endl;
	//==================== 创建点云 ====================

	//-------------------- 输出坐标 --------------------
	for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++it)
	{
    
    
		cout << point_set.point(*it) << endl;
	}
	//==================== 输出坐标 ====================

	return 0;
}

输出结果:

->点云的点数为:5
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0

3.2 输出某一点的坐标

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//迭代器方式插入每一点坐标
	point_set.resize(5);							//设置容器大小
	Point_set::iterator it = point_set.begin();		//设置迭代器初始位置
	point_set.point(*it + 0) = Point(1, 2, 3);
	point_set.point(*it + 1) = Point(4, 5, 6);
	point_set.point(*it + 2) = Point(7, 8, 9);

	cout << "->点云的点数为:" << point_set.size() << endl;
	//==================== 创建点云 ====================

	//----------------- 输出某一点坐标 ------------------
	int i = 1;
	cout << "->第" << i + 1 << "个点的坐标为:" << point_set.point(*it + i) << endl;
	//================= 输出某一点坐标 ==================
	
	return 0;
}

输出结果:

->点云的点数为:5
->2个点的坐标为:4 5 6

3.3 输出XYZ坐标

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));

	cout << "->点云的点数为:" << point_set.size() << endl;
	//==================== 创建点云 ====================

	//------------------ 输出XYZ坐标 -------------------
	for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++it)
	{
    
    
		cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it) << endl;
		cout << "	x:" << point_set.point(*it)[0]
			 << "	y:" << point_set.point(*it)[1]
			 << "	z:" << point_set.point(*it)[2]
			 << endl;
	}
	//================== 输出XYZ坐标 ===================
	return 0;
}

输出结果:

->点云的点数为:31个点坐标:1 2 3
 x:1 y:2 z:32个点坐标:4 5 6
 x:4 y:5 z:63个点坐标:7 8 9
 x:7 y:8 z:9

4 CGAL保存点云(XYZ | PLY)

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));

	cout << "->点云的点数为:" << point_set.size() << endl;
	//==================== 创建点云 ====================

	//------------------ 保存XYZ点云 ------------------
	CGAL::IO::write_XYZ("write_XYZ.xyz", point_set);
	//================== 保存XYZ点云 ==================

	//------------------ 保存PLY点云 ------------------
	CGAL::IO::write_PLY("write_PLY.ply", point_set);
	//================== 保存PLY点云 ==================

	return 0;
}

输出结果:

在这里插入图片描述

5 添加法向量字段

5.1 在已有点上添加法向量信息

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef Kernel::Vector_3 Vector;			//用于添加法向量
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

//打印点云字段信息
void print_point_set(const Point_set &point_set)
{
    
    
	if (point_set.has_normal_map())
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it)
				<< ",法向量为:" << point_set.normal(*it)
				<< endl;
		}
	}
	else
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it) << endl;
		}
	}
}

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));

	print_point_set(point_set);
	//==================== 创建点云 ====================

	//----------------- 添加法向量字段 -----------------
	point_set.add_normal_map();		//添加法向量,默认为(0,0,0)

	print_point_set(point_set);
	//================= 添加法向量字段 =================

	//----------------- 法向量字段赋值 -----------------
	Point_set::iterator it_n = point_set.begin();
	point_set.normal(*(it_n++)) = Vector(2.5, 2.5, 0.6);
	point_set.normal(*(it_n++)) = Vector(0.5, 1.7, 0.9);
	point_set.normal(*(it_n++)) = Vector(0.9, 1.8, 1.9);

	print_point_set(point_set);
	//================= 法向量字段赋值 =================
	
	return 0;
}

输出结果:

1个点坐标:1 2 32个点坐标:4 5 63个点坐标:7 8 91个点坐标:1 2 3,法向量为:0 0 02个点坐标:4 5 6,法向量为:0 0 03个点坐标:7 8 9,法向量为:0 0 01个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.9

5.2 添加新的 XYZ + Normal

代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef Kernel::Vector_3 Vector;			//用于添加法向量
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

//打印点云字段信息
void print_point_set(const Point_set &point_set)
{
    
    
	if (point_set.has_normal_map())
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it)
				<< ",法向量为:" << point_set.normal(*it)
				<< endl;
		}
	}
	else
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it) << endl;
		}
	}
}

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));
	cout << "->创建点云:" << endl;
	print_point_set(point_set);
	//==================== 创建点云 ====================

	//----------------- 添加法向量字段 -----------------
	point_set.add_normal_map();		//添加法向量,默认为(0,0,0)
	cout << "->添加法向量字段:" << endl;
	print_point_set(point_set);
	//================= 添加法向量字段 =================

	//----------------- 法向量字段赋值 -----------------
	Point_set::iterator it_n = point_set.begin();
	point_set.normal(*(it_n++)) = Vector(2.5, 2.5, 0.6);
	point_set.normal(*(it_n++)) = Vector(0.5, 1.7, 0.9);
	point_set.normal(*(it_n++)) = Vector(0.9, 1.8, 1.9);
	cout << "->法向量字段赋值:" << endl;
	print_point_set(point_set);
	//================= 法向量字段赋值 =================

	//----------------- 添加XYZ+Normal -----------------
	///方式1:
	point_set.insert(Point(10, 11, 12), Vector(4, 5, 6));
	cout << "->添加XYZ+Normal方式1:" << endl;
	print_point_set(point_set);
	///方式2:
	Point_set::iterator new_item = point_set.insert(Point(13, 14, 15));
	point_set.normal(*new_item) = Vector(7, 8, 9);
	cout << "->添加XYZ+Normal方式2:" << endl;
	print_point_set(point_set);
	//================= 删除XYZ外的属性 =================
	
	return 0;
}

输出结果:

->创建点云:
第1个点坐标:1 2 32个点坐标:4 5 63个点坐标:7 8 9
->添加法向量字段:
第1个点坐标:1 2 3,法向量为:0 0 02个点坐标:4 5 6,法向量为:0 0 03个点坐标:7 8 9,法向量为:0 0 0
->法向量字段赋值:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.9
->添加XYZ+Normal方式1:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.94个点坐标:10 11 12,法向量为:4 5 6
->添加XYZ+Normal方式2:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.94个点坐标:10 11 12,法向量为:4 5 65个点坐标:13 14 15,法向量为:7 8 9

6 删除XYZ外的属性字段,只保留XYZ

在上一节代码的基础上,最后面添加以下代码:

point_set.clear_properties();

完整代码如下:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;				//三维点(double类型)
typedef Kernel::Vector_3 Vector;			//用于添加法向量
typedef CGAL::Point_set_3<Point> Point_set;	//三维点云

using namespace std;

//打印点云字段信息
void print_point_set(const Point_set &point_set)
{
    
    
	if (point_set.has_normal_map())
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it)
				<< ",法向量为:" << point_set.normal(*it)
				<< endl;
		}
	}
	else
	{
    
    
		for (Point_set::const_iterator it = point_set.begin(); it != point_set.end(); ++it)
		{
    
    
			cout << "第" << *it + 1 << "个点坐标:" << point_set.point(*it) << endl;
		}
	}
}

int main()
{
    
    
	//-------------------- 创建点云 --------------------
	Point_set point_set;		//创建一个三维点云容器
	//insert方式插入每一点坐标
	point_set.insert(Point(1, 2, 3));
	point_set.insert(Point(4, 5, 6));
	point_set.insert(Point(7, 8, 9));
	cout << "->创建点云:" << endl;
	print_point_set(point_set);
	//==================== 创建点云 ====================

	//----------------- 添加法向量字段 -----------------
	point_set.add_normal_map();		//添加法向量,默认为(0,0,0)
	cout << "->添加法向量字段:" << endl;
	print_point_set(point_set);
	//================= 添加法向量字段 =================

	//----------------- 法向量字段赋值 -----------------
	Point_set::iterator it_n = point_set.begin();
	point_set.normal(*(it_n++)) = Vector(2.5, 2.5, 0.6);
	point_set.normal(*(it_n++)) = Vector(0.5, 1.7, 0.9);
	point_set.normal(*(it_n++)) = Vector(0.9, 1.8, 1.9);
	cout << "->法向量字段赋值:" << endl;
	print_point_set(point_set);
	//================= 法向量字段赋值 =================

	//----------------- 添加XYZ+Normal -----------------
	///方式1:
	point_set.insert(Point(10, 11, 12), Vector(4, 5, 6));
	cout << "->添加XYZ+Normal方式1:" << endl;
	print_point_set(point_set);
	///方式2:
	Point_set::iterator new_item = point_set.insert(Point(13, 14, 15));
	point_set.normal(*new_item) = Vector(7, 8, 9);
	cout << "->添加XYZ+Normal方式2:" << endl;
	print_point_set(point_set);
	//================= 添加XYZ+Normal =================

	//----------------- 删除XYZ外的属性 -----------------
	point_set.clear_properties();
	cout << "->删除XYZ外的属性:" << endl;
	print_point_set(point_set);
	//================= 删除XYZ外的属性 =================

	return 0;
}

输出结果:

->创建点云:
第1个点坐标:1 2 32个点坐标:4 5 63个点坐标:7 8 9
->添加法向量字段:
第1个点坐标:1 2 3,法向量为:0 0 02个点坐标:4 5 6,法向量为:0 0 03个点坐标:7 8 9,法向量为:0 0 0
->法向量字段赋值:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.9
->添加XYZ+Normal方式1:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.94个点坐标:10 11 12,法向量为:4 5 6
->添加XYZ+Normal方式2:
第1个点坐标:1 2 3,法向量为:2.5 2.5 0.62个点坐标:4 5 6,法向量为:0.5 1.7 0.93个点坐标:7 8 9,法向量为:0.9 1.8 1.94个点坐标:10 11 12,法向量为:4 5 65个点坐标:13 14 15,法向量为:7 8 9
->删除XYZ外的属性:
第1个点坐标:1 2 32个点坐标:4 5 63个点坐标:7 8 94个点坐标:10 11 125个点坐标:13 14 15

猜你喜欢

转载自blog.csdn.net/weixin_46098577/article/details/122636172