twanghcmut/ego-real2sim / basic_pick_place /code /tests /test_reconstruction.py
twanghcmut's picture
download
raw
4.43 kB
import json
import tempfile
import unittest
from pathlib import Path
import cv2
import numpy as np
from real2sim.reconstruction import Reconstruction, sample_video
from real2sim.reconstruction.surface import (
anchor_transform,
transform_points,
triangulate,
)
class ReconstructionTests(unittest.TestCase):
def test_video_sampling_preserves_original_time_and_rgb(self):
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "clip.avi"
writer = cv2.VideoWriter(
str(path), cv2.VideoWriter_fourcc(*"MJPG"), 10, (32, 24)
)
self.assertTrue(writer.isOpened())
for _ in range(8):
writer.write(np.full((24, 32, 3), [0, 0, 250], dtype=np.uint8))
writer.release()
frames, indices, timestamps = sample_video(
path, stride=3, max_frames=2, start=1
)
np.testing.assert_array_equal(indices, [1, 4])
np.testing.assert_allclose(timestamps, [0.1, 0.4])
self.assertGreater(int(frames[0][0, 0, 0]), 240)
self.assertLess(int(frames[0][0, 0, 2]), 10)
def test_export_excludes_invalid_geometry_and_keeps_camera(self):
points = np.ones((1, 2, 3, 3), dtype=np.float32)
points[0, 0, 0] = np.nan
depth = np.ones((1, 2, 3, 1))
depth[0, 0, 1] = -1
mask = np.ones((1, 2, 3, 1), dtype=bool)
mask[0, 0, 2] = False
pose = np.eye(4)[None]
pose[0, 0, 3] = 2
pred = {
"pts3d": points,
"depth_z": depth,
"mask": mask,
"conf": np.ones((1, 2, 3)),
"intrinsics": np.eye(3)[None],
"camera_poses": pose,
"img_no_norm": np.full((1, 2, 3, 3), 0.5),
}
reconstruction = Reconstruction.from_predictions([pred], [15], [0.5], "test")
with tempfile.TemporaryDirectory() as tmp:
reconstruction.save(tmp, point_stride=1)
folder = Path(tmp)
self.assertEqual(
json.loads((folder / "manifest.json").read_text())["point_count"], 3
)
self.assertIn("element vertex 3", (folder / "scene.ply").read_text())
with np.load(folder / "cameras.npz") as cameras:
np.testing.assert_array_equal(cameras["camera/T_world_cam"], pose)
np.testing.assert_array_equal(cameras["image_size"], [[3, 2]])
np.testing.assert_array_equal(cameras["frame_indices"], [15])
with np.load(folder / "view_0000.npz") as view:
self.assertEqual(view["mask"].sum(), 3)
self.assertEqual(view["img_no_norm"][0, 0, 0], 127)
def test_bad_inputs_fail_early(self):
with self.assertRaises(ValueError):
sample_video("missing.mp4", stride=0)
with self.assertRaises(ValueError):
sample_video("missing.mp4")
with self.assertRaises(ValueError):
Reconstruction.from_predictions([], [0], [0], "test")
def test_surface_excludes_holes_and_discontinuous_edges(self):
yy, xx = np.mgrid[:4, :4]
points = np.stack((xx * 0.01, yy * 0.01, np.ones_like(xx)), axis=-1)
points[-1, -1, 2] = 10
mask = np.ones((4, 4), dtype=bool)
mask[0, 0] = False
vertices, faces, uv = triangulate({"pts3d": points, "mask": mask}, stride=1)
self.assertTrue(np.isfinite(vertices).all())
self.assertTrue((vertices[:, 2] == 1).all())
self.assertEqual(uv.shape, (len(vertices), 2))
self.assertGreater(len(faces), 0)
self.assertLess(len(faces), 18)
self.assertFalse(np.any(np.all(vertices == [0, 0, 1], axis=1)))
def test_camera_anchor_preserves_projection(self):
predicted = np.eye(4)
predicted[:3, 3] = [0.1, 0.2, 0.3]
reference = np.eye(4)
reference[:3, :3] = [[1, 0, 0], [0, 0, -1], [0, 1, 0]]
reference[:3, 3] = [1, 2, 3]
transform = anchor_transform(predicted, reference)
np.testing.assert_allclose(transform @ predicted, reference)
points = np.array([[0.5, 1, 2]])
world = transform_points(points, transform)
np.testing.assert_allclose(
(world - reference[:3, 3]) @ reference[:3, :3],
(points - predicted[:3, 3]) @ predicted[:3, :3],
)
if __name__ == "__main__":
unittest.main()

Xet Storage Details

Size:
4.43 kB
·
Xet hash:
bd2c4a4c70f21ed92d6ef62683c27652644e703d1142e2e968462fff2c38a491

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.