(6)点云数据处理学习——RGBD图

本文介绍如何使用Open3D库从不同RGBD数据集(包括Redwood、SUN、NYU和TUM)读取和处理RGBD图像。通过具体实例展示了如何创建RGBD图像对象、显示图像以及将其转换为点云。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、主要参考

(1)官网的地址

RGBD images — Open3D 0.16.0 documentation

2、实现和测试

 2.1 功能说明

Open3D有一个用于图像的数据结构。它支持各种函数,如read_image、write_image、filter_image和draw_geometries。一个Open3D图像可以直接转换为numpy数组。

一个Open3D RGBDImage由两个图像rgbimage .depth和rgbimage .color组成。我们要求两个图像注册到相同的相机帧和具有相同的分辨率。下面的教程展示了如何从许多著名的RGBD数据集中读取和使用RGBD图像。

2.2Redwood 数据集(Redwood dataset) 

(1)数据集说明

在本节中,我们将展示如何从Redwood数据集[Choi2015]_读取和可视化RGBDImage。

Redwood格式在16位单通道图像中存储深度。整数值表示以毫米为单位的深度测量。它是Open3D解析深度图像的默认格式。

(2)使用的函数

create_from_color_and_depth(  color_raw, depth_raw)

功能说明:默认的转换函数create_rgbd_image_from_color_and_depth从一对彩色和深度图像创建一个RGBDImage。彩色图像被转换为灰度图像,存储在浮动范围[0,1]中。深度图像存储在float中,以米为单位表示深度值。

(3)测试代码

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt


print("Read Redwood dataset")
redwood_rgbd = o3d.data.SampleRedwoodRGBDImages()
color_raw = o3d.io.read_image(redwood_rgbd.color_paths[0])
depth_raw = o3d.io.read_image(redwood_rgbd.depth_paths[0])
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
    color_raw, depth_raw)
print(rgbd_image)

注意open3d自动下载解压后在下面位置

 几张椅子的图挺漂亮的

2.2.1显示一下RGB图和深度图

(1)可以通过np.asarray直接对深度图和彩色图进行处理

color_img = np.asarray(rgbd_image.color)
depth_img = np.asarray(rgbd_image.depth)
print(np.size(color_img))
print(color_img[0][0])
print(depth_img[0][0])

(2)测试代码

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt


print("Read Redwood dataset")
redwood_rgbd = o3d.data.SampleRedwoodRGBDImages()
color_raw = o3d.io.read_image(redwood_rgbd.color_paths[0])
depth_raw = o3d.io.read_image(redwood_rgbd.depth_paths[0])
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
    color_raw, depth_raw)
print(rgbd_image)

#640*480的图
color_img = np.asarray(rgbd_image.color)
depth_img = np.asarray(rgbd_image.depth)
print(np.size(color_img))
print(color_img[0][0])
print(depth_img[0][0])


plt.subplot(1, 2, 1)
plt.title('Redwood grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('Redwood depth image')
plt.imshow(rgbd_image.depth)
plt.show()

(3)测试的结果

2.2.2RGBD图像可以转换为点云图

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt


print("Read Redwood dataset")
redwood_rgbd = o3d.data.SampleRedwoodRGBDImages()
color_raw = o3d.io.read_image(redwood_rgbd.color_paths[0])
depth_raw = o3d.io.read_image(redwood_rgbd.depth_paths[0])
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
    color_raw, depth_raw)
print(rgbd_image)

#640*480的图
# color_img = np.asarray(rgbd_image.color)
# depth_img = np.asarray(rgbd_image.depth)
# print(np.size(color_img))
# print(color_img[0][0])
# print(depth_img[0][0])


# plt.subplot(1, 2, 1)
# plt.title('Redwood grayscale image')
# plt.imshow(rgbd_image.color)
# plt.subplot(1, 2, 2)
# plt.title('Redwood depth image')
# plt.imshow(rgbd_image.depth)
# plt.show()

pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image,
    o3d.camera.PinholeCameraIntrinsic(
        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
# Flip it, otherwise the pointcloud will be upside down
# pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
# o3d.visualization.draw_geometries([pcd], zoom=0.5)

o3d.visualization.draw_geometries([pcd])

 这里使用了PinholeCameraIntrinsicParameters。PrimeSenseDefault作为默认相机参数。它的图像分辨率为640x480,焦距(fx, fy) =(525.0, 525.0),光心(cx, cy) =(319.5, 239.5)。单位矩阵被用作默认的外部参数。pcd.transform在点云上应用上下翻转转换,以达到更好的可视化目的。

2.3 SUN数据集(SUN dataset)

 (1)说明

在本节中,我们将展示如何读取和可视化SUN数据集[Song2015]_的RGBDImage。

本教程与上面处理Redwood数据集的教程几乎相同。唯一的区别是我们使用了转换函数create_rgbd_image_from_sun_format来解析SUN数据集中的深度图像。

(2)测试

1)下载后的数据集如下图所示

 2)测试代码

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt



print("Read SUN dataset")
sun_rgbd = o3d.data.SampleSUNRGBDImage()
color_raw = o3d.io.read_image(sun_rgbd.color_path)
depth_raw = o3d.io.read_image(sun_rgbd.depth_path)
rgbd_image = o3d.geometry.RGBDImage.create_from_sun_format(color_raw, depth_raw)
print(rgbd_image)


plt.subplot(1, 2, 1)
plt.title('SUN grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('SUN depth image')
plt.imshow(rgbd_image.depth)
plt.show()

pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image,
    o3d.camera.PinholeCameraIntrinsic(
        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
# Flip it, otherwise the pointcloud will be upside down
# pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
# o3d.visualization.draw_geometries([pcd], zoom=0.5)
o3d.visualization.draw_geometries([pcd])

 转变成的点云图如下图所示

2.4 NYU数据集(NYU dataset)

本部分展示如何从NYU数据集[Silberman2012]_读取和可视化RGBDImage。

(1)说明 

本部分教程与上面处理Redwood数据集的教程几乎相同,但有两点不同。首先,纽约大学的图片不是标准的jpg或png格式。因此,我们使用mpimg。imread将彩色图像作为numpy数组读取,并将其转换为Open3D图像。调用另一个辅助函数read_nyu_pgm从NYU数据集中使用的特殊大端pgm格式中读取深度图像。其次,我们使用一个不同的转换函数create_rgbd_image_from_nyu_format来解析SUN数据集中的深度图像

(2)测试代码

import open3d as o3d
import numpy as np

import matplotlib.image as mpimg
import re


# This is special function used for reading NYU pgm format
# as it is written in big endian byte order.
def read_nyu_pgm(filename, byteorder='>'):
    with open(filename, 'rb') as f:
        buffer = f.read()
    try:
        header, width, height, maxval = re.search(
            b"(^P5\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n]\s)*)", buffer).groups()
    except AttributeError:
        raise ValueError("Not a raw PGM file: '%s'" % filename)
    img = np.frombuffer(buffer,
                        dtype=byteorder + 'u2',
                        count=int(width) * int(height),
                        offset=len(header)).reshape((int(height), int(width)))
    img_out = img.astype('u2')
    return img_out


print("Read NYU dataset")
# Open3D does not support ppm/pgm file yet. Not using o3d.io.read_image here.
# MathplotImage having some ISSUE with NYU pgm file. Not using imread for pgm.
nyu_rgbd = o3d.data.SampleNYURGBDImage()
color_raw = mpimg.imread(nyu_rgbd.color_path)
depth_raw = read_nyu_pgm(nyu_rgbd.depth_path)
color = o3d.geometry.Image(color_raw)
depth = o3d.geometry.Image(depth_raw)
rgbd_image = o3d.geometry.RGBDImage.create_from_nyu_format(color, depth)
print(rgbd_image)

下载解压后的图片如下图所示

 (3)显示一下

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import re


# This is special function used for reading NYU pgm format
# as it is written in big endian byte order.
def read_nyu_pgm(filename, byteorder='>'):
    with open(filename, 'rb') as f:
        buffer = f.read()
    try:
        header, width, height, maxval = re.search(
            b"(^P5\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n]\s)*)", buffer).groups()
    except AttributeError:
        raise ValueError("Not a raw PGM file: '%s'" % filename)
    img = np.frombuffer(buffer,
                        dtype=byteorder + 'u2',
                        count=int(width) * int(height),
                        offset=len(header)).reshape((int(height), int(width)))
    img_out = img.astype('u2')
    return img_out


print("Read NYU dataset")
# Open3D does not support ppm/pgm file yet. Not using o3d.io.read_image here.
# MathplotImage having some ISSUE with NYU pgm file. Not using imread for pgm.
nyu_rgbd = o3d.data.SampleNYURGBDImage()
color_raw = mpimg.imread(nyu_rgbd.color_path)
depth_raw = read_nyu_pgm(nyu_rgbd.depth_path)
color = o3d.geometry.Image(color_raw)
depth = o3d.geometry.Image(depth_raw)
rgbd_image = o3d.geometry.RGBDImage.create_from_nyu_format(color, depth)
print(rgbd_image)

plt.subplot(1, 2, 1)
plt.title('NYU grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('NYU depth image')
plt.imshow(rgbd_image.depth)
plt.show()

 (4)转换为点云图像显示

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import re


# This is special function used for reading NYU pgm format
# as it is written in big endian byte order.
def read_nyu_pgm(filename, byteorder='>'):
    with open(filename, 'rb') as f:
        buffer = f.read()
    try:
        header, width, height, maxval = re.search(
            b"(^P5\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n])*"
            b"(\d+)\s(?:\s*#.*[\r\n]\s)*)", buffer).groups()
    except AttributeError:
        raise ValueError("Not a raw PGM file: '%s'" % filename)
    img = np.frombuffer(buffer,
                        dtype=byteorder + 'u2',
                        count=int(width) * int(height),
                        offset=len(header)).reshape((int(height), int(width)))
    img_out = img.astype('u2')
    return img_out


print("Read NYU dataset")
# Open3D does not support ppm/pgm file yet. Not using o3d.io.read_image here.
# MathplotImage having some ISSUE with NYU pgm file. Not using imread for pgm.
nyu_rgbd = o3d.data.SampleNYURGBDImage()
color_raw = mpimg.imread(nyu_rgbd.color_path)
depth_raw = read_nyu_pgm(nyu_rgbd.depth_path)
color = o3d.geometry.Image(color_raw)
depth = o3d.geometry.Image(depth_raw)
rgbd_image = o3d.geometry.RGBDImage.create_from_nyu_format(color, depth)
print(rgbd_image)

plt.subplot(1, 2, 1)
plt.title('NYU grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('NYU depth image')
plt.imshow(rgbd_image.depth)
plt.show()


pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image,
    o3d.camera.PinholeCameraIntrinsic(
        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
# Flip it, otherwise the pointcloud will be upside down
# pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
# o3d.visualization.draw_geometries([pcd], zoom=0.5)
o3d.visualization.draw_geometries([pcd])

2.5 TUM数据集(TUM dataset)

(1)说明

本节展示如何从TUM数据集[Strum2012]_读取和可视化RGBDImage。

本教程与上面处理Redwood数据集的教程几乎相同。唯一的区别是我们使用转换函数create_rgbd_image_from_tum_format来解析TUM数据集中的深度图像。

(2)测试

注意:官网教程有误

# tum_rgbd = o3d.data.SampleSUNRGBDImage()

tum_rgbd = o3d.data.SampleTUMRGBDImage()

或者手动下载

 https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/SampleTUMRGBDImage.zip 

import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt


print("Read TUM dataset")
# 方法一:官网下载
#tum_rgbd = o3d.data.SampleTUMRGBDImage()
# color_raw = o3d.io.read_image(tum_rgbd.color_path)
# depth_raw = o3d.io.read_image(tum_rgbd.depth_path)
## 方法二 本地下载后使用 https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/SampleTUMRGBDImage.zip 
tum_rgbd_color_path = "D:/RGBD_CAMERA/python_3d_process/SampleTUMRGBDImage/TUM_color.png"
tum_rgbd_depth_path = "D:/RGBD_CAMERA/python_3d_process/SampleTUMRGBDImage/TUM_depth.png"
color_raw = o3d.io.read_image(tum_rgbd_color_path)
depth_raw = o3d.io.read_image(tum_rgbd_depth_path)
rgbd_image = o3d.geometry.RGBDImage.create_from_tum_format(color_raw, depth_raw)
print(rgbd_image)

plt.subplot(1, 2, 1)
plt.title('TUM grayscale image')
plt.imshow(rgbd_image.color)
plt.subplot(1, 2, 2)
plt.title('TUM depth image')
plt.imshow(rgbd_image.depth)
plt.show()

pcd = o3d.geometry.PointCloud.create_from_rgbd_image(
    rgbd_image,
    o3d.camera.PinholeCameraIntrinsic(
        o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
# # Flip it, otherwise the pointcloud will be upside down
# pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
# o3d.visualization.draw_geometries([pcd], zoom=0.35)
o3d.visualization.draw_geometries([pcd])

 转换后的点云图像如下

 

 

 

### 从 RGBD 图像生成点云的方法 在 ROS 下使用 Realsense D435 深度相机可以方便地获取校准后的 RGBD 片并合成为点云,在 rviz 中查看最终效果,并可保存为 PCD 文件[^1]。 对于将深度转换成点云的过程,这实际上涉及到了坐标系之间的变换——即从图像坐标系到世界坐标系的变化。此过程依赖于相机内部参数作为约束条件来完成计算[^2]。 #### 使用 Open3D 进行点云生成 Open3D 是一种开源库,支持多种编程语言接口(Python, C++),可用于三维数据处理,包括但不限于读取、写入以及操作点云等任务。下面是一个简单的 Python 示例代码展示如何通过给定的 RGB 和 Depth 数据创建点云: ```python import numpy as np import open3d as o3d def rgbd_to_point_cloud(rgb_image_path, depth_image_path, intrinsic_matrix): rgb = o3d.io.read_image(rgb_image_path) depth = o3d.io.read_image(depth_image_path) rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth( rgb, depth, convert_rgb_to_intensity=False ) camera_intrinsic = o3d.camera.PinholeCameraIntrinsic() camera_intrinsic.set_intrinsics(640, 480, intrinsic_matrix[0][0], intrinsic_matrix[1][1], intrinsic_matrix[0][2], intrinsic_matrix[1][2]) pcd = o3d.geometry.PointCloud.create_from_rgbd_image( rgbd_image, camera_intrinsic ) return pcd intrinsic_matrix = [[617.293, 0, 315.662],[0, 617.265, 242.217],[0, 0, 1]] point_cloud = rgbd_to_point_cloud('path/to/rgb/image.png', 'path/to/depth/image.png', intrinsic_matrix) o3d.visualization.draw_geometries([point_cloud]) ``` 这段脚本展示了怎样加载一对彩色和深度图像文件,并基于已知摄像机内参矩阵构建出相应的点云对象;之后还可以调用 `draw_geometries` 函数显示该点云以便直观观察结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值