Spaces:
Sleeping
Sleeping
File size: 3,856 Bytes
d7e58f0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
import numpy as np
import vedo
from scipy.spatial.transform import Rotation as scipy_Rotation
class VedoRenderer(object):
"""An interactive renderer for camera visualization."""
def __init__(self, scale=0.03):
"""Visualize cameras in an interactive scene supported by vedo.
Args:
scale (float, optional):
Scale factor. Defaults to 0.03.
"""
self.scale = scale
self.axis_list = self.__init_axis()
self.camera_list = []
self.frames_dir_path = ''
self.y_reverse = False
def __init_axis(self, axis_len=80):
"""Prepare arrows for axis.
Args:
axis_len (int, optional):
Length of each axis.
Defaults to 80.
Returns:
List[Arrows]:
A list of three arrows.
"""
arrow_end_np = np.eye(3) * axis_len * self.scale
colors = ['r', 'g', 'b'] # r-x, g-y, b-z
ret_list = []
for axis_index in range(3):
ret_list.append(
vedo.Arrows([[0, 0, 0]],
[arrow_end_np[axis_index]]).c(colors[axis_index]))
return ret_list
def set_y_reverse(self):
"""Set y reverse before add_camera if it is needed.
Vedo defines y+ as up direction. When visualizing kinect cameras, y- is
up, call set_y_reverse in this situation to make text in correct
direction.
"""
self.y_reverse = True
self.y_reverse_rotation = \
scipy_Rotation.from_euler('z', 180, degrees=True)
def add_camera(self, camera_parameter, arrow_len=30):
"""Add an camera to the scene.
Args:
camera_parameter (CameraParameter):
An instance of class CameraParameter which stores
rotation, translation and name of a camera.
arrow_len (int, optional):
Length of the arrow. Defaults to 30.
Returns:
list:
A list of vedo items related to the input camera.
"""
rot_mat = np.asarray(camera_parameter.get_value('rotation_mat'))
translation = np.asarray(camera_parameter.get_value('translation'))
cam_center = -np.linalg.inv(rot_mat).dot(translation)
arrow_end_origin = np.eye(3) * arrow_len * self.scale
colors = ['r', 'g', 'b'] # r-x, g-y, b-z
arrow_end_camera = \
np.einsum('ij,kj->ki', np.linalg.inv(rot_mat), arrow_end_origin)
if self.y_reverse:
cam_center = self.y_reverse_rotation.apply(cam_center)
for axis_index in range(3):
arrow_end_camera[axis_index, :] = \
self.y_reverse_rotation.apply(
arrow_end_camera[axis_index, :]
)
vedo_list = []
for i in range(3):
vedo_list.append(
vedo.Arrows([cam_center],
[cam_center + arrow_end_camera[i]]).c(colors[i]))
vedo_list.append(
vedo.Text3D(camera_parameter.name, cam_center, s=self.scale * 10))
self.camera_list += vedo_list
return vedo_list
def show(self, with_axis=True, interactive=True):
"""Show cameras as well as axis arrow by vedo.show()
Args:
with_axis (bool, optional):
Whether to show the axis arrow. Defaults to True.
interactive (bool, optional):
Pause and interact with window (True) or
continue execution (False).
Defaults to True.
"""
list_to_show = []
list_to_show += self.camera_list
if with_axis:
list_to_show += self.axis_list
vedo.show(*list_to_show, interactive=interactive, axes=1)
vedo.clear()
|