8f5be59b7ec3483c6f6047560bf1c5a05d0de9b5
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.
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
- Record one continuous overhead video, placing documents under the camera one at a time (optionally saying out loud what each one is).
- PaperPod finds "stable windows" where nothing is moving, picks the sharpest frame in each, detects the document outline, and produces a perspective-corrected crop.
- (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 candidatesframes/window_NNN_full.png— the full best frame per window (debugging)report.json— video metadata, motion events, stable windows, detectionsmotion_scores.csv— per-sample motion scores, for tuningmotion.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.
Languages
Python
98.3%
Shell
1.7%