点云库PCL学习教程——第4章 输入输出(I/O)

本文介绍了OpenNI框架及其兼容设备,并详细解析了PCL库中的I/O模块,涵盖了点云数据读写类、设备驱动接口及关键成员函数等内容。此外,还对比了几种常见的3D点云数据文件格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

4.1(I/O涉及的设备及相关概念)


4.1.1 OpenNI开源框架

OpenNI是一个多语言、跨平台的框架,它定义了一套用于编写通用自然交互应用的API,主要目的就是形成标准的API,便于下面两个接口之间进行通信:
(1)视觉和音频传感器(用来感知周围环境信息)
(2)视觉和音频感知中间件(用来对应用场景中所记录的音频和视觉数据进行分析和理解,例如能够接受一份可见的图像数据并返回从中检测到的手掌位置信息。)
兼容设备:Primesense Reference Design、Microsoft Kinect和Asus XtionPro
通过这些设备可以获取点云数据的采集。

4.2 PCL中I/O模块及类的介绍


4.2.1 I/O模块中类以及全局函数说明

I/O模块中目前共有21个类
1、class pcl::FileReader
定义了PCD文件的读取接口,主要用做其他读取类的父类。
关键成员函数:
virtual intreadHeader(const std::string & file_name, sensor_msgs::PointCloud2 &cloud, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &file_version, int &data_type, unsigned int &data_idx, const int offset=0)=0 //纯虚函数,定义读取点云头文件的接口函数
【pcl::PCDReader, pcl::PLYReader都继承于此函数】

2、class pcl::FileWriter
是写入PCD文件的类接口定义。与FileReader对应,可以作为其他写入类的父类。
关键成员函数:
virtual int write
【pcl::PCDWriter, pcl::PLYWriter都继承于此函数】

3、class pcl::Grabber
类Grabber为PCL1.X对应的设备驱动接口的基类定义。

// 类的关键成员函数
// 提供回调函数指针,当获取每帧图像或点云数据时都会启动回调函数:
template<typename T>
boost::signals2::connectionregisterCallback(const boost::function<T>&callback)

// 判断是否提供回调函数:
emplate<typename T>
bool providesCallback()const

// 启动设备,开始传输数据流:
virtual void start() = 0

// 停止设备上的数据流传输:
virtual void stop() = 0

// 返回明确的子类名字:
virtual std::string getName() const = 0

// 返回是否在传输数据流:
virtual bool isRunning() const = 0

// 获取FPS帧率,即每秒多少帧数据:
virtualfloat getFramesPerSecond() const = 0

4、classopenni_wrapper::OpenNIDevice
类OpenNIDevice定义OpenNI设备的基类,继承该基类可以实现不同的OpenNI设备子类,用于获取包括红外数据、RGB数据、深度图像数据等。

5、class openni_wrapper::DeviceKinect
6、class openni_wrapper::DevicePrimesense
7、class openni_wrapper::DeviceXtionPro
8、class openni_wrapper::DeviceONI
9、class openni_wrapper::OpenNIDriver
10、class openni_wrapper::OpenNIException
11、class openni_wrapper::Image
12、class openni_wrapper::ImageByerRGBG
13、class openni_wrapper::ImageRGB24
14、class openni_wrapper::ImageYUV422
15、class pcl::OpenNIGrabber
16、class pcl::PCDReader
17、class pcl::PLYReader
18、class pcl::PCDWriter
19、class pcl::PLYWriter
20、class pcl::PCLIOExpection
用到再具体了解吧

4.3 应用实例解析


4.3.1 PCD(点云数据)文件格式

3D点云数据的文件格式:

  1. PLY是一种多边形文件格式,由Stanford大学的Truk等人设计开发;
  2. STL是3D Systems公司创建的模型文件格式,主要应用于CAD,CAM领域;
  3. OBJ是从几何学上定义的文件格式,首先有Wavefront Technologies开发;
  4. X3D是符合ISO标准的基于XML的文件格式,表示3D计算机图形数据;
  5. 其他

PCD文件格式的优势:

  1. 存储和处理有序点云数据集的能力——这一点对于实时应用,例如增强现实、机器学习领域十分重要。
  2. 二进制mmap/munmap数据类型是把数据下载和存储到磁盘上最快的方法。
  3. 存储不同的数据类型(支持所有的基本类型:char, short, int, float, double)——使得点云数据在存储和处理过程中适应性强并且高效,其中无效的点通常存储为MAN类型
  4. 特征描述子的n维直方图——对于3D识别和计算机视觉应用十分重要。
### PCL 中实现点云框选功能的方法 在 Point Cloud Library (PCL) 中,可以通过多种方式实现点云的框选功能。通常情况下,这种操作涉及交互式界面以及基于几何约束的选择逻辑。以下是具体实现方法: #### 1. **使用 `pcl::CropBox` 进行矩形区域裁剪** `pcl::CropBox` 是一种用于裁剪点云数据的有效工具。它允许通过定义一个三维空间中的边界盒来筛选符合条件的点。 ```cpp #include <pcl/point_types.h> #include <pcl/filters/crop_box.h> // 定义输入点云和输出点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cropped_cloud(new pcl::PointCloud<pcl::PointXYZ>); // 设置 CropBox 参数 pcl::CropBox<pcl::PointXYZ> crop_filter; crop_filter.setMin(Eigen::Vector4f(-1.0, -1.0, -1.0, 0)); // 最小坐标 crop_filter.setMax(Eigen::Vector4f(1.0, 1.0, 1.0, 0)); // 最大坐标 crop_filter.setInputCloud(cloud); crop_filter.filter(*cropped_cloud); ``` 上述代码展示了如何设置最小和最大边界以过滤掉不符合条件的点[^2]。 --- #### 2. **结合 VTK 或 Qt 实现交互式框选** 对于更复杂的场景,可以利用 Visualization Toolkit (VTK) 或者 Qt 提供的 GUI 工具包创建交互式的点云可视化环境。用户可以在界面上拖动鼠标绘制矩形框,并实时更新所选点集。 ##### 示例:使用 VTK 的拾取器 VTK 支持强大的渲染引擎和事件处理机制,能够轻松捕获用户的框选动作并将其映射到点云上。 ```cpp #include <vtkRenderWindowInteractor.h> #include <vtkRectangularButtonSource.h> #include <pcl/visualization/pcl_visualizer.h> void boxCallback(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) { vtkRectangularButtonSource* button = static_cast<vtkRectangularButtonSource*>(caller); double bounds[6]; button->GetBounds(bounds); // 获取当前框选范围 // 将 bounds 转换为 PCL 坐标系下的裁剪参数 } ``` 此部分实现了基本的回调函数框架,当用户完成框选时会触发该函数并将结果传递给后续处理模块[^3]。 --- #### 3. **自定义算法实现动态框选** 如果希望完全控制整个流程而不依赖外部库,则可编写自己的算法。例如,在每次鼠标移动过程中记录起点与终点位置,计算对应的二维投影矩阵并与原始点云对比找出匹配项。 假设已知相机内参 K 和外参 T,那么任意屏幕像素 u,v 可逆变换回世界坐标系下的一条直线方程 L(t)=C+tRd 。遍历所有候选点 p_i ,判断其是否位于指定范围内即可得到最终子集 S={p|L_min<=p<=L_max}[^4]。 ```python import numpy as np def project_to_3d(uv_points, depth_map, intrinsic_matrix): """ 将图像平面上的 uv 点转换成 3D 空间中的实际坐标。 :param uv_points: 图像上的二维索引列表 [(u1, v1), ...] :param depth_map: 对应深度图数组 :param intrinsic_matrix: 相机内部参数矩阵 :return: 返回重建后的三维点阵列 [[x,y,z],...] """ fx, fy, cx, cy = intrinsic_matrix[0][0], intrinsic_matrix[1][1], \ intrinsic_matrix[0][2], intrinsic_matrix[1][2] points_3d = [] for pt in uv_points: z = depth_map[int(pt[1]), int(pt[0])] if z != 0: x = (pt[0]-cx)*z / fx y = (pt[1]-cy)*z / fy points_3d.append([x, y, z]) return np.array(points_3d) # 应用示例 uv_start = [x1, y1]; uv_end = [x2, y2] selected_region = project_to_3d([(i,j)for i in range(x1,x2+1)for j in range(y1,y2+1)],depth,K) print(selected_region.shape) ``` 以上 Python 片段演示了一个简单的反投射过程,适用于 RGB-D 数据源的情况[^5]。 --- #### 总结 综上所述,无论是采用内置滤波器还是借助第三方图形接口,亦或是开发专属解决方案,都可以成功达成目标——即从大规模散乱分布的数据集中精确提取感兴趣的目标群体成员个体实例样本集合群组单元等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值