ilia 8f5be59b7e Add realistic receipt test video generator
Renders three thermal-paper style receipts with real text (Home Depot,
Metro, Petro-Canada) placed one at a time on a black mat with hand motion
and drop shadows, matching the recommended real-world recording setup.
Verified: detect finds all 3 receipts, 7 stable windows, clean crops.
2026-07-07 17:11:28 -04:00

PaperPod

Local, privacy-first tool that converts a single overhead video recording of documents (receipts, letters, multi-page stacks) into individual, properly named PDFs ready for a Paperless-ngx consume folder. All processing runs offline on your machine.

How it works

  1. Record one continuous overhead video, placing documents under the camera one at a time (optionally saying out loud what each one is).
  2. PaperPod finds "stable windows" where nothing is moving, picks the sharpest frame in each, detects the document outline, and produces a perspective-corrected crop.
  3. (Upcoming) Spoken descriptions (faster-whisper) or OCR (Tesseract) name each document; multi-page stacks are grouped into single PDFs; a review step lets you rename/merge/split before export.

Status

Module Purpose Status
capture/ Frame sampling + audio extraction from video files Built
vision/ Motion detection, document contours, perspective crop, sharpness Built
events/ State machine: placed / page-flipped / cleared, pod grouping Planned
transcribe/ Local speech-to-text (faster-whisper) Planned
ocr/ OCR fallback naming (Tesseract) Planned
naming/ Final filename assembly + summary CSV Planned
pdf/ PDF assembly + Paperless-ngx consume staging Planned
review_cli/ Pre-export review (rename/merge/split) Planned

Setup

Requires Python 3.11+ and ffmpeg (brew install ffmpeg).

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Usage

# Generate a synthetic test video (no camera needed)
python sample_data/make_sample_video.py

# Inspect a video
python -m paperpod probe sample_data/videos/synthetic_sample.mp4

# Detect stable windows + document candidates
python -m paperpod detect sample_data/videos/synthetic_sample.mp4

# Extract the audio track (16 kHz mono WAV, whisper-ready)
python -m paperpod extract-audio my_recording.mp4

detect writes to output/<video-name>/:

  • crops/window_NNN.png — perspective-corrected document candidates
  • frames/window_NNN_full.png — the full best frame per window (debugging)
  • report.json — video metadata, motion events, stable windows, detections
  • motion_scores.csv — per-sample motion scores, for tuning motion.threshold

Tuning

All thresholds live in config.yaml (motion sensitivity, stable window duration, contour size floor, Canny thresholds, speech matching window, output paths). Plot motion_scores.csv to pick a motion.threshold that separates your camera's noise floor from real hand movement.

Tests

python -m pytest

Tests are self-contained: they synthesize frames and tiny videos on the fly, no sample assets required.

S
Description
Local privacy-first tool — overhead video of documents → named PDFs for Paperless-ngx
Readme MIT
222 KiB
Languages
Python 98.3%
Shell 1.7%