Skip to content

Commit df118ba

Browse files
Implemented basic pointcloud and camera pose visualization
commit-id:c4886df5
1 parent 265321e commit df118ba

File tree

4 files changed

+625
-4
lines changed

4 files changed

+625
-4
lines changed

packages/child-lab-visualization/pyproject.toml

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ name = "child-lab-visualization"
33
version = "0.1.0"
44
description = "Add your description here"
55
readme = "README.md"
6-
authors = [
7-
{ name = "Jan Smółka", email = "[email protected]" }
8-
]
6+
authors = [{ name = "Jan Smółka", email = "[email protected]" }]
97
requires-python = ">=3.12.7"
10-
dependencies = []
8+
dependencies = [
9+
"numpy>=1.26.4",
10+
"torch>=2.6.0",
11+
"viser>=0.2.23",
12+
"transformation-buffer",
13+
"video-io",
14+
]
15+
16+
[tool.uv.sources]
17+
transformation-buffer = { workspace = true }
18+
video-io = { workspace = true }
1119

1220
[build-system]
1321
requires = ["hatchling"]
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
from .server import show_pointcloud_and_camera_poses
12

3+
__all__ = ['show_pointcloud_and_camera_poses']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from pathlib import Path
2+
3+
import numpy
4+
import torch
5+
from transformation_buffer.buffer import Buffer
6+
from video_io.calibration import Calibration
7+
from video_io.reader import Reader
8+
from viser import ViserServer
9+
10+
11+
def show_pointcloud_and_camera_poses(
12+
server: ViserServer,
13+
origin_name: str,
14+
reader: Reader,
15+
points_files: list[Path],
16+
calibration: Calibration,
17+
buffer: Buffer,
18+
) -> None:
19+
height = reader.metadata.height
20+
width = reader.metadata.width
21+
fov = 2 * numpy.arctan2(height / 2, calibration.focal_length[0])
22+
aspect = width / height
23+
24+
server.scene.add_camera_frustum(f'/frames/0/cameras/{origin_name}', fov, aspect)
25+
26+
for frame in buffer.frames_visible_from(origin_name):
27+
transformation = buffer[(frame, origin_name)]
28+
assert transformation is not None
29+
30+
if 'marker' in frame:
31+
server.scene.add_frame(
32+
f'/frames/0/ref_frames/{frame}',
33+
axes_length=0.1,
34+
axes_radius=0.0025,
35+
wxyz=transformation.rotation_quaternion().numpy(),
36+
# Dividing by 1000 is a workaround for working with old intrinsic parameters.
37+
position=transformation.translation().div(1000.0).numpy(),
38+
)
39+
40+
else:
41+
server.scene.add_camera_frustum(
42+
f'/frames/0/cameras/{frame}',
43+
fov,
44+
aspect,
45+
wxyz=transformation.rotation_quaternion().numpy(),
46+
position=transformation.translation().div(1000.0).numpy(),
47+
)
48+
49+
points_first_batch: torch.Tensor = torch.load(points_files[0])
50+
frames_first_batch = reader.read_batch(points_first_batch.shape[0])
51+
assert frames_first_batch is not None
52+
53+
server.scene.add_point_cloud(
54+
'/frames/0/point_cloud',
55+
points=points_first_batch[0].permute((1, 2, 0)).flatten(0, -2).numpy(),
56+
colors=frames_first_batch[0].permute((1, 2, 0)).flatten(0, -2).numpy(),
57+
point_size=0.001,
58+
point_shape='circle',
59+
position=(0.0, 0.0, -2.0),
60+
)

0 commit comments

Comments
 (0)