pcl 基本操作汇总

news2024/11/19 19:23:29

目录

PCLVisualizer简单的点云可视化

createViewPort创建视窗

代码 

效果

点云视窗上打印文本信息

使用addText

合并多个点云

xyz+xyz

xyz + nxnynz

新建自己的Point类型

点云的刚体变换(旋转+平移)


以下是pcl点云基本操作,后面会慢慢更新。

PCLVisualizer简单的点云可视化

#include <iostream>
#include <pcl\io\pcd_io.h>
#include <pcl\visualization\pcl_visualizer.h>
 
using namespace std;
 
int main()
{
	// 加载数据
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCDReader reader;
	if (reader.read(".\\models\\horse.pcd", *cloud) < 0)
	{
		PCL_ERROR("not exists!\n");
		system("pause");
		return -1;
	}
 
	// 可视化点云
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("viewer_window_name"));
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "horse_cloud");  // 将点云附加到视窗中,并对该点云定义唯一的ID“horse_cloud”
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);  // 100 ms 刷新一次
	}
 
	return 0;
}

createViewPort创建视窗

代码 

#include <pcl/visualization/cloud_viewer.h>

int main()
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("PCL Viewer"));
	viewer->initCameraParameters();  // 初始化相机默认参数
	// 一个视窗
	//int v1(0);
	//viewer->createViewPort(0.0, 0.0, 1.0, 1.0, v1);   // x[0,1], y[0,1]
	//viewer->setBackgroundColor(255, 0, 255, v1);

	// 两个视窗
	//int v1(0), v2(1);
	//viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);  // x1[0,0.5], y1[0,1]
	//viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);  // x2[0.5,1], y2[0,1]
	//viewer->setBackgroundColor(255, 0, 255, v1);
	//viewer->setBackgroundColor(0, 255, 255, v2);

	// 三个视窗
	//int v1(0), v2(1), v3(2);
	//viewer->createViewPort(0.0, 0.0, 0.33, 1.0, v1);  // x1[0,0.33], y1[0,1]
	//viewer->createViewPort(0.33, 0.0, 0.66, 1.0, v2);  // x2[0.33,0.66], y2[0,1]
	//viewer->createViewPort(0.66, 0.0, 1.0, 1.0, v3);  // x3[0.66,1], y3[0,1]
	//viewer->setBackgroundColor(255, 0, 255, v1);
	//viewer->setBackgroundColor(0, 255, 255, v2);
	//viewer->setBackgroundColor(255, 255, 0, v3);

	// 四个视窗
	int v1(0), v2(1), v3(2), v4(3);
	viewer->createViewPort(0.0, 0.0, 0.5, 0.5, v1);  // x1[0,0.5], y1[0,0.5]
	viewer->createViewPort(0.5, 0.0, 1.0, 0.5, v2);  // x2[0.5,1], y2[0,0.5]
	viewer->createViewPort(0.0, 0.5, 0.5, 1.0, v3);  // x3[0.,0.5], y3[0.5,1]
	viewer->createViewPort(0.5, 0.5, 1.0, 1.0, v4);  // x3[0.5,1], y3[0.5,1]
	viewer->setBackgroundColor(255, 0, 255, v1);
	viewer->setBackgroundColor(0, 255, 255, v2);
	viewer->setBackgroundColor(255, 255, 0, v3);
	viewer->setBackgroundColor(255, 0, 0, v4);
	
	viewer->addCoordinateSystem();  // 在viewer对象下所有的视窗都可视化坐标系
	viewer->spin();  // 显示交互界面
}

效果

一个视窗。 

 两个视窗。

 三个视窗。

 四个视窗。

点云视窗上打印文本信息

使用addText

addText参数说明,注意最后一个参数可以指定在哪个视窗上显示文本。

bool addText (const std::string &text, int xpos, int ypos, int fontsize, double r, double g, double b, const std::string &id = "", int viewport = 0);

view/** \brief Add a text to screen
    * \param[in] text the text to add
    * \param[in] xpos the X position on screen where the text should be added
    * \param[in] ypos the Y position on screen where the text should be added
    * \param[in] fontsize the fontsize of the text
    * \param[in] r the red color value
    * \param[in] g the green color value
    * \param[in] b the blue color value
    * \param[in] id the text object id (default: equal to the "text" parameter)
    * \param[in] viewport the view port (default: all)
    */

pcl::visualization::PCLVisualizer viewer("demo");  // 创建可视化对象
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, 0);  // 定义viewport位置. 可以定义多个视角
viewer.addText("Original point cloud\n", 10, 15, 16, 1, 1, 1, "text_id", 0);

合并多个点云

xyz+xyz

点的类型都是pcl::PointXYZ类型

#include <pcl/point_types.h>
#include <pcl/io/file_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <iostream>

int
main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b;
	pcl::PointCloud<pcl::PointXYZ> cloud_c;
 
	// 创建点云数据
	cloud_a.width = 3;  // 点数3
	cloud_a.height = cloud_b.height = 1;  // 设置为无序点云
	cloud_a.points.resize(cloud_a.width * cloud_a.height);
 
	cloud_b.width = 2;
	cloud_b.points.resize(cloud_b.width * cloud_b.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);
	}
	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;
	pcl::io::savePCDFile("test.pcd", cloud_c);
 
}

结果:

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 5
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 5
DATA ascii
1.28125 577.09375 197.9375
828.125 599.03125 491.375
358.6875 917.4375 842.5625
764.5 178.28125 879.53125
727.53125 525.84375 311.28125

xyz + nxnynz


#include <pcl/point_types.h>
#include <pcl/io/file_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>


int
main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ> cloud_a;  // 向量a
	pcl::PointCloud<pcl::Normal> n_cloud_b;  // 法向量
	pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;  // xyz + nxnynz = (x,y,z,nx,ny,nz)
 
	// 创建点云数据
	cloud_a.width = 3;  // 点数3
	cloud_a.height = 1;  // 设置为无序点云
	cloud_a.points.resize(cloud_a.width * cloud_a.height);
 
	n_cloud_b.width = 3;
	n_cloud_b.height = 1;
	n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.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);
	}
	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);
	pcl::io::savePCDFile("test.pcd", p_n_cloud_c);
 
}

结果:

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z normal_x normal_y normal_z curvature
SIZE 4 4 4 4 4 4 4
TYPE F F F F F F F
COUNT 1 1 1 1 1 1 1
WIDTH 3
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 3
DATA ascii
1.28125 577.09375 197.9375 764.5 178.28125 879.53125 0
828.125 599.03125 491.375 727.53125 525.84375 311.28125 0
358.6875 917.4375 842.5625 15.34375 93.59375 373.1875 0

新建自己的Point类型

步骤:先定义结构体,再注册。

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
 
struct MyPointType  // 定义点类型说明
{
	PCL_ADD_POINT4D;  // 该点类型有4个元素
	float val;  
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW  // 确保new操作符对齐操作
}EIGEN_ALIGN16;  // 强制SSE对齐
 
POINT_CLOUD_REGISTER_POINT_STRUCT(
	MyPointType,  // 注册点类型宏
	(float, x, x)
	(float, y, y)
	(float, z, z)
	(float, val, val)
	)
 
int
main(int argc, char** argv)
{
	// 创建1行2列的点云
	pcl::PointCloud<MyPointType> cloud;
	cloud.points.resize(2);  
	cloud.width = 2;
	cloud.height = 1;
 
	// 对每个点赋值
	cloud.points[0].val = 1;
	cloud.points[0].x = cloud.points[0].y = cloud.points[0].z = 0;
	cloud.points[1].val = 2;
	cloud.points[1].x = cloud.points[1].y = cloud.points[1].z = 3;
 
	pcl::io::savePCDFile("test.pcd", cloud);
}

保存的test.pcd文件内容如下。

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z val
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 2
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 2
DATA ascii
0 0 0 1
3 3 3 2

点云的刚体变换(旋转+平移)

#include <pcl/point_types.h>
#include <pcl/io/file_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/filters/voxel_grid.h>
#include <iostream>
#include <pcl/registration/ndt.h>
#include <pcl/registration/icp.h>

#include <iostream>


int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);  // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_rotate(new pcl::PointCloud<pcl::PointXYZ>);  // 只是旋转
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_rotate_shift(new pcl::PointCloud<pcl::PointXYZ>);  // 旋转加平移
	if (pcl::io::loadPCDFile("E:\\code\\c++\\PCL_demo\\PCL_demo\\models\\rabbit.pcd", *cloud_in) < 0)
    {
        PCL_ERROR("Error loading cloud %s.\n");
        return (-1);
    }
    
    // 旋转
    rigid_transformation(cloud_in, cloud_rotate, M_PI / 4, "x", 0, 0, 0);
    rigid_transformation(cloud_in, cloud_rotate_shift, M_PI / 4, "x", 0, 5, 0);

    // 可视化
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Trans viewer"));
    viewer->initCameraParameters();
    int v1(0), v2(1);
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);

    viewer->addCoordinateSystem(1);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_in_color_r(cloud_in, 128, 128, 0);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_in_color_b(cloud_rotate, 128, 0, 128);
    viewer->addPointCloud(cloud_in, cloud_in_color_r, "orig1", v1);
    viewer->addPointCloud(cloud_rotate, cloud_in_color_b, "trans1", v1);
    viewer->addPointCloud(cloud_in, cloud_in_color_r, "orig2", v2);
    viewer->addPointCloud(cloud_rotate_shift, cloud_in_color_b, "trans2", v2);

    viewer->spin();
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/106724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++--数据结构--最小生成树-- Kruskal--Prim--高阶0713

注&#xff1a;本次修改了添加边的一些其他情况可以采用坐标来添加边 void _AddEdge(size_t srci, size_t dsti, const W& w) {_matrix[srci][dsti] w;// 无向图if (Direction false){_matrix[dsti][srci] w;} }void AddEdge(const V& src, const V& dst, const…

【学习笔记03】vue的组件

目录一、组件二、组件的分类&#xff08;一&#xff09;全局组件&#xff08;二&#xff09;局部组件1、为什么vue组件 data函数返回一个对象2、bootstrap的使用三、父组件传值给子组件1、父传子实现进度条2、 props的属性四、子组件传值给父组件五、兄弟组件传值一、组件 可以…

【Javassist】快速入门系列04 使用Javassist更改整个方法体

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 03 使用Javassist实现方法异常处理 04 使用Javassist更改整个方法体 文章目录系列文章目录前言引入Javassist jar包使用Javassist更改整个方法体总结说明前言 上一章我们介绍了使用Javas…

2022全年度白酒十大热门品牌销量榜单

白酒为中国特有的一种蒸馏酒&#xff0c;是世界六大蒸馏酒之一&#xff0c;中国是全球最大的蒸馏酒市场&#xff0c;中国的白酒消费也位列世界烈酒行业领先地位。近几年来&#xff0c;由于市场需求的不断提升及居民的消费升级&#xff0c;高档白酒价格也不断增长&#xff0c;从…

会员管理系统可行性研究

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 1.引言 1.1编写目的 1.2项目背景 1.3定义 1.4参考资料 2.可行性研究前提 2.1要求 2.2目标 2.3条件、假定和限制 2.4决定可行性的因素 3.现有小程序分析 3.1经…

进程-计算机是如何工作的

文章目录冯诺依曼计算机体系组成寄存器和内存编译型语言vs解释型语言进程进程管理进程的状态虚拟地址空间虚拟内存冯诺依曼计算机体系 组成 (1) 输入设备:键盘&#xff0c;鼠标 (2) 输出设备:显示器&#xff0c;打印机 其中硬盘(可做输入、输出) (3) 存储器:内存 (4) CPU 运…

Composing Programs(SICP python版) chap1 笔记

《Composing Programs》(SICP python版) chap1 笔记 持续更新中 在学习 CS61A 2022fall的时候配着看的 文章目录《Composing Programs》(SICP python版) chap1 笔记Chapter 1: Building Abstractions with Functions1.1 Getting Started1.1.1 Programming in Python1.1.2 Insta…

python安装face_recognition

本人使用系统为windows10,python的版本是3.8&#xff0c;在安装face_recognition之前需要安装以下内容&#xff1a; 1.cmake 2.dlib&#xff0c;dlib的安装依赖于cmake 1 安装CMake 1.1 官网下载&#xff1a;CMake 1.2 开始安装CMake: 1.3 验证是否安装成功&#xff1a; 打开…

10 Mysql中各种锁

概述 MySQL中的也存在一些类型的锁&#xff0c;用来保证多个连接同时操作数据时的安全即数据的一致性问题&#xff1b;同时&#xff0c;虽然锁能够解决一些数据的一致性和有效性&#xff0c;但是我们还是要选择合适的锁来降低锁对于并发问题的影响 1. 全局锁 全局锁就是对整…

傻白探索Chiplet,互连技术研究现状(七)

目录 一、串行互连 二、并行互连 三、串行与并行互连的比较 四、互连标准接口 &#xff08;1&#xff09;背景 &#xff08;2&#xff09;UCIe Chiplet的可行性常常受到片间互连的性能、可用性以及功耗和成本问题的限制&#xff0c;各种异构芯片的互连接口和标准的设计在技…

Web3中文|恐惧vs伦理:AI艺术评论家错在哪里?

本周&#xff0c;人工智能引发众怒。随着“AI艺术”在网络的流行&#xff0c;一群艺术家正在知名艺术家平台Art Station上掀起一场反AI艺术的抗议活动&#xff0c;而人工智能技术的拥趸者也及时回击了这波反对热潮。 这种充斥着反对意见的热潮是迟早会出现的。现在这些人认为“…

简单说手什么是JWT?

JSON Web Token&#xff08;缩写 JWT&#xff09;是目前最流行的跨域认证解决方案。 传统的session认证 http协议本身是一种无状态的协议&#xff0c;而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证&#xff0c;那么下一次请求时&#xff0c;用户还要再一…

【Lingo】【MATLAB】【求解运筹学问题模板题】

文章目录一、线性规划模型&#xff08;Lingo&#xff09;1.线性规划问题&#xff08;模板&#xff09;2.求解最优化问题3.包装箱平板车问题4.职员时序安排问题5.运输问题6.排菜单问题7.工地施工问题8.生产计划优化研究&#xff08;柴油机生产&#xff09;二、线性规划问题&…

机器学习算法基础——逻辑回归

01逻辑回归可以用来解决简单的二分类问题。 逻辑回归的预测函数为hθ(x)g(θTx)h_\theta (x)g(\theta^Tx)hθ​(x)g(θTx)&#xff0c;其中g(x)g(x)g(x)为sigmoidsigmoidsigmoid函数&#xff0c;用于将数值映射到区间[0,1][0,1][0,1]中&#xff0c;然后再取对数值用于刻画损失函…

51单片机实训day3——点亮LED灯、闪烁LED灯(一)理论

内 容&#xff1a;编写代码实现LED灯的点亮功能 学 时&#xff1a;2学时 知识点&#xff1a;分析原理图、LED灯控制原理 重点&#xff1a;GPIO参数配置、LED原理图分析 难点&#xff1a;编写 GPIO参数配置函数、LED点亮函数 时间&#xff1a;2022年12月21日 9:00&#xff5e;…

实验1 数据库定义与操作语言实验

前言&#xff1a;实验本身并不是很难&#xff0c;照着实验指导书抄就行&#xff0c;不过注意有些sql语句和mysql语句是不相同的&#xff0c;需要进行一定的修改 数据集链接 实验1 数据库定义与操作语言实验 实验1.1 数据库定义实验 1.实验目的 理解和掌握数据库DDL语言&am…

指挥中心显示大屏类型简介

因工作需要&#xff0c;现在需要不断补充指挥中心建设过程中各种设备知识&#xff0c;怕被别人忽悠了也不知道&#xff0c;抓紧学习了解。今天学习大屏部分&#xff0c;目前来说&#xff0c;常见的显示大屏主要分为DLP拼接屏、LCD拼接屏和LED小间距大屏几种类型。 1、DLP大屏 …

【maven工程的pom.xml文件内部结构详解+maven工程的多层次依赖管理】

目录pom文件内部【结构详解】pom文件内部【依赖管理】1、依赖传递&#xff1a;2、依赖传递过程中&#xff0c;版本冲突&#xff1a;3、依赖传递过程中&#xff0c;对外隐藏主动断开&#xff1a;pom文件内部【依赖的作用范围】pom文件内部【结构详解】 <?xml version"…

【ARMv8 异常模型入门及渐进 11 - Linux 中断上下文 irq_enterirq_exit】

文章目录1.1 背景1.1.1 in_interrupt 定义1.1.2 irq_count 定义1.1.3 preempt_count 各域含义1.1.4 ARMv8 中断处理流程回顾1.1 背景 在 Linux 代码中经常会看到 WARN_ON(in_interrupt()); 或者 BUG_ON(in_interrupt()); 从名字可以看出这两句的含义是&#xff1a;如果当前处在…

运用手机多媒体之使用通知

文章目录使用通知将程序运行到手机上使用通知创建通知渠道通知的基本用法通知的进阶技巧setStyle()方法不同重要等级的通知渠道使用通知 将程序运行到手机上 在AS当中除了使用模拟器来运行我们的程序,还可以使用真机来运行我们写的程序想要将程序运行到手机上,首先需要将手机…