RGBD图像转3D点云

在图像处理和计算机视觉领域,RGBD 是指结合图像颜色和深度信息的数据格式。文本介绍如何使用Python将RGBD数据转换为3D点云,可以使用NSDT 3DConvert在线查看3D点云或者进行格式转换:

https://3dconvert.nsdt.cloud

1、RGBD = 颜色+深度

缩写 RGB 代表三基色通道,每个通道由 0 到 255 之间的整数值表示。这些值决定相应颜色的强度,0 表示没有颜色,255 表示最大强度。 第一个值代表红色通道,第二个值代表绿色,第三个值代表蓝色。 当任何 RGB 值增加时,颜色特征会向该特定颜色通道收敛。 为了说明这一点,请考虑以下示例。

(RGB)           -> color

(0, 0, 0)       -> black
(255, 0, 0)     -> red
(0, 255, 0)     -> green
(0, 0, 255)     -> blue 
(255, 255, 255) -> white

缩写词 RGBD 的最后一个字母代表深度通道。 该值提供图像的距离信息。 深度值可以通过多种技术获得,例如飞行时间 (ToF) 传感器、结构光传感器或立体相机设置。 这些传感器通过测量光或电磁波从传感器传播到物体并返回所需的时间来计算深度值。

2、3D 点云

3D 点云是一种基本数据结构,由三维笛卡尔坐标系中的一组数据点组成,其中云中的每个单独点对应于 3D 空间中的唯一位置,由其 x、y 和 z 精确定义 坐标。 点云是各种软件行业的关键实体,包括计算机视觉、机器人、地理信息系统 (GIS) 和 3D 建模。

3、从 RGBD图像创建 3D 点云

要从 2D 图像创建 3D 点云,焦距和基点的知识至关重要。 为此,给出相机矩阵作为输入。

下面的块显示了标准针孔相机的相机矩阵。

                    | fx   0  cx |
 Camera Matrix =    |  0  fy  cy |
                    |  0   0   1 |

其中各参数含义如下:

  • fx:表示沿x轴的焦距。
  • fy:表示沿 y 轴的焦距。
  • cx:表示基点的x坐标,它是图像平面沿 x 轴的中心。
  • cy:表示基点的y坐标,它是图像平面沿 y 轴的中心。

注意:

  • 右下角元素代表比例因子,通常设置为 1。
  • 其他元素表明相机的透视投影,不涉及水平 (x) 和垂直 (y) 轴之间的任何扭曲或倾斜效应。

当提供 RGBD 二维图像和标准针孔相机的相机矩阵时,可以使用基本数学原理来构建三维点云。

根据上图, f(焦距)由相机矩阵给出, y(像素的y坐标)可以通过枚举像素来计算, z(深度)就是深度值。 必须计算 Y才能创建 3D 点云。 通过使用三角形相似性, Y = y * z / f。 此说明仅针对 y坐标, x坐标可以用相同的公式获得。

下面的函数实现了上述步骤。

def to_3D(fx, fy, depth, cx, cy, u, v):
    x = (u-cx)*depth/fx
    y = (v-cy)*depth/fy
    z = depth
    x = np.expand_dims(x, axis = -1)
    y = np.expand_dims(y, axis = -1)
    z = np.expand_dims(z, axis = -1)
    return np.concatenate((x,y,z), axis=-1)

在上面的函数中, uv参数代表像素的 xy坐标。 为了说明这些参数,请考虑以下的数据,其中的值是使用具有 640 像素列和 480 像素行的图像创建的。

the shape of u = (480, 640)

the shape of v = (480, 640)

u = 

[[  0   1   2 ... 637 638 639]
 [  0   1   2 ... 637 638 639]
 [  0   1   2 ... 637 638 639]
 ...
 [  0   1   2 ... 637 638 639]
 [  0   1   2 ... 637 638 639]
 [  0   1   2 ... 637 638 639]]

v = 

[[  0   0   0 ...   0   0   0]
 [  1   1   1 ...   1   1   1]
 [  2   2   2 ...   2   2   2]
 ...
 [477 477 477 ... 477 477 477]
 [478 478 478 ... 478 478 478]
 [479 479 479 ... 479 479 479]]

最后,可以使用以下函数创建 3D 点云。

def make_point_cloud(datapath, fx, fy, cx, cy):
    rgbd = .....\load data
    H = len(rgbd)
    W = len(rgbd[0])
    u = np.arange(W)
    v = np.arange(H)
    u, v = np.meshgrid(u, v)
    xyz = to_3D(fx, fy, rgbd[:,:,3], cx, cy, u, v)
    rgb = rgbd[:,:,:-1]
    point_cloud = np.concatenate((xyz, rgb), axis=-1)
    return point_cloud

4、RGBD转3D点云示例

输入RGB图像和深度图像如下:

左:RGB图像 右:深度图像

利用前面的函数,我们得到的3D点云如下所示:


原文链接:RGBD to 3D Point Cloud

BimAnt翻译整理,转载请标明出处