Skip to main content

A fast deskew using hough line transform

Project description

Fast-deskew

CI PyPI Python License

A fast drop-in alternative to the excellent deskew library by sbrunner, using OpenCV instead of scikit-image for the heavy lifting. It estimates the skew angle of a document image so you can rotate it back to straight.

On sbrunner's own test set it returns the same angles while running ~9× faster (see Benchmark).

Before and after deskewing

Installation

  • Using pip:
pip install fast-deskew-cv
  • From source:
pip install git+https://git@github.com/HOZHENWAI/fast_deskew.git

Usage

import cv2
from deskew import determine_skew

image_grayscale = cv2.imread('input_image.png', cv2.IMREAD_GRAYSCALE)
skew_angle = determine_skew(image_grayscale)

determine_skew returns the skew angle in degrees (or None if no dominant orientation is found). To straighten the image, rotate it by +skew_angle:

import cv2
from deskew import determine_skew

image = cv2.imread('input_image.png')
grayscale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

angle = determine_skew(grayscale)
if angle is not None:
    height, width = image.shape[:2]
    matrix = cv2.getRotationMatrix2D((width / 2, height / 2), angle, 1.0)
    deskewed = cv2.warpAffine(image, matrix, (width, height),
                              borderValue=(255, 255, 255))
    cv2.imwrite('output_image.png', deskewed)

How it works

The classical Hough-transform skew-detection pipeline:

  1. Blur the image (Gaussian) to suppress noise.
  2. Canny edge detection — thresholds are derived from a percentile of the image's gradient magnitude, so the same defaults work across document sizes and contrasts.
  3. Hough line transform to find straight edges.
  4. Fold every line orientation into a canonical interval (so text baselines and vertical strokes, which differ by ~90°, reinforce the same estimate) and return the most frequent (modal) angle from the strongest lines.

Parameters

Parameter Default Description
image_array 8-bit single-channel (grayscale) image.
sigma 3.0 Standard deviation of the Gaussian pre-blur.
num_peaks 20 Number of strongest Hough lines used to vote on the angle.
angle_pm_90 False Fold into [-90, 90) instead of [-45, 45).
min_angle / max_angle None Restrict the reported skew to a degree range.
min_deviation 1.0 Angular resolution in degrees (also the voting bin width).
gradient_percentile 99.0 Gradient-magnitude percentile used as the high Canny threshold when auto-deriving.
canny_threshold_low / canny_threshold_high None Explicit Canny thresholds; None auto-derives them from the gradient.
hough_rho 1.0 Distance resolution of the Hough accumulator (pixels).
hough_threshold 30 Minimum Hough votes for a line (a floor; peak selection stays relative via num_peaks).

Benchmark

fast-deskew vs the reference deskew (1.6.1) on the reference library's own 8 test images. Both libraries receive the same grayscale array; timing is the median of repeated calls and excludes image loading. Angles are compared against the ground-truth values from the reference test suite.

Image Size Ground truth deskew fast-deskew Speed-up
1 6172×4152 −1.0° −1.0° / 2781 ms −1.0° / 320 ms 8.7×
2 1748×1241 −2.0° −2.0° / 300 ms −2.0° / 31 ms 9.7×
3 1748×1241 −6.0° −6.0° / 286 ms −6.0° / 27 ms 10.5×
4 1748×1241 7.0° 7.0° / 238 ms 7.0° / 30 ms 7.9×
5 724×1198 3.0° 3.0° / 103 ms 3.0° / 10 ms 10.1×
6 1415×1120 −3.0° −3.0° / 209 ms −3.0° / 20 ms 10.6×
7 575×336 3.0° 3.0° / 28 ms 3.0° / 3.5 ms 7.9×
8 3089×2435 15.0° 15.0° / 702 ms 15.0° / 73 ms 9.6×

Accuracy: 8/8 angles identical to the reference. Speed: ~9× faster (median).

Measured on Python 3.14, OpenCV 4.13, scikit-image 0.26, AMD64. Absolute timings are hardware-dependent; the relative speed-up is the meaningful figure.

Notes & limitations

  • Input is expected to be an 8-bit grayscale image (convert color images with cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) first).
  • For skews beyond ±45°/±90°, fix the global page rotation first and use this library for the residual fine skew. angle_pm_90=True widens the fold range.

Development

pip install -e ".[dev]"
pytest

License

MIT — see LICENSE.

Acknowledgements

Algorithm and test images from sbrunner/deskew.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fast_deskew_cv-1.0.1.tar.gz (8.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fast_deskew_cv-1.0.1-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file fast_deskew_cv-1.0.1.tar.gz.

File metadata

  • Download URL: fast_deskew_cv-1.0.1.tar.gz
  • Upload date:
  • Size: 8.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for fast_deskew_cv-1.0.1.tar.gz
Algorithm Hash digest
SHA256 407d912cf41e08d8e2b855b10fd9f6ecb2ae53770cc8d725dbcaef23c80d393d
MD5 c93e4f6b55824e0842f6883a122cc1c2
BLAKE2b-256 3febbeb7daa32a1697c7eea85c463500460fe543fac3f55a018a470ba2a9e36e

See more details on using hashes here.

File details

Details for the file fast_deskew_cv-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: fast_deskew_cv-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 6.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for fast_deskew_cv-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71b9e6cb0f06e700e1a436178296697ee449e72bb0bd434ac20339ff7e51280f
MD5 a2420987eb37b49690d08023cf8a3668
BLAKE2b-256 3927c1572692facb857c62daac4e30d211b037f78ab3443336647e93ad7b13d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page