Configuration#
All tunable parameters live on the ScanConfig dataclass. Construct one, pass it to scan() or scan_batch().
from pagescan import ScanConfig, scan
config = ScanConfig(jpeg_quality=80, auto_orient=False)
scan("photo.jpg", "out.pdf", config=config)
Field reference#
Background detection#
Field |
Type |
Default |
Purpose |
|---|---|---|---|
|
|
|
Lower HSV bound for background. Default targets warm wood ( |
|
|
|
Upper HSV bound for background. |
|
|
|
Stricter saturation minimum for edge detection. Prevents cream-coloured paper ( |
# Blue tablecloth instead of wood
ScanConfig(
background_hsv_low=(100, 50, 30),
background_hsv_high=(130, 255, 255),
)
Output dimensions#
Field |
Type |
Default |
Notes |
|---|---|---|---|
|
|
|
A4 width at 300 DPI. |
|
|
|
A4 height at 300 DPI. |
|
|
|
DPI tag written to the PDF. |
|
|
|
Margin around document on the output canvas. |
|
|
|
JPEG quality for PDF embedding. Lower = smaller file. |
# US Letter
ScanConfig(output_width=2550, output_height=3300)
Pipeline toggles#
Field |
Type |
Default |
What it controls |
|---|---|---|---|
|
|
|
OCR-based 90/180/270° rotation correction. Disable when input orientation is known. |
|
|
|
Hough-based skew correction for residual text tilt after perspective. |
|
|
|
Master switch for the enhancement stages. |
|
|
|
Illumination normalisation before enhancement. |
|
|
|
Push the paper background toward pure white. |
|
|
|
Master switch for ML-based corner detection. When |
ML detection path#
Field |
Type |
Default |
What it controls |
|---|---|---|---|
|
|
|
Use the YOLO + HQ-SAM cascade as the primary ML detection path. When |
|
|
|
Minimum YOLO confidence for accepting a detection. Below this, cascade falls through to legacy. |
|
|
|
Over-crop guard. Predicted quads with area below this fraction of the image are rejected as too small (typical failure: SAM segments an inner text block instead of the full page). Raise toward |
Debug#
Field |
Type |
Default |
Notes |
|---|---|---|---|
|
|
|
When |
|
|
|
Directory for debug output. Created if missing. |
Built-in presets#
The pagescan.config module exposes four preset configurations for the most common use cases:
Preset |
Equivalent of |
Use case |
|---|---|---|
|
|
Standard A4 office scan at 300 DPI. |
|
|
US Letter at 300 DPI. |
|
|
Headless / fast path. ~10× faster, slightly worse corner accuracy. |
|
|
Crop + perspective only. No tone changes — preserves original colours and texture. |
from pagescan import scan, PRESET_FAST
scan("photo.jpg", "out.pdf", config=PRESET_FAST)
Tuning guide#
“It’s cropping too aggressively”#
Raise the over-crop guard:
ScanConfig(min_doc_coverage=0.15)
Then pagescan.scan(...) rejects any quad smaller than 15% of the frame, falling back to the conservative contour path. This is the single most common knob to adjust.
“It’s not detecting the document at all”#
Lower the detector confidence threshold:
ScanConfig(detector_conf_threshold=0.10)
This accepts weaker YOLO detections. Risk: more false positives on document-like background objects.
“Whites are coming out grey”#
Enable white balance (default), or raise JPEG quality so the post-enhancement whites don’t get crushed:
ScanConfig(white_balance=True, jpeg_quality=80)
“Output looks oversaturated / cartoonish”#
Disable enhancement entirely:
ScanConfig(enhance=False)
# Or use the raw preset:
from pagescan import PRESET_RAW
“First scan is slow”#
That’s the one-time HF download (~50 MB cascade weights, ~360 MB HQ-SAM checkpoint). Subsequent scans use the cached copy. Pre-warm in a build step:
from pagescan.detector import _ensure_model as ensure_detector
from pagescan.segmenter import _ensure_model as ensure_sam
ensure_detector()
ensure_sam()