Skip to content

About

Degrade document images (fax, wrinkles, low-res, noise) for OCR robustness testing

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

imagedown-cli

English | 日本語

A command line tool that deliberately degrades document images for OCR robustness testing. It can produce low-resolution 1-bit pages that look like they came through a fax machine, paper that is partly crumpled or creased so the text collapses, low-quality JPEG re-encodes, sensor noise, uneven lighting, and any chain of these.

Original fax (204x98 dpi, 1-bit, streaks)
original fax
wrinkle (part of the page crumpled) fold (sharp creases)
wrinkle fold
preset crumpled-fax lowres → wrinkle → fold → fax --mode fine
crumpled-fax chain

Every preset at a glance (imagedown sample.png --suite out/):

contact sheet

Installation

uv tool install git+https://github.com/mshk/imagedown-cli
imagedown --help

Or clone it for development:

git clone https://github.com/mshk/imagedown-cli.git
cd imagedown-cli
uv sync
uv run imagedown --help

Requires Python 3.10+. Dependencies are Pillow, NumPy and click.

Usage

Effects are sub-commands and are applied left to right.

# Fax look: 204x98 dpi, 1-bit, horizontal streaks, slight skew
imagedown scan.png fax
# -> scan_degraded.png

# Halve the resolution, crumple, crease, then fax at "fine" resolution
imagedown scan.png -o out.png --seed 1 lowres --scale 0.5 wrinkle --strength 15 fold --count 1 fax --mode fine

# Process a whole directory
imagedown scans/ -o degraded/ preset crumpled-fax

# Generate every preset (handy for building an OCR test set)
imagedown scan.png --suite variants/
imagedown --list-presets

--seed makes the random effects (noise, lighting, fax, wrinkle, fold) reproducible. Each of those also accepts its own --seed to override the base seed.

Effects

Command What it does Main options
lowres Downscale, then upscale back (resolution loss) --scale, --resample nearest|bilinear|bicubic
blur Gaussian blur (out of focus) --radius
noise Gaussian noise plus salt-and-pepper speckle --amount, --salt-pepper
jpeg Low-quality JPEG re-encoding (block artifacts) --quality, --passes
rotate Small rotation (skewed feed) --angle
ink Ink bleed (positive spread), thinning (negative), or fading --spread, --fade, --threshold
lighting Uneven illumination and vignette (phone photo) --strength, --cells, --vignette
fax Fax transmission: 204x98/196 dpi, binarization, streaks, dropped lines, skew, speckle --mode standard|fine|superfine, --source-dpi, --threshold, --dither, --streaks, --dropouts, --skew, --speckle
wrinkle Crumple part of the page (warp + shading) --strength, --cells, --coverage, --light
fold Sharp fold lines; text near the crease gets squeezed and broken --count, --depth, --width, --light
preset Apply a named recipe (see --list-presets) NAME

Run imagedown <command> --help for the full option list of any effect.

How fax works

A standard ITU-T T.4 fax scans at 204 dpi horizontally and 98 dpi vertically (196 dpi in fine mode) and binarizes the page to 1 bit. Pass the assumed resolution of your input with --source-dpi; the image is downscaled anisotropically by that ratio, thresholded (or dithered with --dither), decorated with streaks and dropped lines in fax pixel space, then scaled back with nearest-neighbour so the receiving machine's blocky dots are preserved.

How wrinkle and fold work

Both build a height map of the paper surface: ridged multi-octave noise for wrinkle, exponential ridges along random lines for fold. The gradient of that map becomes a displacement field that re-samples the image (squeezing and stretching glyphs), and the slope under a random light direction produces Lambert-style shading so raised paper is lit and valleys fall into shadow. --coverage limits wrinkle to a soft random blob, leaving the rest of the document readable.

Development

uv run pytest
uv run python scripts/make_sample.py samples/sample.png   # synthetic invoice for trying things out
uv run imagedown samples/sample.png --suite samples/suite --seed 1
uv run python scripts/contact_sheet.py samples/suite samples/contact_sheet.png

License

MIT License. See LICENSE.

About

Degrade document images (fax, wrinkles, low-res, noise) for OCR robustness testing

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages