<!-- Generated by tools/build-machine-view.py from index.html. Do not edit by hand. -->

**DOCUMENT SCANNER FOR PYTHON**

# Phone photo in, deskewed print-ready PDF out.

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
```

```
$ pagescan photo.jpg output.pdf
INFO: Processing: photo.jpg
INFO: Detection: legacy
Saved: output.pdf
Quality: 0.87
```

**WHY IT EXISTS**

## Built for the documents you cannot upload.

01

### Runs on your machine

Detection, segmentation and enhancement all happen locally. The weights sit on disk; the photo never leaves the process.

02

### Headless and scriptable

One command per file, or a loop over ten thousand. No GUI, no desktop session, nothing to click — it belongs in a cron job.

03

### Made for regulated work

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**

## Seven stages, two escape hatches.

Stages 01–04 are model-driven and can fail. Both fallbacks rejoin the main flow, so 05–07 always run on the same contract.

Input photo source

**01 · LOCATE THE PAGE**

01

### YOLO11 detector

Finds the page.

bbox

DefaultSA24 + LCNet — on the current weights this chain beats the cascade on the held-out benchmark (44/50 vs 35/50 at IoU ≥ 0.90) and runs ~75× faster, so it is what ScanConfig() uses. The cascade is opt-in via use_cascade=True.

02

### HQ-SAM ViT-B segmenter

Refines the edge.

mask

03

### Quad fit

Hull → polyDP.

4 corners

04

### Validate & repair

Quad sanity checks.

valid

**02 · RECTIFY**

05

### Perspective transform

Warp to a flat rectangle.

flat page

AltContour fallback — no usable quad, so the page is cropped to its bounding box instead.

06

### Orientation correction

Upright the page.

upright

**03 · FINISH**

07

### Enhancement

Shadow removal, white balance, sharpen.

300 dpi

PDF output output

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**

## Every model that touches the page, published.

Detection, segmentation and orientation weights on Hugging Face under Apache-2.0 — audit them, fine-tune them, redistribute them. The library itself is MIT.

YOLO11n

Detector. Finds the page in the photo and hands on a bounding box.

HQ-SAM ViT-B

Segmenter. Turns the box into an edge accurate enough to fit a quad to. From SysCV’s sam-hq, Apache-2.0.

MobileNetV3 small

Orientation. Decides which way is up, so the rectified page comes out upright. From the OnnxTR project, Apache-2.0.

FastViT-SA24 + LCNet100

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**

## One command per page.

**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)
```

© 2026 7R+ GmbH · MIT

---

Human-readable version: https://pagescan.7rplus.com/
Source: https://github.com/7RPlus-GmbH/pagescan
Docs: https://7rplus-gmbh.github.io/pagescan/
Licence: MIT (library) · Apache-2.0 (model weights)
Publisher: 7R+ GmbH
