Python:基于 RGB-D 图像的点云计算( 二 )


Python:基于 RGB-D 图像的点云计算

文章插图
从深度图像计算的点云
3.彩色点云
如果我们想从RGB-D图像中计算彩色点云怎么办呢?颜色信息可以提高点云配准等许多任务的性能 。彩色点云的定义如下:
Python:基于 RGB-D 图像的点云计算

文章插图
 
其中x, y, z为3D坐标,r, g, b为RGB系统中的颜色 。
我们首先导入前面深度图像对应的RGB图像:
# Read the rgb image:rgb_image = iio.imread('../data/rgb.jpg')# Display depth and grayscale image:fig, axs = plt.subplots(1, 2)axs[0].imshow(depth_image, cmap="gray")axs[0].set_title('Depth image')axs[1].imshow(rgb_image)axs[1].set_title('RGB image')plt.show()
Python:基于 RGB-D 图像的点云计算

文章插图
深度图像及其对应的 RGB 图像
要查找深度传感器 3D 坐标系中定义的给定点p(x, y,z)的颜色:
1.我们将其转换为RGB相机坐标系[2]:
Python:基于 RGB-D 图像的点云计算

文章插图
 
其中R和T为两个相机之间的外部参数:分别为旋转矩阵和平移向量 。
类似地,我们使用NYU Depth V2数据集的参数:
# Rotation matrix:R = -np.array([[9.9997798940829263e-01, 5.0518419386157446e-03, 4.3011152014118693e-03],[-5.0359919480810989e-03, 9.9998051861143999e-01, -3.6879781309514218e-03],[- 4.3196624923060242e-03, 3.6662365748484798e-03, 9.9998394948385538e-01]])# Translation vector:T = np.array([2.5031875059141302e-02, -2.9342312935846411e-04, 6.6238747008330102e-04])
RGB相机坐标系中的点计算如下:
Convert the point from depth sensor 3D coordinate systemto rgb camera coordinate system:[x_RGB, y_RGB, z_RGB] = np.linalg.inv(R).dot([x, y, z]) - np.linalg.inv(R).dot(T)
2. 利用RGB相机的固有参数,将其映射到彩色图像坐标系
Python:基于 RGB-D 图像的点云计算

文章插图
这些是获取颜色像素的索引
注意,在前面的公式中,焦距和光心是RGB相机的参数 。类似地,我们使用NYU Depth V2数据集的参数:
# RGB camera intrinsic Parameters:FX_RGB = 5.1885790117450188e+02FY_RGB = 5.1946961112127485e+02CX_RGB = 3.2558244941119034e+0CY_RGB = 2.5373616633400465e+02
对应像素的索引计算如下:
Convert from rgb camera coordinate systemto rgb image coordinate system:j_rgb = int((x_RGB * FX_RGB) / z_RGB + CX_RGB + width / 2)i_rgb = int((y_RGB * FY_RGB) / z_RGB + CY_RGB)
让我们把所有东西放在一起并显示点云:
colors = []pcd = []for i in range(height):for j in range(width):Convert the pixel from depth coordinate systemto depth sensor 3D coordinate systemz = depth_image[i][j]x = (j - CX_DEPTH) * z / FX_DEPTHy = (i - CY_DEPTH) * z / FY_DEPTHConvert the point from depth sensor 3D coordinate systemto rgb camera coordinate system:[x_RGB, y_RGB, z_RGB] = np.linalg.inv(R).dot([x, y, z]) - np.linalg.inv(R).dot(T)Convert from rgb camera coordinates systemto rgb image coordinates system:j_rgb = int((x_RGB * FX_RGB) / z_RGB + CX_RGB + width / 2)i_rgb = int((y_RGB * FY_RGB) / z_RGB + CY_RGB)# Add point to point cloud:pcd.append([x, y, z])# Add the color of the pixel if it exists:if 0 <= j_rgb < width and 0 <= i_rgb < height:colors.append(rgb_image[i_rgb][j_rgb] / 255)else:colors.append([0., 0., 0.])# Convert to Open3D.PointCLoud:pcd_o3d = o3d.geometry.PointCloud() # create a point cloud objectpcd_o3d.points = o3d.utility.Vector3dVector(pcd)pcd_o3d.colors = o3d.utility.Vector3dVector(colors)# Visualize:o3d.visualization.draw_geometries([pcd_o3d])
Python:基于 RGB-D 图像的点云计算

文章插图
从 RGB-D 图像计算的彩色点云
4.代码优化
在本节中,我们将解释如何优化代码,使其更高效,更适合实时应用程序 。
4.1 点云
使用嵌套循环计算点云非常耗时 。对于分辨率为480×640的深度图像,在一台拥有8GB RAM和i7-4500 CPU的机器上,计算点云大约需要2.154秒 。
为了减少计算时间,可以用向量化操作取代嵌套循环,计算时间可减少至约0.024秒:
# get depth resolution:height, width = depth_im.shapelength = height * width# compute indices:jj = np.tile(range(width), height)ii = np.repeat(range(height), width)# rechape depth imagez = depth_im.reshape(length)# compute pcd:pcd = np.dstack([(ii - CX_DEPTH) * z / FX_DEPTH,(jj - CY_DEPTH) * z / FY_DEPTH,z]).reshape((length, 3))
我们还可以通过在开始时计算一次常数来将计算时间减少到大约0.015秒:
# compute indices:jj = np.tile(range(width), height)ii = np.repeat(range(height), width)# Compute constants:xx = (jj - CX_DEPTH) / FX_DEPTHyy = (ii - CY_DEPTH) / FY_DEPTH# transform depth image to vector of z:length = height * widthz = depth_image.reshape(height * width)# compute point cloudpcd = np.dstack((xx * z, yy * z, z)).reshape((length, 3))


推荐阅读