如何从点云创建深度图像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从点云创建深度图像相关的知识,希望对你有一定的参考价值。

首先,在PCL(Point Cloud Learning)中国协助发行的书提供光盘的第9章例1文件夹中,打开名为range_image_creation.cpp的代码文件。
解释说明
下面来解析打开源代码中的关键语句。
#include <pcl/range_image/range_image.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.0f - 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)); // 按弧度360.0度
float maxAngleHeight = (float) (180.0f * (M_PI/180.0f)); // 按弧度180.0度
Eigen::Affine3f sensorPose = (Eigen::Affine3f)Eigen::Translation3f(0.0f, 0.0f,0.0f); //采集位置
pcl::RangeImage::CoordinateFrame coordinate_frame =pcl::RangeImage::CAMERA_FRAME; //深度图像遵循的坐标系统
float noiseLevel=0.00;
float minRange = 0.0f;
int borderSize = 1;
这部分定义了创建深度图像时需要的设置参数,将角度分辨率定义为1度,意味着由邻近的像素点所对应的每个光束之间相差1度,maxAngleWidth=360和maxAngleHeight=180意味着,我们进行模拟的距离传感器对周围的环境拥有一个完整的360度视角,用户在任何数据集下都可以使用此设置,因为最终获取的深度图像将被裁剪到有空间物体存在的区域范围。但是,用户可以通过减小数值来节省一些计算资源,例如:对于传感器后面没有可以观测的点时,一个水平视角为180度的激光扫描仪,即maxAngleWidth=180就足够了,这样只需要观察距离传感器前面就可以了,因为后面没有需要观察的场景。sensorPose定义了模拟深度图像获取传感器的6自由度位置,其原始值为横滚角roll、俯仰角pitch、偏航角yaw都为0,coordinate_frame=CAMERA_FRAME说明系统的X轴是向右的,Y轴是向下的,Z轴是向前的,另外一个选择是LASER_FRAME,其X轴向前,Y轴向左,Z轴向上。noiseLevel=0是指使用一个归一化的Z缓冲器来创建深度图像,但是如果想让邻近点集都落在同一个像素单元,用户可以设置一个较高的值,例如noiseLevel=0.05可以理解为,深度距离值是通过查询点半径为125px的圆内包含的点用来平均计算而得到的。如果minRange>0,则所有模拟器所在位置半径minRange内的邻近点都将被忽略,即为盲区。在裁剪图像时,如果borderSize>0,将在图像周围留下当前视点不可见点的边界。
pcl::RangeImage rangeImage;
rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight, sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
std::cout << rangeImage << "\\n";
其余的代码是使用那些用户给定的参数,从点云创建深度图像,并且在终端下打印出一些信息。
深度图像继承于PointCloud类,它的点类型具有x,y,z和range距离字段,共有三种类型的点集,有效点集是距离大于零的点集,当前视点不可见点集x=y=z=NAN且值域为负无穷大,远距离点集x=y=z=NAN且值域为无穷大。
编译和运行程序
利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件。生成执行文件后,就可以运行了,在cmd中键入命令:
...>range_image_creation.exe
参考技术A ‍额

如何将 RGB 深度图像转换为点云?

【中文标题】如何将 RGB 深度图像转换为点云?【英文标题】:How can I convert RGB depth image to Point Cloud? 【发布时间】:2019-02-18 13:20:10 【问题描述】:

我有一个关于机器人映射的研究想法。基本上,最终目标是使用适中的单目相机(售价 20-50 美元)并创建 3D 占用网格图(有一个用 c++ 编写的流行库,称为 Octomap)。为了做到这一点,我建议自己采取以下步骤:

    获取 rgb 图像(来自视频)并使用卷积神经网络转换为深度图像。这部分完成了。

    获取原始 rgb 图像和创建的深度图像并转换为点云。

    获取点云并将其转换为 3D 占用网格图。

所以对于第 2 步,我有点困惑,无论我做对还是错。我已经使用了这个代码,它是一个开源的:

import argparse
import sys
import os
from PIL import Image

focalLength = 938.0
centerX = 319.5
centerY = 239.5
scalingFactor = 5000

def generate_pointcloud(rgb_file,depth_file,ply_file):

    rgb = Image.open(rgb_file)
    depth = Image.open(depth_file).convert('I')

    if rgb.size != depth.size:
        raise Exception("Color and depth image do not have the same 
resolution.")
    if rgb.mode != "RGB":
        raise Exception("Color image is not in RGB format")
    if depth.mode != "I":
        raise Exception("Depth image is not in intensity format")


    points = []    
    for v in range(rgb.size[1]):
        for u in range(rgb.size[0]):
            color = rgb.getpixel((u,v))
            Z = depth.getpixel((u,v)) / scalingFactor
            print(Z)
            if Z==0: continue
            X = (u - centerX) * Z / focalLength
            Y = (v - centerY) * Z / focalLength
            points.append("%f %f %f %d %d %d 0\n"% 

我认为points 是实际存储点云的列表,对吗?

所以我要问的一个大问题是,使用深度学习算法创建 RGB 图像和深度图像是否可以使用上面的代码转换为点云?

【问题讨论】:

我想你应该没问题,只要你知道缩放因子和焦距。 【参考方案1】:

如果您能妥善处理 RGB 和深度图像比例,那就没问题了。您的最终点云属性可能类似于 (x,y,z,r,g,b)

【讨论】:

以上是关于如何从点云创建深度图像的主要内容,如果未能解决你的问题,请参考以下文章

PCL:如何从点云中删除偏差?

从点云创建不规则的 3D 几何图形

点云处理技术之PCLrange image——创建深度图像并可视化

如何将 RGB 深度图像转换为点云?

OpenCV中的立体图像创建深度图

如何使用 PCL 库从点云数据中获取协方差矩阵?