Plane projections of 3D voxel volumes, from NRRD to MP4
One NRRD volume, one CSV plane-list, one MP4 — a frame per plane. Voxels are sampled with a closest-voxel rule, invalid planes fail loudly with an error frame in the video, and a 500³ uint8 volume renders well above the 30 FPS hard bar.
What it does
Everything from the exercise brief, with the engineering around it: typed seams, golden tests, and a reproducible benchmark harness.
NRRD volume loader
Reads 8-, 16- and 32-bit unsigned volumes up to 1024³ per axis
(v = M[x][y][z]), rendered with a fully vectorized
numpy path.
Plane validation
3-point planes must be isosceles (legs equal from the first point); 4-point planes must be an isosceles trapezoid. Invalid specs raise and produce a visible error frame.
Closest-voxel sampling
Each output pixel takes the nearest voxel centre on the plane — deliberately simple, axis-wise fast-path geometry keeps it quick.
MP4 via OpenCV
cv2.VideoWriter with the mp4v codec — pip-installable,
no system ffmpeg needed (ADR 0004), canonical 30 fps.
Tested & typed
pytest suite with golden-frame oracles, CLI and validation tests, plus
mypy --strict on the whole package.
Benchmark harness
bench.py measures load and render scopes separately, min-of-repeats,
with a dedicated encode probe and versioned results files.
Pipeline
One command, one video. Every stage is a seam that is tested in isolation.
volume.nrrd
3D unsigned voxel array, 8/16/32-bit
planes.csv
3 or 4 points per plane; validated on load
project()
Closest-voxel sampling → one 2D frame per plane
out.mp4
One frame per plane; error frames for invalid planes
# the brief's demo contract (SRS FR-1) $ python Ex0.py assets/nrrd/MRHead_1.nrrd assets/csv/lecturer_example.csv out.mp4
Demo videos
Real outputs of the tool, byte-for-byte as committed in assets/videos/.
Full frame-by-frame commentary lives in docs/example-run.md.
Quickstart
Python ≥ 3.12 (numpy 2.5 requires it). Everything is pip-installable.
# clone + set up $ git clone https://github.com/ofeq-dev/plane-projection.git $ cd plane-projection $ python -m venv .venv && . .venv/bin/activate $ pip install -r requirements.txt # render a video: volume + plane list → mp4 $ python Ex0.py assets/nrrd/MRHead_1.nrrd assets/csv/lecturer_example.csv out.mp4 # tests, typecheck, benchmark $ python -m pytest $ python bench.py assets/nrrd/croissant.nrrd assets/csv/croissant.csv --repeats 3
Benchmarks
Min-of-repeats wall time via time.perf_counter(); throughput =
rendered frames ÷ (load + render); encoding reported separately. Full methodology and all
31 runs in benchmarks/results-2026-11-07.md.
Machine: Intel i7-4650U (4 cores), Python 3.15.
| Input (volume × planes) | Frames | Load s | Render s | FPS (load+render) |
|---|---|---|---|---|
| croissant.nrrd × croissant.csv (canonical, 500³ uint8) | 100 | 0.878 | 1.116 | 50.1 ✓ NFR-1 hard bar |
| onion.nrrd × head.csv | 280 | 0.050 | 0.596 | 433.5 |
| MRHead_1.nrrd × head.csv | 280 | 0.087 | 0.650 | 380.2 |
| biscuit_cake.nrrd × biscuit_cake.csv | 120 | 0.091 | 0.339 | 278.6 |
| swiss_roll.nrrd × biscuit_cake.csv | 120 | 0.180 | 0.343 | 229.3 |
Run-to-run drift measured at 5.4% (criterion < 10%). The 100 FPS aspirational target was not met on this machine; the 30 FPS hard bar is met with margin on every comparable run.
Documentation
The full engineering story, from requirements to architecture decisions.
Software requirements
Functional and non-functional requirements, traced to the brief.
LIVEAlgorithm walkthrough
Interactive, plain-words tour of the frame geometry — hosted right here on this site.
SPECAlgorithm (full spec)
The complete frame-geometry spec: index space, plane coordinate frames, sampling, error frames.
TESTSTesting strategy
Seams, oracles, and the golden-frame protocol behind the pytest suite.
RUNExample run
A real run, frame by frame, with the exported videos and per-frame explanation.
ADRArchitecture decisions
LFS for assets, canonical index space, video encoding choice.