You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对RealSense D435i已保存的RGB与深度图像进行对齐?

RealSense D435i 离线深度图对齐RGB图实现方案

核心说明

离线对齐不需要依赖实时拍摄流,只需要获取拍摄设备的深度、彩色相机内参,以及深度到彩色相机的外参,即可完成重投影对齐,以下优先提供Python实现方案。

方案1:pyrealsense2原生对齐(最推荐,精度最高)

直接调用RealSense官方SDK的对齐接口,和实时对齐的计算逻辑完全一致,不需要自己实现重投影逻辑。

前置步骤:获取相机校准参数

如果是你自己的拍摄设备,直接运行以下代码读取设备出厂校准参数即可,D435i的出厂校准参数稳定性很高,只要没有拆解过设备就可以直接复用:

import pyrealsense2 as rs
# 初始化流读取参数
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
profile = pipeline.start(config)
# 读取深度、彩色流配置
depth_profile = rs.video_stream_profile(profile.get_stream(rs.stream.depth))
color_profile = rs.video_stream_profile(profile.get_stream(rs.stream.color))
# 读取内参与外参,可将这些参数序列化保存到本地json文件后续离线使用
depth_intrinsics = depth_profile.get_intrinsics()
color_intrinsics = color_profile.get_intrinsics()
depth_to_color_extrinsics = depth_profile.get_extrinsics_to(color_profile)
pipeline.stop()

离线对齐代码

import cv2
import numpy as np
import pyrealsense2 as rs

# 初始化对齐对象,目标对齐到彩色流
align = rs.align(rs.stream.color)

# 读取本地存储的原始图像,*深度图必须读取16位原始数据,禁止提前转8位灰度图*
raw_depth = cv2.imread("你的深度图路径.png", cv2.IMREAD_UNCHANGED)
raw_color = cv2.imread("你的RGB图路径.png")

# 构造SDK可识别的帧对象
depth_frame = rs.video_frame(rs.frame(), raw_depth.tobytes(), depth_profile, 0, 0)
color_frame = rs.video_frame(rs.frame(), raw_color.tobytes(), color_profile, 0, 0)

# 执行对齐
aligned_frames = align.process(rs.frameset([depth_frame, color_frame]))
aligned_depth_frame = aligned_frames.get_depth_frame()
# 转换为numpy数组,和RGB图尺寸完全对应
aligned_depth = np.asanyarray(aligned_depth_frame.get_data())

方案2:纯OpenCV手动实现(无SDK依赖)

如果不想安装pyrealsense2环境,可以手动实现3D重投影逻辑完成对齐,代码如下:

import cv2
import numpy as np

# 替换为你自己的相机参数,从之前读取的内参外参转换即可
# 深度相机内参3x3矩阵
depth_intr = np.array([
    [depth_intrinsics.fx, 0, depth_intrinsics.ppx],
    [0, depth_intrinsics.fy, depth_intrinsics.ppy],
    [0, 0, 1]
])
# 彩色相机内参3x3矩阵
color_intr = np.array([
    [color_intrinsics.fx, 0, color_intrinsics.ppx],
    [0, color_intrinsics.fy, color_intrinsics.ppy],
    [0, 0, 1]
])
# 深度到彩色的旋转矩阵3x3、平移向量3x1
R = np.array(depth_to_color_extrinsics.rotation).reshape(3,3)
T = np.array(depth_to_color_extrinsics.translation).reshape(3,1)
# RealSense默认深度值单位为毫米,转米用
depth_scale = 0.001

# 读取图像
raw_depth = cv2.imread("你的深度图路径.png", cv2.IMREAD_UNCHANGED)
raw_color = cv2.imread("你的RGB图路径.png")
color_h, color_w = raw_color.shape[:2]

# 生成深度图像素坐标网格
u_d, v_d = np.meshgrid(np.arange(raw_depth.shape[1]), np.arange(raw_depth.shape[0]))
z_d = raw_depth * depth_scale
# 转换为深度相机坐标系下的3D点
x_d = (u_d - depth_intr[0,2]) * z_d / depth_intr[0,0]
y_d = (v_d - depth_intr[1,2]) * z_d / depth_intr[1,1]
points_3d_depth = np.stack([x_d, y_d, z_d], axis=-1).reshape(-1, 3)

# 转换为彩色相机坐标系下的3D点
points_3d_color = (R @ points_3d_depth.T + T).T
# 投影为彩色图像素坐标
z_c = points_3d_color[:, 2]
u_c = (points_3d_color[:, 0] * color_intr[0,0] / z_c + color_intr[0,2]).astype(np.int32)
v_c = (points_3d_color[:, 1] * color_intr[1,1] / z_c + color_intr[1,2]).astype(np.int32)

# 过滤有效坐标范围,生成对齐后的深度图
valid_mask = (u_c >=0) & (u_c < color_w) & (v_c >=0) & (v_c < color_h) & (z_c > 0)
aligned_depth = np.zeros((color_h, color_w), dtype=raw_depth.dtype)
aligned_depth[v_c[valid_mask], u_c[valid_mask]] = raw_depth[v_d.reshape(-1)[valid_mask], u_d.reshape(-1)[valid_mask]]

# 可选:对齐后的深度图可能存在孔洞,可用cv2.inpaint填充
# hole_mask = (aligned_depth == 0).astype(np.uint8)
# aligned_depth = cv2.inpaint(aligned_depth, hole_mask, 5, cv2.INPAINT_TELEA)

内容的提问来源于stack exchange,提问作者Yarden Akaby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:42:00