From ebadf40f3a6644218a2e608173c26c76ecdbf6b2 Mon Sep 17 00:00:00 2001 From: Josh Hall Date: Sat, 7 Nov 2026 22:58:56 +0200 Subject: [PATCH] docs: logo header, TOC, pipeline diagram, ADR table; add favicon at root and docs/ --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ docs/favicon.svg | 12 ++++++++++++ favicon.svg | 12 ++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 docs/favicon.svg create mode 100644 favicon.svg diff --git a/README.md b/README.md index e1f49ab..68196f3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +

Plane Projection logo

+ # Plane Projection [![CI](https://github.com/ofeq-dev/plane-projection/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ofeq-dev/plane-projection/actions/workflows/ci.yml) @@ -12,6 +14,19 @@ volume + one CSV plane-list → one `.mp4`, one frame per plane, in list order. ![Croissant projection frame](docs/images/example-run/croissant-row1.png) +## Contents + +- [The problem](#the-problem) +- [Scope](#scope) +- [Quick start](#quick-start) +- [How it works](#how-it-works) +- [Testing](#testing) +- [Performance](#performance) +- [Example runs & outputs](#example-runs--outputs) +- [Docs](#docs) +- [Repository layout](#repository-layout) +- [License](#license) + ## The problem > Given a 3D raster matrix `M` and a plane `p`, compute the 2D image of the @@ -36,6 +51,31 @@ Requirements, acceptance criteria and the exact frame geometry live in [`docs/srs.md`](docs/srs.md) and [`docs/algorithm.md`](docs/algorithm.md); terms are defined in [`GLOSSARY.md`](GLOSSARY.md). +## How it works + +```mermaid +flowchart LR + A["NRRD volume\n(8/16/32-bit)"] --> L["Volume loader"] + B["CSV plane list"] --> P["Parse + validate\n(3- or 4-point planes)"] + L --> R["Closest-voxel\nprojection renderer"] + P --> R + R --> F["Frame per plane\n(invalid → error frame)"] + F --> V["MP4 writer\n(OpenCV mp4v)"] +``` + +Each plane is parsed and validated against the isosceles-triangle / trapezoid +rules; valid planes are rendered by nearest-voxel sampling onto a canvas sized +to the largest plane in the list, and everything — good and bad frames — is +written to one MP4. The full frame geometry and rounding rules are in +[`docs/algorithm.md`](docs/algorithm.md); key implementation choices and why +they were made are in [`docs/adr/`](docs/adr/): + +| ADR | Decision | +|---|---| +| [0001](docs/adr/0001-store-volume-and-video-assets-in-git-lfs.md) | Store large volumes/videos in Git LFS | +| [0002](docs/adr/0002-canonical-voxel-index-space.md) | Canonical voxel-index space (no world-space headers) | +| [0004](docs/adr/0004-video-encoding-via-opencv-mp4v.md) | Video encoding via OpenCV `mp4v` (pip-only, no system ffmpeg) | + ## Scope **In scope:** NRRD volume input, CSV plane-list input, per-plane rendering, diff --git a/docs/favicon.svg b/docs/favicon.svg new file mode 100644 index 0000000..a1d567c --- /dev/null +++ b/docs/favicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 0000000..a1d567c --- /dev/null +++ b/favicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + +