重投影 blender 渲染得到的图像到世界坐标系,如何对齐

python 复制代码
import numpy as np
import imageio
import imageio.v3 as iio
import os
import cv2
import open3d as o3d
import json

os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"

def read_img(img_file):
    if img_file.endswith('.exr'):
        img = iio.imread(img_file, flags=cv2.IMREAD_UNCHANGED, plugin='opencv')
    else:
        img = iio.imread(img_file)
    if img.ndim == 2:
        img = img[..., None]
    return img

name_data = 'orbit_cam_s1031151646'
meta_path = f""
base_dir = f""

with open(meta_path, 'r') as f:
    meta = json.load(f)
transform_matrices = [np.array(frame["transform_matrix"]) for frame in meta["frames"]]
camera_angle_x = meta["camera_angle_x"]


blender_to_cv = np.array([
    [1,  0,  0, 0],
    [0, -1,  0, 0],
    [0,  0, -1, 0],
    [0,  0,  0, 1],
])

# ---------- 初始化全局点云 ----------
all_xyz_world = []
all_colors = []

for i in range(4):  # 处理第 0~3 帧
    depth_pth = os.path.join(base_dir, f"{i}.depth.exr")
    rgb_pth   = os.path.join(base_dir, f"{i}.rgb.png")

    if not os.path.exists(depth_pth):
        print(f"⚠️ 跳过缺失帧 {i}")
        continue

    depth = read_img(depth_pth)[..., 0]
    rgb   = read_img(rgb_pth)[..., :3] / 255.0
    H, W = depth.shape

    focal = 0.5 * H / np.tan(0.5 * camera_angle_x)
    K = np.array([
        [focal, 0, 0.5 * W],
        [0, focal, 0.5 * H],
        [0, 0, 1]
    ])
    K_inv = np.linalg.inv(K)

    # ---------- 构造像素坐标 ----------
    u, v = np.meshgrid(np.arange(W), np.arange(H))
    uv1 = np.stack([u, v, np.ones_like(u)], axis=2).reshape(-1, 3)

    z = depth.reshape(-1, 1)
    xyz_cam = (uv1 @ K_inv.T) * z
    c2w = transform_matrices[i]
    c2w = c2w @ blender_to_cv  # 对齐相机坐标定义

    ones = np.ones((xyz_cam.shape[0], 1))
    xyz_cam_h = np.concatenate([xyz_cam, ones], axis=1)
    xyz_world = (xyz_cam_h @ c2w.T)[:, :3]

    colors = rgb.reshape(-1, 3)
    valid = (z[:, 0] > 0) & (z[:, 0] <= 100.0) & np.isfinite(z[:, 0])

    all_xyz_world.append(xyz_world[valid])
    all_colors.append(colors[valid])

    print(f"✅ Frame {i} 有效点数: {np.sum(valid)}")

# ---------- 合并所有帧 ----------
all_xyz_world = np.concatenate(all_xyz_world, axis=0)
all_colors = np.concatenate(all_colors, axis=0)

print(f"\n🌈 合并后总点数: {len(all_xyz_world)}")

# ---------- 可视化 ----------
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(all_xyz_world)
pcd.colors = o3d.utility.Vector3dVector(all_colors)

o3d.visualization.draw_geometries([pcd], window_name="Merged Color Point Cloud")

# ---------- 保存 ----------
o3d.io.write_point_cloud("merged_color_cloud.ply", pcd)
print("💾 已保存 merged_color_cloud.ply")
相关推荐
CG_MAGIC16 小时前
3ds Max场景烘焙:大型建筑/道具的光照贴图批量生成
3d·blender·贴图·zbrush·建模教程·渲云渲染
AI视觉网奇18 小时前
blender 取消绑定
blender
lllljz3 天前
Blender导出模型到Unity或UE5引擎材质丢失模型出错
unity·ue5·游戏引擎·blender·材质
无人装备硬件开发爱好者3 天前
Python + Blender 5.0 几何节点全栈实战教程1
开发语言·python·blender
无人装备硬件开发爱好者6 天前
Python + Blender 5.0 几何节点全栈实战教程2
python·blender
哎呦哥哥和巨炮叔叔6 天前
2026年3D软件横向对比:SketchUp、Blender 与 3ds Max 如何选择?
blender·3ds max·建筑可视化·动画制作·3d软件·渲染101云渲染·sketchup
哎呦哥哥和巨炮叔叔6 天前
程序化纹理(Procedural Texture)详解:3D项目体积缩减90%,云渲染效率全面提升
blender·maya·渲染101云渲染·材质系统·arnold渲染·程序化纹理·cg工作流
成都渲染101云渲染66667 天前
渲染速度慢怎么办?如何将 Maya 渲染速度提升成百上千倍(通用方法)
人工智能·图形渲染·blender·maya·houdini
CG_MAGIC9 天前
用Blender创作鼹鼠怪兽
3d·blender·zbrush·建模教程·渲云渲染
陈陈爱java10 天前
Blender使用守则
数码相机·blender