A standard COLMAP sparse model + one timestamp per image + one timestamp per point.
Every image and every point becomes an independent sample in spacetime (x, y, z, t).
Nothing else: frame sync is just timestamps being close, and any discretization is a
derived view or a render parameter, never stored data.
colmap4d adds up to three sidecar files to an ordinary COLMAP model and changes no existing file — so old tools open it as a perfectly normal (static) reconstruction, while a 4D-aware viewer unlocks a free 3D view + a draggable time axis.
Spec v1.0 — frozen. See the specification; Part I and the conformance goldens are normative, and changes follow the CHANGELOG.
colmap4d is an independent, community extension of the COLMAP output format. It is not affiliated with or endorsed by the COLMAP project; "COLMAP" is used only to name the format it extends.
| I want to… | go to |
|---|---|
| Read colmap4d data (the common case) | Quick start below — pip install colmap4d, three lines |
| Produce colmap4d data (convert / write) | docs/converters.md |
| Build a second implementation (C++/Rust/JS) | the spec: implement Part I, then pass every fixture in conformance/golden/ at the v1.0 tag |
| Contribute (human or AI agent) | CONTRIBUTING.md + AGENTS.md |
| Drive colmap4d from an AI agent | the colmap4d skill |
More detail: repository layout, dev commands & versioning.
Read a COLMAP model together with its time layer — zero dependencies:
import colmap4d
mv = colmap4d.load_model_view("path/to/sparse") # COLMAP model dir, with or without sidecars
mv.point_time(42) # -> t_ns (int64 ns), or None if the point is temporally-unbounded
mv.image_time(1) # -> t_ns, or None
mv.effective_points_t() # {point3d_id: t_ns}, dangling ids already dropped
mv.sidecars.time_meta # {"clock_domain": "utc_ntp", ...} or NoneJust the timestamps, without the base model: colmap4d.load_sidecars("path/to/sparse").
A plain COLMAP model (no sidecars) loads fine: empty times, all points temporally-unbounded —
the backward-compatibility baseline. The reader is standard-library only; pip install 'colmap4d[model]' adds pycolmap for authoritative parsing and 3.12 rigs/frames support.
Uploading time to a GPU (4DGS/NeRF)? Rebase first — raw epoch ns overflows float32; upload
(t − t0) seconds as float32 via colmap4d.rebase_to_seconds_f32(t, mv.t0_ns()).