PCL三维重建教程_点云基础篇(认识、读取加载显示、输出保存点云、附赠点云类型转换) C++

讲在前面:

本教程类似于教会你加减乘除(点云基础、分割、滤波、配准),然后自己做一道包含加减乘除的综合题(实践操作)。

此教程用最简单的例程,给大家直观感受。就像做一道物理大题,我们总用理想情况,便于理解学习。因此,所有的示例都围绕斯坦福的小兔子展开。

我不会带你们看官方文档,而是用自己的想法和语言来表达,目的是让一头雾水的人会去应用。毕竟我知道,做这个的大多数人,也只是为了应用,如果去深究原理,必然也不会来到这里。很多东西,我们只会应用就会“高人一等”,原理重要吗?重要!但对于大多数人来说,没有必要。司机并不一定知道汽车内部是什么结构,怎样运行的,他只需要会开车。没错,所以我们只能是司机,但对于我们来说,足够了。在我看来学会了应用,才会去学习更深层次的东西。当你不知原因打印出一个"hello world!",那种神秘和兴奋,会引导你去想弄清楚,这到底是为什么。

先去吃个饭,一会再写:)


前提准备:

首先说明我的环境:win10 +visual studio 2013 +PCL1.8.0
如果你使用其他版本,只要配置好了,也没有什么问题。
如果你还没有配置好环境,请看以下文章。

点我配置环境!

此外需要你有一定的c/c++,或是其他任意一门语言基础。
真的只需要基础就可以,这方面课程也比较多,请先自行去学习。


示例斯坦福兔子下载
ヾ( ̄ー ̄)X

进入正题!

首先,我们认识一下点云。

点云,字面来看,是很多点组成的云?云是千变万化的,大量的点的千变万化也组成了不同的形状。

现在跟我想,我们写txt文件的时候,可以把输入的一个字符看做一个基本单位。

那在pcd文件中呢?就是一个点,但这个点不一般。它有位置和颜色。

下面,我打开一个点云兔子pcd文件。
在这里插入图片描述

读取加载显示点云:

我怎么把这个点云可视化呢?

示例一:

#include<pcl/visualization/cloud_viewer.h>
#include<iostream>//标准C++库中的输入输出类相关头文件。
#include<pcl/io/io.h>
#include<pcl/io/pcd_io.h>//pcd 读写类相关的头文件。
#include<pcl/io/ply_io.h>
#include<pcl/point_types.h> //PCL中支持的点类型头文件。
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;
using namespace pcl;
using namespace visualization;

int main() {
	//声明变量 就像我们用整型a 之前 要 int a; 
	//类也是如此
	PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
	PCDReader reader;
	
	//加载pcd文件
	reader.read<PointXYZ>("{你的兔子路径}rabbit.pcd", *cloud);   
	//如果要加载别的pcd文件 只需修改这里!

	//创建显示窗口 并命名为 my viewer
	CloudViewer viewer("my viewer");
	//显示读取的点云
	viewer.showCloud(cloud);
	
	//阻止窗口关闭
	system("pause");

	return 0;

}
首先我们要引用头文件,头文件中是别人写好的一些代码。
因为我们不会写(造积木)!我们看似在敲代码,
不过只是在用别人的积木,组建出不一样的东西罢了。
使用命令空间,可以让代码看起来简洁。
不使用的话 main函数里第一句则为
pcl::PointCloud<pcl::PointXYZ>::Ptr my_cloud(new pcl::PointCloud<pcl::PointXYZ>);
很长且眼花缭乱!

效果如下:
在这里插入图片描述

有两种方式,我们不要深究区别,不要忘了我们现在的目的,只是想看到点云而已。

第二种:
可以修改显示的点云颜色

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>

int	main()
{   //声明变量
	pcl::PointCloud<pcl::PointXYZ>::Ptr my_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCDReader my_reader;
	
    //读取点云
	my_reader.read<pcl::PointXYZ>("E:\\Desktop\\code\\pointcloud\\rabbit.pcd", *my_cloud); //路径根据你自己的修改

	// 显示结果图  
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("view"));
	
	// 设置背景颜色
	viewer->setBackgroundColor(0, 255, 0);
	//这里为绿色
	
	// 设置点云颜色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(my_cloud, 255, 0, 255);
	//这里为紫色
	
	// 加载显示的点云
	viewer->addPointCloud(my_cloud, color, "cloud");
	
	//可以设置最开始的视角
	//viewer->initCameraParameters();


	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
	}
	return (0);
}

在这里插入图片描述

输出保存点云:

#include<pcl/visualization/cloud_viewer.h>
#include<iostream>//标准C++库中的输入输出类相关头文件。
#include<pcl/io/io.h>
#include<pcl/io/pcd_io.h>//pcd 读写类相关的头文件。
#include<pcl/io/ply_io.h>
#include<pcl/point_types.h> //PCL中支持的点类型头文件。
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;
using namespace pcl;
using namespace visualization;

int main() {

	//无颜色类型点云
	PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
	//有颜色类型点云
	PointCloud<PointXYZRGB>::Ptr new_cloud(new PointCloud<PointXYZRGB>);

	//读取加载pcd文件
	PCDReader reader;
	reader.read<PointXYZ>("rabbit.pcd", *cloud);
	
	//获取原始点云数据数量
	int num = cloud->points.size();
	cout << "cloud size is:" << num << endl;

	//循环对每个点操作
	for (int i = 0; i <num; i++)
	{	
		//定义一个XYZRGB类型点云P 临时储存原始点云的坐标

		PointXYZRGB p;
		p.x = cloud->points[i].x;  //cloud->point[i]即 cloud点云中的第i个点  
		p.y = cloud->points[i].y;  //.x .y .z就是其坐标信息
		p.z = cloud->points[i].z;

		//给每个点赋值点云颜色
		p.r = 0;
		p.g = 255;
		p.b = 255;

		//将同类型的P内的坐标和颜色信息赋值给新点云
		new_cloud->points.push_back(p);
	}


	visualization::CloudViewer viewer("my viewer");
	viewer.showCloud(new_cloud);

	pcl::io::savePCDFile("new_rabbit.pcd", *cloud);

	system("pause");
	return 0;
}

由于保存太简单,无非多了以下代码。

pcl::io::savePCDFile("new_rabbit.pcd", *cloud);

我决定学一赠一,教大家点云类型转换。

具体内容仔细看注释即可。

如XYZRGB到XYZ 实质就是丢掉RGB信息,我们只需要一个把原来的点云XYZ信息赋值给新点云,不赋值RGB即可。

上面的例子是把XYZ到XYZRGB,赋值XYZ信息后,又加上了藏青色(应该是这个色吧)。

效果如下:

在这里插入图片描述
可以不收藏,不关注,但请点个赞👍

  • 73
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
PCL(Point Cloud Library)是一个开源的计算机视觉,其中内置了许多点云处理的算法,包括点云曲面重建。 点云曲面重建是将无序的点云数据转换为连续的曲面模型,常用于三维建模、机器人视觉导航、医学图像处理等领域。PCL提供了多种点云曲面重建算法,包括基于网格的方法和基于隐式曲面的方法。本文将介绍其中的一种基于网格的方法——Poisson重建。 Poisson重建算法的基本思想是,利用点云数据构建一个无向加权图,并将重建的曲面模型视为该图的等势面。在该图上进行拉普拉斯平滑,得到的曲面为最小化拉普拉斯能量的解。 下面是Poisson重建的具体步骤: 1. 对点云进行预处理,去除离群点、滤波、下采样等操作,以减少噪声和计算量。 2. 构建点云的法向量估计算法。Poisson重建算法需要法向量信息作为重建的基础PCL提供了多种法向量估计算法,如基于协方差矩阵的法向量估计、基于法向量的一致性检测等。 3. 构建无向加权图。Poisson重建算法将点云数据视为一个无向加权图,其中每个点表示一个顶点,每个点之间根据一定的规则连接一条边,边权重表示两个点之间的相似度。PCL中常用的连接规则为K近邻和半径搜索。 4. 执行Poisson重建算法。在无向加权图上进行拉普拉斯平滑,得到的曲面为最小化拉普拉斯能量的解。Poisson重建算法还可以对结果进行后处理,如光滑、去除孔洞等。 下面是Poisson重建算法的Python实现代码: ``` import pcl # 加载点云数据 cloud = pcl.load('input_cloud.pcd') # 预处理 cloud_filtered = cloud.make_statistical_outlier_filter().filter() cloud_downsampled = cloud_filtered.make_voxel_grid_filter().filter() cloud_normals = cloud_downsampled.make_normal_estimation().compute() # 构建无向加权图 search_tree = cloud_downsampled.make_kdtree() mls = cloud_downsampled.make_moving_least_squares() mls.set_search_radius(0.1) mls.set_polynomial_order(2) mls.set_upsampling_method(pcl.MovingLeastSquares.NONE) cloud_smoothed = mls.process() poisson = cloud_smoothed.make_poisson_reconstruction() poisson.set_depth(9) poisson.set_iso_divide(8) poisson.set_point_weight(4) poisson.set_samples_per_node(1.5) poisson.set_confidence(false) poisson.set_output_polygons(true) reconstructed = poisson.reconstruct() ``` 其中,'input_cloud.pcd'为点云数据文件名,需要先使用PCL进行格式转换。以上代码仅为示例,具体参数需要根据实际应用场景进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值