PCL点云转为深度图


#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl\point_cloud.h>
#include <pcl\range_image\range_image.h>
#include <vector>
#include <pcl/visualization/common/float_image_utils.h>//保存深度图像
#include <pcl/io/png_io.h>//保存深度图像

int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ> pointcloud;
	for (float y = -0.5f; y <= 0.5f; y += 0.01f)
	{
		for (float z = -0.5f; z <= 0.5f; z += 0.01f)
		{
			pcl::PointXYZ point;
			point.x = 2.0 - y;
			point.y = y;
			point.z = z;
			pointcloud.points.push_back(point);
		}
	}
	pointcloud.width = (uint32_t)pointcloud.points.size();
	pointcloud.height = 1;


	float angularResolution = (float)(1.0f * (M_PI / 180.0f));//角分辨率是1度,也就是说由相邻像素表示的光束相差一弧度
	float maxAngleWidth = (float)(360.0f * (M_PI / 180.0f));
	float maxAngleHeight = (float)(180.0f * (M_PI / 180.0f));//模拟的范围传感器有一个完整的360度全景图
	Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f, 0.0f);//传感器的位置定义了虚拟传感器的6 DOF位置,它的原点是滚动=俯仰=偏航=0。
	pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;//x朝向右,y向下,z轴是向前的,另一种选择是激光框架,x面向前方,y向左,z向上。
	float noiseLevel = 0.00;//对于噪声,噪声是0,范围图像是使用普通的z缓冲区创建的
	float minRange = 0.0f;// minRange >0 ,所有更近的点都将被忽略
	int borderSize = 1;//边界大小>0,边界将会在裁剪时留下一个未被观察到的点的边界。

	pcl::RangeImage rangeImage;
	rangeImage.createFromPointCloud(pointcloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose,
		coordinate_frame, noiseLevel, minRange, borderSize);

	float* ranges = rangeImage.getRangesArray();
	unsigned char* rgb_image = pcl::visualization::FloatImageUtils::getVisualImage(ranges, rangeImage.width, rangeImage.height);
	pcl::io::saveRgbPNGFile("saveRangeImageRGB.png", rgb_image, rangeImage.width, rangeImage.height);

	std::cout << rangeImage << "\n";

	return (0);
}
### 将深度图换为点云数据的方法 为了实现从深度图像到点云换,可以利用PCL库提供的功能来完成这一过程。具体来说,通过读取深度图像的数据,并将其映射成三维空间中的点集,最终形成点云对象。 #### 使用PCL深度图转为点云的具体流程如下: - **加载深度图像**:首先需要获取或读入深度图像。 - **创建点云容器**:定义一个`PointCloud<PointXYZ>`类型的变量用于保存即将生成的点云数据。 - **遍历像素值计算3D坐标**:对于每一个有效深度值对应的像素位置,在已知相机内参的情况下,可以通过反投影的方式得到该点的世界坐标(x,y,z)。 - **设置点属性并加入点云**:根据上述计算的结果填充点的位置信息至点云结构体中。 - **保存点云文件**:最后可以选择以ASCII或是二进制格式保存为`.pcd`文件[^1]。 下面给出一段简单的C++代码示例展示如何执行以上操作: ```cpp #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <opencv2/core.hpp> // OpenCV核心模块头文件 using namespace cv; using namespace pcl; // 假设已经有一个Mat类的对象depth_image表示深度图, // 并且知道摄像头参数fx,fy,cx,cy. void depthImageToPointCloud(const Mat& depth_image, float fx, float fy, float cx, float cy, PointCloud<PointXYZ>::Ptr cloud) { int width = depth_image.cols; int height = depth_image.rows; cloud->width = width; cloud->height = height; cloud->is_dense = false; cloud->points.resize(cloud->width * cloud->height); for(int v=0;v<height;++v){ const ushort* row_ptr = depth_image.ptr<ushort>(v); for(int u=0;u<width;++u){ ushort d = row_ptr[u]; if(d==0){continue;} // 跳过无效深度 PointXYZ &p = cloud->points[v*width + u]; p.x = static_cast<float>(u-cx)*static_cast<float>(d)/fx; p.y = static_cast<float>(v-cy)*static_cast<float>(d)/fy; p.z = static_cast<float>(d); } } } int main(){ // 加载深度图片... Mat depth_img = imread("path_to_depth_image", IMREAD_UNCHANGED); // 初始化点云集指针 PointCloud<PointXYZ>::Ptr point_cloud(new PointCloud<PointXYZ>); // 执行换函数 depthImageToPointCloud(depth_img, /*fx=*/525.0f,/*fy=*/525.0f, /*cx=*/319.5f,/*cy=*/239.5f, point_cloud); // 存储为ASCII编码的PCD文件 io::savePCDFileASCII ("test_pcd.pcd", *point_cloud); } ``` 这段程序展示了基本的工作流,其中包含了从深度图像构建点云的过程以及如何选择不同的方式(ASCII vs Binary)来保存结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cynthia.Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值