Lab geometry: three models, two phones
MapAnything, Depth Anything 3, and VGGT-Omega on both complete lab recordings. Six colored point clouds, 128 keyframes per video, camera paths, and downloadable PLY files.
Explore the point-cloud comparison →One handheld walk around the lab (103 seconds of 640×480 video) turned into a 3D Gaussian splat. No depth camera, no markers and no tripod were used. The two videos below are rendered from the trained splat, not played back from the recording.
Fly through the splat yourself → (53 MB download; your browser renders it)
Walk-through
Follows the path the phone was carried along, smoothed and played at 1.5× speed (69 s). This is the view the capture covers, so it is the most accurate one.
Overview
An orbit 10 m above the floor (40 s). Everything above 2.2 m and everything outside the room is cut away. No frame of the recording was taken from up here, so this view shows the room's layout, not its detail. The floor looks streaky because the phone only ever saw it at a low angle.
Camera poses, and the first attempt that got them wrong
Camera path seen from above, over the sparse 3D points.
The lab has several aisles that look alike. With every long-range match kept (left), a 20-second stretch of the walk was placed in the wrong aisle. The average reprojection error was still 0.63 px, so that number could not reveal the problem. The fix was to compare consecutive frames, which cannot be far apart, then keep only the long-range matches that agree with a first pass mapped from short-range matches alone (right).
How it was made
- Frames. The phone app saves raw image planes as well as an MP4. The raw frames were used because the MP4 is re-compressed. From every 4 frames the sharpest was kept, giving 775 frames.
- Camera poses. COLMAP features, sequential matching with loop detection, then GLOMAP in the two passes described above. Focal length and lens distortion were estimated during mapping (469 px focal at 640 px width).
- Splat. The same gsplat trainer as the RealSense captures, with the settings that did best there: a 3D anti-aliasing filter, a penalty on needle-shaped gaussians, and at most 3M gaussians. Gaussians still nearly transparent at the end were removed before saving. A per-frame colour correction absorbs the phone's auto-exposure, which ranged from ISO 622 to 3575.
- Videos. Rendered from the splat on the GPU and encoded as H.264.
Numbers
| Recording | 3,102 frames, 30 fps, 640×480 | Redmi Note 8 Pro rear camera, auto exposure |
|---|---|---|
| Frames used | 775 | sharpest of every 4 recorded frames |
| Frames with a pose | 775 / 775 | mean reprojection error 0.63 px, 72,679 sparse points |
| Training / held-out frames | 744 / 31 | every 25th frame held out |
| Held-out PSNR / SSIM / LPIPS | 24.37 / 0.874 / 0.135 | scored without the colour correction, so exposure changes count against it |
| Gaussians | 865,117 | the other 71% of the 3M cap faded to transparent and were removed |
| Training | 40,000 iterations, 29 min | 6.8 GB peak GPU memory |