学习PCL笔记--自用

**

PCL代码学习

网上找的原文地址
**

1. 写入PCD文件

主要:
<pcl/io/pcd_io.h>
<pcl/point_types.h>
pcl::PointCloudpcl::PointXYZcloud;
pcl::io::savePCDFileASCII(“test_pcd.pcd”, cloud);

#include<iostream>
#include<pcl/io/pcd_io.h>
//pcd 读写类相关头文件
#include<pcl/point_types.h>
//pcl中支持的点类型头文件
int main()//看书打代码的时候忘了写main函数,有错误
{
	pcl::PointCloud<pcl::PointXYZ>cloud;
	//描述将要实例化的模板类PointCloud,每一个点的类型都被设置成pcl::PointXYZ,作为模板类实例化的参数
	cloud.width = 5;
	cloud.height = 1;
	cloud.is_dense = false;
	cloud.points.resize(cloud.width * cloud.height);
	for (size_t i = 0; i < cloud.points.size(); ++i)//书上是size_ti=0,typedef undesigned long long size_t
	{
		cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
		cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
	}
	pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);//保存地址,与源文件一个文件夹
	std::cout << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;
	for (size_t i = 0; i < cloud.points.size(); ++i)//输出点云xyz值
	{
		std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
	}
	return(0);
}

2.读取PCD文件

pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloud pcl::PointXYZ);
pcl::io::loadPCDFilepcl::PointXYZ(“test_pcd.pcd”, *cloud)

#include<iostream>
#include<pcl/io/pcd_io.h>
//pcl读写类相关头文件
#include<pcl/point_types.h>
//pcl支持的点类型头文件
int main()
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//创建了一个PointCloud<pcl::PointXYZ> boost共享指针并进行实例化
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("test_pcd.pcd", *cloud)== -1)//if判断时候就已经执行了
	{
		PCL_ERROR("不能载入文件test_pcd.pcd\n");
		return(-1);
		//现在如果有文件已经读入了,cloud存储其地址
		//点类型为默认二进制块读取转换为模块化的PointCLoud格式里pcl::PointXYZ
	}
	std::cout << "Loaded "
		<< cloud->width * cloud->height
		<< " data points from test_pcd.pcd with the following fields: "
		<< std::endl;
	for (size_t i = 0; i < cloud->points.size(); ++i)
		std::cout << "    " << cloud->points[i].x
		<< " " << cloud->points[i].y
		<< " " << cloud->points[i].z << std::endl;

	return (0);
}

3. 合并两个点云形成点云

原本是用字符串数组argv[1]决定用哪个连接,但是运行的时候出错:istream的_Str读取字符串时出错0xcccccccccccccccc
网上说是数组越界,这个问题没搞明白,换成数字就好了。

#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
//两种合并:点与点,点与向量
int main()
{
	int argv;//数组,用于判断使用哪种合并方式
	std::cout << "输入选择,‘1’为点与点,‘2’为点与向量连接" << std::endl;
	std::cin >> argv;
	pcl::PointCloud<pcl::PointXYZ>cloud_a, cloud_b, cloud_c;//声明三个pcl::PointXYZ点云类型
	pcl::PointCloud<pcl::Normal>n_cloud_b;//存储进行连接时需要的normal点云
	pcl::PointCloud<pcl::PointNormal>p_n_cloud_c;//存储连接XYZ与Normal后的点云

	//接下来创建点云数据
	cloud_a.width = 3;//cloud_a点个数为3
	cloud_a.height = cloud_b.height = n_cloud_b.height = 1;//都为无序点云
	cloud_a.points.resize (cloud_a.width * cloud_a.height);
	//填充两种点云类型
	for (size_t i = 0; i < cloud_a.points.size(); ++i)
	{
		cloud_a.points[i].x = 1024 * rand() / RAND_MAX + 1.0f;
		cloud_a.points[i].y = 1024 * rand() / RAND_MAX + 1.0f;
		cloud_a.points[i].z = 1024 * rand() / RAND_MAX + 1.0f;
	}
	if (argv == 1)
	{
		cloud_b.width = 2;
		cloud_b.points.resize(cloud_b.width * cloud_b.height);
		for (size_t i = 0; i < cloud_b.points.size(); ++i)
		{
			cloud_b.points[i].x = 1024 * rand() / RAND_MAX + 1.0f;
			cloud_b.points[i].y = 1024 * rand() / RAND_MAX + 1.0f;
			cloud_b.points[i].z = 1024 * rand() / RAND_MAX + 1.0f;
		}
		cloud_c = cloud_a;
		cloud_c += cloud_b;
		for (size_t i = 0; i < cloud_c.points.size(); ++i)
		{
			std::cout << "cloud_c" << cloud_c.points[i].x <<"  "<< cloud_c.points[i].y <<"  "<< cloud_c.points[i].z << std::endl;
		}
	}
	else
	{
		n_cloud_b.width = 3;
		n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.height);
		for (size_t i = 0; i < n_cloud_b.points.size(); ++i)
		{
			n_cloud_b.points[i].normal[0] = 1024 * rand() / RAND_MAX + 1.0f;
			n_cloud_b.points[i].normal[1] = 1024 * rand() / RAND_MAX + 1.0f;
			n_cloud_b.points[i].normal[2] = 1024 * rand() / RAND_MAX + 1.0f;
		}
		pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_c);
		for (size_t i = 0; i < p_n_cloud_c.points.size(); ++i)
		{
			std::cout << p_n_cloud_c.points[i].x << "  " << p_n_cloud_c.points[i].y << "  " << p_n_cloud_c.points[i].z << "  " << p_n_cloud_c.points[i].normal[0] << "  " << p_n_cloud_c.points[i].normal[1] << "  " << p_n_cloud_c.points[i].normal[2] << std::endl;
		}
	}

}

4. 在点云中加入高斯噪声

没明白高斯噪声怎么生成,之后看。。
在13行处,如果没有括号,就会提示:
严重性 代码 说明 项目 文件 行 禁止显示状态
错误(活动) E0300 指向绑定函数的指针只能用于调用函数 PCL_Debug C:\Users\one\Desktop\PCL_Debug\PCL_Debug\源.cpp 13
在size后面加上()成功运行
这是因为调用的是函数,要加上括号。

#include<pcl/point_types.h>
#include<pcl/point_cloud.h>
#include<iostream>
#include <pcl/console/time.h>
#include <boost/random.hpp>
int main()
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//创建了一个PointCloud<pcl::PointXYZ> boost共享指针并进行实例化
	cloud->width = 100;
	cloud->height = 1;
	cloud->points.resize(cloud->width * cloud->height);
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
		cloud->points[i].x = 1000.0f * rand() / (RAND_MAX + 1.0f);
		cloud->points[i].y = 1000.0f * rand() / (RAND_MAX + 1.0f);
		cloud->points[i].z = 1000.0f * rand() / (RAND_MAX + 1.0f);
	}
	//添加高斯噪声,范围(0-0.01)
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudfiltered(new pcl::PointCloud<pcl::PointXYZ>());
	cloudfiltered->points.resize(cloud->points.size());
	cloudfiltered->header = cloud->header;
	cloudfiltered->width = cloud->width;
	cloudfiltered->height = cloud->height;
	boost::mt19937 rng;
	rng.seed(static_cast<unsigned int> (time(0)));
	boost::normal_distribution<> nd(0, 0.01);
	boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd);
	for (size_t point_i = 0; point_i < cloud->points.size(); ++point_i)
	{
		cloudfiltered->points[point_i].x = cloud->points[point_i].x + static_cast<float> (var_nor());
		cloudfiltered->points[point_i].y = cloud->points[point_i].y + static_cast<float> (var_nor());
		cloudfiltered->points[point_i].z = cloud->points[point_i].z + static_cast<float> (var_nor());
	}
	return 0;
}

5. 使用kdtree(k近邻搜索和半径搜索)

#include <pcl/point_cloud.h>//点类型定义头文件
#include <pcl/kdtree/kdtree_flann.h>//kdtree类定义头文件

#include<iostream>
#include<vector>
#include<ctime>


int main(int argc, char** argv)
{
	srand(time(NULL));//用系统时间初始化随机种子
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//创建一个PointCloud<pcl::PointXYZ>..
	//pcl 是一个命名空间,跟std类似,
	//PointCloud是类模板,
	//<pcl::PointXYZ>是模板类实例化的类型
	//PointCloud<pcl::PointXYZ>就是一个实例化了的模板类
	//ptr是智能指针,相当于之前普通指针声明的*,
	//cloud是指针变量,就是一个指向PointCloud<pcl::PointXYZ>类对象的指针
	//new pcl::PointCloud<pcl::PointXYZ>就是给了一个地址初始化指针

	//随机点云生成
	cloud->width = 1000;//点云数量
	cloud->height = 1;//无序点云
	cloud->points.resize(cloud->width * cloud->height);

	for (size_t i = 0; i < cloud->points.size(); ++i)//循环填充点云数据
	{
		cloud->points[i].x = 1024.0f * rand() / (RAND_MAX + 1.0f);
		cloud->points[i].y = 1024.0f * rand() / (RAND_MAX + 1.0f);
		cloud->points[i].z = 1024.0f * rand() / (RAND_MAX + 1.0f);
	}
	//创建kdtreeFLANN对象,并把创建的点云设置为输入,创建一个searchPoint变量作为查询点
	pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;//创建kd-tree对象

	kdtree.setInputCloud(cloud);//设置搜索空间

	pcl::PointXYZ searchPoint;//设置查询点并附随机值
	searchPoint.x = 1024.0f * rand() / (RAND_MAX + 1.0f);
	searchPoint.y = 1024.0f * rand() / (RAND_MAX + 1.0f);
	searchPoint.z = 1024.0f * rand() / (RAND_MAX + 1.0f);
	
	//k近邻搜索
	//创建一个整数(设置为10)和两个向量来存储搜索到的k近邻,两个向量中,一个存储搜索到查询点近邻的索引,另一个存储对应近邻的距离平方
	int K = 10;
	std::vector<int> pointIdxNKNSearch(K);//存储查询点近邻索引,定义向量pointTdxNKNSearch
	std::vector<float> pointNKNSquaredDistance(K);//存储近邻点对应距离平方,定义向量pointNKNSquareDistance
	std::cout << "K nearest neighbor search at(" << searchPoint.x
		<< "," << searchPoint.y
		<< "," << searchPoint.z 
		<< ") with K=" << K << std::endl;//打印查询点的信息
	
	//假设kd-tree对象返回了多余0个近邻,搜索结果已经存储在之前创建的两个向量pointTdxNKNSearch和pointNKNSquareDistance中,并把所有10个紧邻的位置打印出来
	if(kdtree.nearestKSearch(searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance)>0);//执行k近邻搜索
	
	{
		for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
			std::cout << cloud->points[pointIdxNKNSearch[i]].x
			<< "," << cloud->points[pointIdxNKNSearch[i]].y
			<< "," << cloud->points[pointIdxNKNSearch[i]].z
			<< "square distance:" << pointNKNSquaredDistance[i] << ")" << std::endl;
	}
	
	//下面代码展示查找到给定searchPoint的某一半径(随机产生)内的所有近邻,重新定义两个向量
	//pointIdxRadiusSearch和pointSquareRadiusDistance来存储关于近邻的信息
	std::vector<int>pointIdxRadiusSearch;//存储近邻索引
	std::vector<float>pointSquareRadiusDistance;//存储近邻对应的距离平方
	float radius = 256.0f * rand() / (RAND_MAX + 1.0f);
	std::cout << "distance<radius=" << radius << std::endl;
	//像之前一样,如果kd-tree对象在指定半径内返回返回多余0个近邻,他将打印输出向量中存储的点的坐标与距离
	if (kdtree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointSquareRadiusDistance) > 0)
	{
		for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i)
		{
			std::cout << cloud->points[pointIdxRadiusSearch[i]].x << "," << cloud->points[pointIdxRadiusSearch[i]].y << "," << cloud->points[pointIdxRadiusSearch[i]].z<< "(squared distance:" << pointSquareRadiusDistance[i] << ")" << std::endl;
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《Visual C++ 2005入门经典》的源代码及课后练习答案 对应的书籍资料见: Visual C++ 2005入门经典 基本信息 原书名: Ivor Horton's Beginning Visual C++ 2005 原出版社: Wiley 作者: (美)Ivor Horton 译者: 李颂华 康会光 出版社:清华大学出版社 ISBN:9787302142713 上架时间:2007-2-12 出版日期:2007 年1月 开本:16开 页码:1046 版次:1-1 编辑推荐   本书由编程语言先驱者Ivor Horton倾力而著,是国内第一本全面、深入介绍Visual C++ 2005的经典之作! 内容简介   本书系编程语言先驱者Ivor Horton的经典之作,是学习C++编程最畅销的图书品种之一,不仅涵盖了Visual C++ .NET编程知识,还全面介绍了标准C++语言和.NET C++/CLI。本书延续了Ivor Horton讲解编程语言的独特方法,从中读者可以学习Visual C++ 2005的基础知识,并全面掌握在MFC和Windows Forms中访问数据源的技术。此外,本书各章后面的习题将有助于读者温故而知新,并尽快成为C++高效程序员。...    作译者   Ivor Horton是世界著名的计算机图书作家,主要从事与编程相关的顾问及撰写工作,曾帮助无数程序员步入编程的殿堂。他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了实时闭环工业控制系统。Horton拥有丰富的教学经验(教学内容包括C、C++、Fortran、PL/1、APL等),同时还是机械、加工和电子CAD系统、机械CAM系统和DNC/CNC系统方面的专家。Ivor Horton还著有Beginning Visual C++ 6、Beginning C Programming和Beginning Java 2等多部入门级好书。 目录 封面 -18 前言 -14 目录 -9 第1章 使用Visual C++ 2005编程 1 1.1 .NET Framework 1 1.2 CLR 2 1.3 编写C++应用程序 3 1.4 学习Windows编程 4 1.4.1 学习C++ 4 1.4.2 C++标准 5 1.4.3 控制台应用程序 5 1.4.4 Windows编程概念 6 1.5 集成开发环境简介 7 1.6 使用IDE 9 1.6.1 工具栏选项 9 1.6.2 可停靠的工具栏 10 1.6.3 文档 11 1.6.4 项目和解决方案 11 1.6.5 设置Visual C++ 2005的选项 23 1.6.6 创建和执行Windows应用程序 24 1.6.7 创建Windows Forms应用程序 26 1.7 小结 29 第2章 数据、变量和计算 31 2.1 C++程序结构 31 2.1.1 程序注释 36 2.1.2 #include指令——头文件 37 2.1.3 命名空间和using声明 37 2.1.4 main()函数 38 2.1.5 程序语句 38 2.1.6 空白 40 2.1.7 语句块 41 2.1.8 自动生成的控制台程序 41 2.2 定义变量 42 2.2.1 命名变量 43 2.2.2 C++中的关键字 43 2.2.3 声明变量 44 2.2.4 变量的初值 44 2.3 基本数据类型 45 2.3.1 整型变量 45 2.3.2 字符数据类型 46 2.3.3 整型修饰符 47 2.3.4 布尔类型 48 2.3.5 浮点类型 48 2.3.6 ISO/ANSI C++中的基本类型 49 2.3.7 字面值 50 2.3.8 定义数据类型的同义词 50 2.3.9 具有特定值集的变量 51 2.3.10 指定枚举常量的类型 52 2.4 基本的输入/输出操作 53 2.4.1 从键盘输入 53 2.4.2 到命令行的输出 53 2.4.3 格式化输出 54 2.4.4 转义序列 55 2.5 C++中的计算 57 2.5.1 赋值语句 57 2.5.2 算术运算 58 2.5.3 计算余数 63 2.5.4 修改变量 63 2.5.5 增量和减量运算符 64 2.5.6 计算

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值