作者留言
当我们有深度图和颜色图之后,我们可以做很多操作,例如:颜色图负责目标识别、图像分割、目标跟踪 等传统视觉任务;深度图与颜色图结合后,可以得到每个像素的 3D坐标(x, y, z)。下面来介绍深度图与颜色图结合后形成点云图的效果。深度相机的sdk基本都会有这个接口。
1.初始化 Orbbec 相机并配置深度和彩色图像流
pipeline = Pipeline()
config = Config()
# 配置深度图像流
depth_profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
depth_profile = depth_profile_list.get_default_video_stream_profile()
config.enable_stream(depth_profile)
# 配置彩色图像流
has_color_sensor = False
try:
profile_list = pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
if profile_list is not None:
color_profile = profile_list.get_default_video_stream_profile()
config.enable_stream(color_profile)
has_color_sensor = True
except OBError as e:
print(e)
pipeline.enable_frame_sync()
pipeline.start(config)
2.取一帧对齐后的深度和彩色图像数据
对齐是为了让深度图中的每个像素与颜色图中的像素对应到同一个真实世界点上。
align_filter = AlignFilter(align_to_stream=OBStreamType.COLOR_STREAM)
frames = pipeline.wait_for_frames(100)
frame = align_filter.process(frames)
depth_frame = frames.get_depth_frame()
color_frame = frames.get_color_frame() if has_color_sensor else None
3.通过深度图生成点云数据
point_cloud_filter = PointCloudFilter()
point_format = OBFormat.RGB_POINT if has_color_sensor and color_frame is not None else OBFormat.POINT
point_cloud_filter.set_create_point_format(point_format)
point_cloud_frame = point_cloud_filter.process(frame)
points = point_cloud_filter.calculate(point_cloud_frame)
# 转换为 NumPy 数组
points_array = np.array([p[:3] for p in points]) # XYZ
colors_array = np.array([p[3:6] for p in points]) if has_color_sensor else None # RGB
4. 使用 Open3D 将点云保存为 .ply
文件格式
def convert_to_o3d_point_cloud(points, colors=None):
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
if colors is not None:
pcd.colors = o3d.utility.Vector3dVector(colors / 255.0)
return pcd
def save_points_to_ply(points, colors, file_name):
pcd = convert_to_o3d_point_cloud(points, colors)
o3d.io.write_point_cloud(file_name, pcd)
print(f"Point cloud saved to: {file_name}")
Q:为什么可以通过 RGBD 图像生成点云
A:RGBD 图像由一张彩色图像(RGB)和一张深度图(D)组成。深度图中的每个像素记录了相机到场景中某点的距离,而彩色图提供了每个像素的颜色信息。由于我们知道了每个像素的图像坐标 (u, v),加上深度值 (d),再结合相机的内参(焦距 fx, fy 和主点 cx, cy),就可以通过相机模型的反投影公式将每个像素转换为相机坐标系下的三维点 (X, Y, Z):
这样,每个深度图像素都能还原为一个三维坐标点,同时对应的 RGB 图像提供该点的颜色信息。将所有像素转换后即可形成一幅带有颜色的稠密点云。这就是为什么只需一张 RGB 图和对应的深度图,就可以恢复出场景的三维结构并生成完整的点云。