Metadata-Version: 2.3
Name: page-dewarp
Version: 0.3.4
Summary: Page dewarping and thresholding using a cubic sheet model.
Keywords: computer vision,cubic spline,dewarping,document scanning,image correction,image processing
Author: Louis Maddox
Author-email: Louis Maddox <louismmx@gmail.com>
License: MIT
Classifier: Development Status :: 6 - Mature
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Dist: matplotlib
Requires-Dist: msgspec>=0.18.6
Requires-Dist: numpy>1.25
Requires-Dist: opencv-python
Requires-Dist: scipy
Requires-Dist: sympy
Requires-Dist: jax>=0.6.2 ; extra == 'jax'
Requires-Dist: jax[cuda12]>=0.6.2 ; extra == 'jax-cuda12'
Requires-Dist: jax[cuda13]>=0.8.0 ; python_full_version >= '3.11' and extra == 'jax-cuda13'
Requires-Python: >=3.10
Project-URL: Documentation, https://page-dewarp.vercel.app/
Project-URL: Homepage, https://github.com/lmmx/page-dewarp
Project-URL: Repository, https://github.com/lmmx/page-dewarp.git
Provides-Extra: jax
Provides-Extra: jax-cuda12
Provides-Extra: jax-cuda13
Description-Content-Type: text/markdown

# page-dewarp

[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![PyPI](https://img.shields.io/pypi/v/page-dewarp.svg)](https://pypi.org/project/page-dewarp)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/page-dewarp.svg)](https://pypi.org/project/page-dewarp)
[![downloads](https://static.pepy.tech/badge/page-dewarp/month)](https://pepy.tech/project/page-dewarp)
[![License](https://img.shields.io/pypi/l/page-dewarp.svg)](https://pypi.python.org/pypi/page-dewarp)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/lmmx/page-dewarp/master.svg)](https://results.pre-commit.ci/latest/github/lmmx/page-dewarp/master)

Document image dewarping library using a cubic sheet model.

Python 3 library for page dewarping and thresholding,
[available on PyPI](https://pypi.org/project/page_dewarp/).

A managed web version, **[Page Dewarp Web](https://page-dewarp-web.pages.dev)**, is also available for use from any device with a browser, with an API for programmatic web access.

## Installation

To install from PyPI, optionally using [uv](https://docs.astral.sh/uv/) (recommended), run:

```sh
uv pip install page-dewarp
```

### JAX

To install with JAX autodiff for ~11x faster optimisation on single images and ~33x faster for batches (CPU only), add the `jax` extra:

```sh
uv pip install page-dewarp[jax]
```

#### GPU support

To install with support for GPU execution instead of only CPU, choose one of:

```sh
uv pip install page-dewarp[jax-cuda12] # CUDA 12
uv pip install page-dewarp[jax-cuda13] # CUDA 13 (requires Python 3.11+)
```

> **Note**: CPU execution is the default `DEVICE` and can be faster than GPU for this workload, but this may vary
> depending on your relative CPU/GPU horsepower (cores, RAM, VRAM, etc.)

## Serial vs Batch

When the JAX backend is available, default behaviour when given multiple images is to use batch
mode. Performance benchmark on 40 images (via [#139](https://github.com/lmmx/page-dewarp/pull/139)):

| **Device** | **Serial** | **Batch** | **Speedup** |
|--------|--------|--------|--------|
| CPU | **36s** | **8.7s** | 4.1x |
| GPU | 53s | 11.2s | **4.7x**  |

## Dependencies

Python 3.10+ and NumPy, SciPy, SymPy, Matplotlib, OpenCV, and msgspec are required to run `page-dewarp`.

## Documentation

See the [docs site](https://page-dewarp.vercel.app) for full details, including a [How It Works](https://page-dewarp.vercel.app/how-it-works/Introduction/) walkthrough of the algorithm and a [configuration reference](https://page-dewarp.vercel.app/api/options).

## Usage

- See [config docs](https://page-dewarp.vercel.app/api/options) for a table of options

```
usage: page-dewarp [-h] [-d {0,1,2,3}] [-dd {file,screen,both}]
                   [-o OUTPUT_DIR] [-f OUTPUT_FORMAT] [-j OUTPUT_JSON]
                   [-it OPT_MAX_ITER] [-m OPT_METHOD] [-dev DEVICE]
                   [-b USE_BATCH] [-vw SCREEN_MAX_W] [-vh SCREEN_MAX_H]
                   [-x PAGE_MARGIN_X] [-y PAGE_MARGIN_Y] [-tw TEXT_MIN_WIDTH]
                   [-th TEXT_MIN_HEIGHT] [-ta TEXT_MIN_ASPECT]
                   [-tk TEXT_MAX_THICKNESS] [-tm TEXT_MORPH_OPS]
                   [-lm LINE_MORPH_OPS] [-wz ADAPTIVE_WINSZ] [-ri RVEC_IDX]
                   [-ti TVEC_IDX] [-ci CUBIC_IDX] [-sw SPAN_MIN_WIDTH]
                   [-sp SPAN_PX_PER_STEP] [-eo EDGE_MAX_OVERLAP]
                   [-el EDGE_MAX_LENGTH] [-ec EDGE_ANGLE_COST]
                   [-ea EDGE_MAX_ANGLE] [-fl FOCAL_LENGTH] [-z OUTPUT_ZOOM]
                   [-dpi OUTPUT_DPI] [-nb NO_BINARY] [-sh SHEAR_COST]
                   [-mc MAX_CORR] [-s REMAP_DECIMATE]
                   IMAGE_FILE_OR_FILES [IMAGE_FILE_OR_FILES ...]

positional arguments:
  IMAGE_FILE_OR_FILES   One or more images to process

options:
  -h, --help            show this help message and exit
  -d, --debug-level {0,1,2,3}
                        (type: int, default: 0)
  -dd, --debug-dest {file,screen,both}
                        (type: str, default: file)
  -o, --output-dir OUTPUT_DIR
                        Directory for output and debug images (type: str,
                        default: .)
  -f, --output-format OUTPUT_FORMAT
                        Output image format (e.g. png, tiff, bmp, jpeg) (type:
                        str, default: png)
  -j, --json OUTPUT_JSON
                        Write JSON sidecar with dewarp parameters (type: int,
                        default: 0)
  -it, --max-iter OPT_MAX_ITER
                        Maximum optimisation iterations (type: int, default:
                        600000)
  -m, --method OPT_METHOD
                        Name of the JAX/SciPy optimisation method to use.
                        (type: str, default: auto)
  -dev, --device DEVICE
                        Compute device to select for optimisation. (type: str,
                        default: auto)
  -b, --batch USE_BATCH
                        Whether to batch process images (JAX backend only).
                        (type: str, default: auto)
  -vw, --max-screen-width SCREEN_MAX_W
                        Viewing screen max width (for resizing to screen)
                        (type: int, default: 1280)
  -vh, --max-screen-height SCREEN_MAX_H
                        Viewing screen max height (for resizing to screen)
                        (type: int, default: 700)
  -x, --x-margin PAGE_MARGIN_X
                        Reduced px to ignore near L/R edge (type: int,
                        default: 50)
  -y, --y-margin PAGE_MARGIN_Y
                        Reduced px to ignore near T/B edge (type: int,
                        default: 20)
  -tw, --min-text-width TEXT_MIN_WIDTH
                        Min reduced px width of detected text contour (type:
                        int, default: 15)
  -th, --min-text-height TEXT_MIN_HEIGHT
                        Min reduced px height of detected text contour (type:
                        int, default: 2)
  -ta, --min-text-aspect TEXT_MIN_ASPECT
                        Filter out text contours below this w/h ratio (type:
                        float, default: 1.5)
  -tk, --max-text-thickness TEXT_MAX_THICKNESS
                        Max reduced px thickness of detected text contour
                        (type: int, default: 10)
  -tm, --text-morph TEXT_MORPH_OPS
                        Morphological ops for text mask (e.g. d_9_1,e_1_3)
                        (type: str, default: d_9_1,e_1_3)
  -lm, --line-morph LINE_MORPH_OPS
                        Morphological ops for line mask (e.g. e_3_1_3,d_8_2)
                        (type: str, default: e_3_1_3,d_8_2)
  -wz, --adaptive-winsz ADAPTIVE_WINSZ
                        Window size for adaptive threshold in reduced px
                        (type: int, default: 55)
  -ri, --rotation-vec-param-idx RVEC_IDX
                        Index of rvec in params vector (slice: pair of values)
                        (type: tuple[int, int], default: (0, 3))
  -ti, --translation-vec-param-idx TVEC_IDX
                        Index of tvec in params vector (slice: pair of values)
                        (type: tuple[int, int], default: (3, 6))
  -ci, --cubic-slope-param-idx CUBIC_IDX
                        Index of cubic slopes in params vector (slice: pair of
                        values) (type: tuple[int, int], default: (6, 8))
  -sw, --min-span-width SPAN_MIN_WIDTH
                        Minimum reduced px width for span (type: int, default:
                        30)
  -sp, --span-spacing SPAN_PX_PER_STEP
                        Reduced px spacing for sampling along spans (type:
                        int, default: 20)
  -eo, --max-edge-overlap EDGE_MAX_OVERLAP
                        Max reduced px horiz. overlap of contours in span
                        (type: float, default: 1.0)
  -el, --max-edge-length EDGE_MAX_LENGTH
                        Max reduced px length of edge connecting contours
                        (type: float, default: 100.0)
  -ec, --edge-angle-cost EDGE_ANGLE_COST
                        Cost of angles in edges (tradeoff vs. length) (type:
                        float, default: 10.0)
  -ea, --max-edge-angle EDGE_MAX_ANGLE
                        Maximum change in angle allowed between contours
                        (type: float, default: 7.5)
  -fl, --focal-length FOCAL_LENGTH
                        Normalized focal length of camera (type: float,
                        default: 1.2)
  -z, --output-zoom OUTPUT_ZOOM
                        How much to zoom output relative to *original* image
                        (type: float, default: 1.0)
  -dpi, --output-dpi OUTPUT_DPI
                        Just affects stated DPI of PNG, not appearance (type:
                        int, default: 300)
  -nb, --no-binary NO_BINARY
                        Disable output conversion to binary thresholded image
                        (type: int, default: 0)
  -sh, --shear-cost SHEAR_COST
                        Penalty against camera tilt (shear distortion). (type:
                        float, default: 0.0)
  -mc, --max-corrections MAX_CORR
                        Maximum corrections used to approximate the inverse
                        Hessian. (type: int, default: 100)
  -s, --shrink REMAP_DECIMATE
                        Downscaling factor for remapping image (type: int,
                        default: 16)
```

To try out an example image:

```sh
git clone https://github.com/lmmx/page-dewarp
cd page-dewarp
mkdir results && cd results
page-dewarp ../example_input/boston_cooking_a.jpg
```

See `page-dewarp --help` for the full list of options.

## Background

This library was renovated from the [original (2016) Python 2 script](https://github.com/mzucker/page_dewarp/)
by Matt Zucker. A book on a flat surface can be modelled as a cubic curve fixed to zero at its endpoints (see Matt's [original writeup](https://mzucker.github.io/2016/08/15/page-dewarping.html) and [`derive_cubic.py`](https://github.com/lmmx/page-dewarp/blob/master/derive_cubic.py) for the derivation).
