Document scanner for Python
Deskew, orient, enhance, PDF — locally. Nothing leaves the machine: no upload, no API key, no third party holding a copy of the document you just photographed.
pip install git+https://github.com/7RPlus-GmbH/pagescan
Why it exists
Detection, segmentation and enhancement all happen locally. The weights sit on disk; the photo never leaves the process.
One command per file, or a loop over ten thousand. No GUI, no desktop session, nothing to click — it belongs in a cron job.
MIT licensed and open weight, so a compliance review can read every line and every model that touched the page.
How pagescan reads a page
Stages 01–04 are model-driven and can fail. Both fallbacks rejoin the main flow, so 05–07 always run on the same contract.
01 · Locate the page
Finds the page.
ScanConfig() uses. The cascade is opt-in via
use_cascade=True.
Refines the edge.
Hull → polyDP.
Quad sanity checks.
02 · Rectify
Warp to a flat rectangle.
Upright the page.
03 · Finish
Shadow removal, white balance, sharpen.
The dashed boxes are fallbacks, not steps: a photo that detects and fits cleanly never touches them. Everything downstream of 04 receives the same shape either way, which is why a rejected quad degrades the result instead of failing the run.
Open weights
Detection, segmentation and orientation weights on Hugging Face under Apache-2.0 — audit them, fine-tune them, redistribute them. The library itself is MIT.
Detector. Finds the page in the photo and hands on a bounding box.
Segmenter. Turns the box into an edge accurate enough to fit a quad to. From SysCV’s sam-hq, Apache-2.0.
Orientation. Decides which way is up, so the rectified page comes out upright. From the OnnxTR project, Apache-2.0.
The corner-regression chain that runs by default — faster than the cascade and, on the current weights, more accurate on held-out photos. From DocsaidLab’s DocAligner, Apache-2.0.
Install & use
Command line
# not on PyPI yet — install from source $ pip install git+https://github.com/7RPlus-GmbH/pagescan $ pagescan photo.jpg output.pdf # a directory of photos, one PDF each $ pagescan --batch --input-dir photos/ \ --output-dir scans/ --workers 4 # crop and perspective only, no enhancement $ pagescan photo.jpg --raw
Python
import pagescan pagescan.scan("photo.jpg", "output.pdf") pagescan.scan_batch("input/", "output/") from pagescan import ScanConfig cfg = ScanConfig(jpeg_quality=60, deskew=True) pagescan.scan("photo.jpg", "out.pdf", config=cfg)