点云库(PCL)学习——I/O

1.PCD(Point Cloud Data)文件格式

1.PCD并不是第一个支持三维点云的格式。特别是计算机图形学和计算几何界,已经创造了许多格式来描述使用激光扫描仪获得的任意多边形和点云。比如:PLY,STL,OBJ,X3D等。在当今的传感器技术以及算法被发明之前,这些格式就因为不同的目的在不同的时间相继被创造出来,它们也存在着多多少少的缺陷。
2.文件格式头文件:每个PCD文件都包含了一个头文件来定义和声明点云数据的某些属性(properties)并存储在文件里。PCD的头文件必须用ASCII编写。

NOTE:每个头文件条目(header entry)以及ASCII点云数据都在PCD文件中明确,并以行隔开。
0.7版本的PCD头文件包含以下条目:VERSION、FIELDS、SIZE、TYPE、COUNT、WIDTH、HEIGHT、VIEWPOINT、POINTS、D,头文件条目必须严格按照上述顺序指定标题条目。

2.从PCD文件中读取点云数据

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

int
main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);//创建一个PointCloud<PointXYZ>boost共享指针并初始化

  if (pcl::io::loadPCDFile<pcl::PointXYZ> ("test_pcd.pcd", *cloud) == -1) //* load the file
  {
    PCL_ERROR ("Couldn't read file test_pcd.pcd \n");//从磁盘加载PointCloud数据
    return (-1);
  }
  std::cout << "Loaded "
            << cloud->width * cloud->height
            << " data points from test_pcd.pcd with the following fields: "
            << std::endl;
  for (const auto& point: *cloud)
    std::cout << "    " << point.x
              << " "    << point.y
              << " "    << point.z << std::endl;//显示加载的数据

  return (0);
}

3.向PCD文件中写点云数据

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

int
  main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ> cloud;

  // Fill in the cloud data
  cloud.width    = 5;
  cloud.height   = 1;
  cloud.is_dense = false;
  cloud.points.resize (cloud.width * cloud.height);

  for (auto& point: cloud)
  {
    point.x = 1024 * rand () / (RAND_MAX + 1.0f);
    point.y = 1024 * rand () / (RAND_MAX + 1.0f);
    point.z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  pcl::io::savePCDFileASCII ("test_pcd.pcd", cloud);
  std::cerr << "Saved " << cloud.size () << " data points to test_pcd.pcd." << std::endl;

  for (const auto& point: cloud)
    std::cerr << "    " << point.x << " " << point.y << " " << point.z << std::endl;

  return (0);
}

4.连接(concatenate)两个点云的点

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

int main (int argc, char** argv)
{
	if (argc !=2) //限制参数为2个
	{
		std::cerr << "please specify command line arg '-f' or '-p'" << std::endl;
		exit(0);
	}
	pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c;
	plc::PointCloud<pcl::Normal> n_cloud_b;
	pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;

	//Fill in the cloud data
	cloud_a.width = 5;
	cloud_a.height = cloud_b.height = n_cloud_b.height = 1;
	cloud_a.points.resize(cloud_a.width * cloud_a.height);
	if (strcmp(argv[1], "-p") == 0)
	{
		cloud_b.width = 3;
		cloud_b.points.resize(cloud_b.width*cloud_b.height);
	}
	else{
		n_cloud_b.width = 5;
		n_cloud_b.points.resize(n_cloud_b.width*n_cloud_b.height);
	}
	for (std::size_t i = 0; i<cloud_a.size(); ++i)
	{
	cloud_a[i].x = 1024*rand()/(RAND_MAX + 1.0f);
	cloud_a[i].y = 1024*rand()/(RAND_MAX + 1.0f);
	cloud_a[i].z = 1024*rand()/(RAND_MAX + 1.0f);
	}
	if (strcmp(argv[1], "-p") == 0)
		for (std::size_t i = 0; i<cloud_b.size(); ++i)
		{
			cloud_b[i].x = 1024*rand()/(RAND_MAX + 1.0f);
			cloud_b[i].y = 1024*rand()/(RAND_MAX + 1.0f);
			cloud_b[i].z = 1024*rand()/(RAND_MAX + 1.0f);
		}
	else
		for (std::size_t i = 0; i<n_cloud_b.size(); ++i)
		{
			n_cloud_b[i].normal[0] = 1024*rand()/ (RAND_MAX + 1.0f);
			n_cloud_b[i].normal[1] = 1024*rand()/ (RAND_MAX + 1.0f);
			n_cloud_b[i].normal[2] = 1024*rand()/ (RAND_MAX + 1.0f);
		}
	std::cerr<<"Cloud A : " << std::endl;
	for (std::size_t i = 0; i<cloud_a.size(); ++i)
	std::cerr<< "   " << cloud_a[i].x << "  " << cloud_a[i].y << "  " << cloud_a[i].z << std::endl;
	std::cerr<<"Cloud B: " << std::endl;
	if (strcmp(argv[1], "-p") == 0)
		for (std::size_t i = 0; i<cloud_b.size (); ++i)
			std::cerr<<"   " << cloud_b[i].x << " " << cloud_b[i].y << " " << cloud_b[i].z << std::endl;
	else
		for (std::size_t i = 0; i < n_cloud_b.size (); ++i)
			std::cerr << "    " << n_cloud_b[i].normal[0] << " " << n_cloud_b[i].normal[1] << " " << n_cloud_b[i].normal[2] << std::endl;
	if (strcmp(argv[1], "-p") == 0)
	{
		cloud_c = cloud_a;
		cloud_c += cloud_b;
		std::cerr << "Cloud C: " << std::endl;
		for (std::size_t i = 0; i < cloud_c.size (); ++i)
			std::cerr << "    " << cloud_c[i].x << " " << cloud_c[i].y << " " << cloud_c[i].z << " " << std::endl;
	}
	else
	{
	pcl::concatenateFields (cloud_a, n_cloud_b, p_n_cloud_c);
	std::cerr << "Cloud C: " << std::endl;
	for (std::size_t i = 0; i < p_n_cloud_c.size (); ++i)
		std::cerr << "    " <<
		p_n_cloud_c[i].x << " " << p_n_cloud_c[i].y << " " << p_n_cloud_c[i].z << " " << p_n_cloud_c[i].normal[0] << " " << p_n_cloud_c[i].normal[1] << " " << p_n_cloud_c[i].normal[2] << std::endl;
	}
	reture (0);
}
### Python 实现实时点云处理 #### 使用 PCLPy 进行实时点云处理 对于希望利用Python实现高效实时点云处理的应用场景而言,PCLPy是一个非常合适的工具。该库允许开发者借助于Point Cloud Library (PCL)的强大功能来执行复杂的操作,而无需离开熟悉的Python环境[^1]。 为了支持实时应用需求,在设计基于PCLPy的解决方案时需考虑几个重要因素: - **性能优化**:由于实时应用程序通常有严格的延迟要求,因此应尽可能减少不必要的计算开销并充分利用硬件加速选项。 - **数据流管理**:有效的缓冲机制和异步I/O策略有助于维持稳定的数据传输速率,这对于保持系统的响应速度至关重要。 下面给出一段简单的代码片段作为示例,展示了如何使用`pclpy`读取来自传感器的连续帧,并对其进行基本预处理: ```python import pclpy from sensor_msgs.msg import PointCloud2 as pc2 import rospy def callback(data): cloud = pclpy.PointXYZ() pclpy.fromROSMsg(data, cloud) # 对获取到的每一帧点云做进一步处理... if __name__ == "__main__": rospy.init_node('point_cloud_listener', anonymous=True) sub = rospy.Subscriber("/camera/depth_registered/points", pc2, callback) rospy.spin() ``` 此脚本订阅了一个名为`/camera/depth_registered/points`的话题,每当接收到新的消息时就会触发回调函数`callback()`,后者负责将ROS格式的消息转换成适合后续分析的形式。 #### 法线空间采样用于特征提取 当涉及到更高级别的任务如对象识别或姿态估计时,则可能需要用到更加专业的技术手段——例如法线空间采样(normal space sampling),它能够帮助从原始输入中提炼出更具代表性的几何特性[^3]。 通过上述方法获得的关键点集不仅保留了物体表面的主要形态信息,而且大大降低了后续运算所需的时间成本;这使得即使是在资源受限环境下也能顺利完成高质量的任务目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值