diff --git a/.gitignore b/.gitignore index 4c01e19..fb9c456 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,8 @@ *.mkv *.mp4 *.avi -.venv/ \ No newline at end of file +.venv/ +#demos +!demo_changes.png +!demo.jpg +!line500fps32pix.mp4 \ No newline at end of file diff --git a/demo.jpg b/demo.jpg new file mode 100644 index 0000000..5500127 Binary files /dev/null and b/demo.jpg differ diff --git a/demo_changes.png b/demo_changes.png new file mode 100644 index 0000000..0fe33f4 Binary files /dev/null and b/demo_changes.png differ diff --git a/line500fps32pix.mp4 b/line500fps32pix.mp4 new file mode 100644 index 0000000..87db625 Binary files /dev/null and b/line500fps32pix.mp4 differ diff --git a/readme.md b/readme.md index bdbeabe..35067d0 100644 --- a/readme.md +++ b/readme.md @@ -2,89 +2,45 @@ A digital implementation of **strip photography** (also called **slit photography**) that captures a two-dimensional image as a sequence of one-dimensional images over time. -**How it works:** -Strip photography records a moving scene over time using a camera that observes a narrow strip rather than the full field. This implementation simulates the technique by extracting the same line position from each video frame and assembling them into a composite image where: +![demo](demo.png) + +Strip photography records a moving scene over time by extracting the same line position from each video frame and assembling them into a composite image where: - One axis represents **space** (the slit/line being observed) - The other axis represents **time** (progression through video frames) - -**Visual effects:** -- Moving objects appear as visible shapes in the final image -- Stationary objects (like background) appear as horizontal/vertical stripes +- Moving objects appear as visible shapes, stationary objects as stripes - Object width is inversely proportional to speed (faster = narrower, slower = wider) ## Usage -**Column Mode** - Extract vertical lines (columns) from each frame: +**Row Mode** - Extract horizontal lines with threshold filtering: ```bash -uv run main.py test1.mkv --xcolumn 100 --output test1_column.png +uv run main.py .\line500fps32pix.mp4 --yrow 16 --output demo.jpg --threshold 0.005 ``` -**Row Mode** - Extract horizontal lines (rows) from each frame: +**Debug Mode** - Analyze changes and generate threshold recommendations: ```bash -uv run main.py test1.mkv --yrow 200 --output test1_row.png +uv run main.py .\line500fps32pix.mp4 --yrow 16 --output demo.jpg --debug ``` +![debug view](demo_changes.png) -**Debug Mode** - Analyze changes and generate threshold graph: -```bash -uv run main.py test1.mkv --xcolumn 100 --output analysis --debug -``` - -**Custom Threshold** - Control compression by setting change threshold: -```bash -uv run main.py test1.mkv --xcolumn 100 --output test1_column.png --threshold 0.01 -``` - -## Configure -We use uv to handle pip dependencies. Install with: +## Setup +Install dependencies with uv: ```bash uv sync ``` -## Output -- **Column mode**: Extracts vertical line at x-coordinate from each frame - - Output dimensions: `(source_height, total_frames, 3)` - - Width = number of frames, Height = source video height -- **Row mode**: Extracts horizontal line at y-coordinate from each frame - - Output dimensions: `(total_frames, source_width, 3)` - - Width = source video width, Height = number of frames +## Output Modes +- **Column mode**: Extracts vertical line (`--xcolumn`) → Width = frames, Height = video height +- **Row mode**: Extracts horizontal line (`--yrow`) → Width = video width, Height = frames -Each column/row in the output represents one frame from the input video, showing motion over time. +## Features -## Advanced Features +**Change Detection**: Automatically filters frames with minimal changes using configurable thresholds +- Use `--threshold` (0-1) to control sensitivity +- `--debug` mode provides threshold recommendations and change analysis +- Higher thresholds = more compression, fewer frames -### Change Detection & Compression -The implementation includes intelligent change detection that discards frames with minimal visual changes, creating more compact outputs that focus on motion: - -- **Automatic filtering**: Only frames with significant changes are included -- **Configurable threshold**: Use `--threshold` (0-1) to control sensitivity -- **Compression stats**: Shows how many frames were kept vs. skipped - -### Debug Mode -Use `--debug` to analyze your video and determine optimal threshold values: - -```bash -uv run main.py video.mp4 --xcolumn 500 --output analysis --debug -``` - -This generates: -- **Change graph**: Visual plot of frame-to-frame changes over time -- **Statistics**: Mean, max, min, and standard deviation of changes -- **Threshold suggestions**: Recommended values with compression ratios - -### Threshold Selection Guide -- **0.001-0.005**: High sensitivity, keeps most motion (10-30% compression) -- **0.005-0.02**: Medium sensitivity, good balance (30-70% compression) -- **0.02-0.1**: Low sensitivity, only major changes (70-95% compression) -- **>0.1**: Very low sensitivity, minimal frames (95%+ compression) - -### Examples with Compression - -Extract with 75% compression (recommended starting point): -```bash -uv run main.py video.mp4 --xcolumn 320 --output compressed.png --threshold 0.01 -``` - -Maximum compression for detecting only major scene changes: -```bash -uv run main.py video.mp4 --xcolumn 320 --output minimal.png --threshold 0.05 -``` \ No newline at end of file +**Threshold Guide**: +- `0.001-0.005`: High sensitivity (10-30% compression) +- `0.005-0.02`: Medium sensitivity (30-70% compression) +- `0.02+`: Low sensitivity (70%+ compression)