Open3D gui--------保存当前相机视角和恢复当前相机视角

保存当前相机视角和恢复当前相机视角

想要实现 open3d 提供的可视化接口 ctrl+c 复制视角,ctrl+v 恢复视角的功能

尝试过很多方法,找到了最简单的方法 来自https://github.com/isl-org/Open3D/issues/3627。

import numpy as np
import open3d as o3d
import open3d.visualization.gui as gui
from pickle import load, dump

ToGLCamera = np.array([
    [1,  0,  0,  0],
    [0,  -1,  0,  0],
    [0,  0,  -1,  0],
    [0,  0,  0,  1]
])
FromGLGamera = np.linalg.inv(ToGLCamera)

def model_matrix_to_extrinsic_matrix(model_matrix):
    return np.linalg.inv(model_matrix @ FromGLGamera)

def create_camera_intrinsic_from_size(width=1024, height=768, hfov=60.0, vfov=60.0):
    fx = (width / 2.0)  / np.tan(np.radians(hfov)/2)
    fy = (height / 2.0)  / np.tan(np.radians(vfov)/2)
    # fx = fy # not sure why, but it looks like fx should be governed/limited by fy
    return np.array(
        [[fx, 0, width / 2.0],
         [0, fy, height / 2.0],
         [0, 0,  1]])

def save_view(vis, fname='saved_view.pkl'):
    try:
        model_matrix = np.asarray(vis.scene.camera.get_model_matrix())
        extrinsic = model_matrix_to_extrinsic_matrix(model_matrix)
        width, height = vis.size.width, vis.size.height
        intrinsic = create_camera_intrinsic_from_size(width, height)
        saved_view = dict(extrinsic=extrinsic, intrinsic=intrinsic, width=width, height=height)
        with open(fname, 'wb') as pickle_file:
            dump(saved_view, pickle_file)
    except Exception as e:
        print(e)

def load_view(vis, fname="saved_view.pkl"):
    try:
        with open(fname, 'rb') as pickle_file:
            saved_view = load(pickle_file)
        vis.setup_camera(saved_view['intrinsic'], saved_view['extrinsic'], saved_view['width'], saved_view['height'])
        # Looks like the ground plane gets messed up, no idea how to fix
    except Exception as e:
        print("Can't find file", e)

def main():
    gui.Application.instance.initialize()
    vis = o3d.visualization.O3DVisualizer("Demo to Load a Camera Viewpoint for O3DVisualizer", 1024, 768)
    gui.Application.instance.add_window(vis)
    vis.point_size = 8
    vis.show_axes = True
    # Add saving and loading view
    vis.add_action("Save Camera View", save_view)
    vis.add_action("Load Camera View", load_view)

    # Create Random Geometry
    pcd = o3d.io.read_point_cloud('D:\W_M_NIUST\WM_Project\MyProject/scene0423_00_crop_0.ply')
    # pc = np.random.randn(100, 3) * 0.5
    # pcd = o3d.geometry.PointCloud()
    # pcd.points = o3d.utility.Vector3dVector(pc)
    vis.add_geometry("Random Point Cloud", pcd)
    vis.reset_camera_to_default()

    gui.Application.instance.run()


if __name__ == "__main__":
    main()

在o3d>0.16版本中,setup_camera()函数多了一个参数 boundingbox,我们改写如下

 vis.setup_camera(intrinsic, extrinsic, width, height, pcd.get_axis_aligned_bounding_box())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值