deskew

repository·master·Indexed 17 days ago

https://github.com/sbrunner/deskew

A Python library for detecting and correcting skew (rotation) in images containing text. It provides the `determine_skew` function to calculate rotation angles, a CLI for angle estimation and image correction, and debugging tools via `determine_skew_debug_images` to visualize the Hough transform process. The library integrates with scikit-image and OpenCV for applying image rotations.

Tokens
2.8K
Snippets
10
Records
11
Agent score
68%

What's inside deskew

  1. Debug skew detection with debug_images

    master

    If the detected skew angle is incorrect, you can generate debug images to inspect the detection process.

    1. Install the debug dependencies: pip install deskew[debug_images]
    2. Use the function determine_skew_debug_images to generate visual aids.
    3. Tune the following parameters to improve accuracy:
      • num_peaks (default is 20; try increasing this first)
      • angle_pm_90
      • min_angle
      • max_angle
      • min_deviation
      • sigma
  2. Implement deskewing with OpenCV

    master

    To deskew an image using OpenCV, use determine_skew on a grayscale version of the image. Because OpenCV's standard rotation might crop the image, you may need a custom rotation function (like the one provided in the example below) that calculates the new bounding box dimensions to accommodate the rotated content.

    import math
    import cv2
    import numpy as np
    from typing import Tuple, Union
    from deskew import determine_skew
    
    def rotate(
            image: np.ndarray, angle: float, background: Union[int, Tuple[int, int, int]]
    ) -> np.ndarray:
        old_width, old_height = image.shape[:2]
        angle_radian = math.radians(angle)
        width = abs(np.sin(angle_radian) * old_height) + abs(np.cos(angle_radian) * old_width)
        height = abs(np.sin(angle_radian) * old_width) + abs(np.cos(angle_radian) * old_height)
    
        image_center = tuple(np.array(image.shape[1::-1]) / 2)
        rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
        rot_mat[1, 2] += (width - old_width) / 2
        rot_mat[0, 2] += (height - old_height) / 2
        return cv2.warpAffine(image, rot_mat, (int(round(height)), int(round(width))), borderValue=background)
    
    image = cv2.imread('input.png')
    grayscale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    angle = determine_skew(grayscale)
    rotated = rotate(image, angle, (0, 0, 0))
    cv2.imwrite('output.png', rotated)
  3. Implement deskewing with scikit-image

    master

    To deskew an image using scikit-image, use determine_skew to find the angle and skimage.transform.rotate to apply the correction. Note that when rotating, you should set resize=True to ensure the image content is not cropped.

    import numpy as np
    from skimage import io
    from skimage.color import rgb2gray
    from skimage.transform import rotate
    from deskew import determine_skew
    
    image = io.imread('input.png')
    grayscale = rgb2gray(image)
    angle = determine_skew(grayscale)
    # Rotate and rescale to prevent cropping
    rotated = rotate(image, angle, resize=True) * 255
    io.imsave('output.png', rotated.astype(np.uint8))
  4. Detect skew angle with determine_skew()

    master

    The core function determine_skew calculates the skew angle of an image containing text. It typically expects a grayscale image as input.

    By default, the returned angle is between -45 and 45 degrees to prevent arbitrary changes to image orientation. If you require an angle between -90 and 90 degrees, set the angle_pm_90 argument to True.

    from deskew import determine_skew
    from skimage import io
    from skimage.color import rgb2gray
    
    image = io.imread('input.png')
    grayscale = rgb2gray(image)
    angle = determine_skew(grayscale)
    print(f"Detected angle: {angle}")
  5. Use the deskew CLI

    master

    The deskew command-line interface allows you to either detect the skew angle of an image or perform the deskewing operation directly.

    # Get the skew angle
    deskew input.png
    
    # Deskew an image and save to a specific output file
    deskew --output output.png input.png
  6. Generate debug images with determine_skew_debug_images()

    master

    Use determine_skew_debug_images() to visualize the internal steps of the skew detection process. This is useful for troubleshooting why a specific angle was chosen or why no angle was detected.

    Returns: Returns a tuple (angle_deg, debug_images) where:

    • angle_deg: float | None (the detected angle in degrees).
    • debug_images: A list of tuples (name, image_array) containing:
      • "hough_transform": A visualization of the Hough transform space.
      • "detected_lines": The original image with detected lines overlaid.
      • "polar_angles": Polar plots showing original and corrected angle frequencies.

    Note: This function requires cv2 (OpenCV) and matplotlib to be installed. It also attempts to use gm (GraphicsMagick) to flatten transparent backgrounds in the generated plots.

    Parameters: Identical to determine_skew(), but min_angle and max_angle are treated as degrees and converted to radians internally.

    from deskew import determine_skew_debug_images
    
    angle, debug_imgs = determine_skew_debug_images(image)
    
    for name, img in debug_imgs:
        print(f"Displaying debug image: {name}")
        # Use cv2.imshow or similar to view 'img'
  7. Calculate skew angle with determine_skew()

    master

    Use determine_skew() to find the rotation angle (in degrees) of text within an image. This is the primary high-level function for skew detection.

    Parameters:

    • image: Input image as a NumPy array (ImageType).
    • sigma: Standard deviation of the Gaussian filter used for edge detection (default: 3.0).
    • num_peaks: Number of peaks to detect in the Hough transform (default: 20).
    • num_angles: (Deprecated) Number of angles to consider. Use min_deviation instead.
    • angle_pm_90: If True, considers angles in the range [-180, 180] instead of [-90, 90].
    • min_angle: Minimum angle to consider (in degrees).
    • max_angle: Maximum angle to consider (in degrees).
    • min_deviation: Minimum deviation between angles (in degrees, default: 1.0).

    Returns:

    • float: The detected skew angle in degrees.
    • None: If no skew is detected.
    import numpy as np
    from deskew import determine_skew
    
    # Load your image as a numpy array
    image = np.array(your_image_data)
    
    # Calculate the skew angle
    angle = determine_skew(image, sigma=3.0, min_angle=-10, max_angle=10)
    
    if angle is not None:
        print(f"Detected skew angle: {angle} degrees")
    else:
        print("No skew detected")
  8. Get detailed skew data with determine_skew_dev()

    master

    Use determine_skew_dev() when you need more than just the final angle. It returns the angle in radians along with a detailed tuple containing the raw Hough transform data, peak data, and frequency distributions of detected angles.

    Returns: Returns a tuple (angle, data) where:

    • angle: np.float64 | None (the detected angle in radians).
    • data: A nested tuple containing:
      • hough_line_out: (hspace, angles, distances) from skimage.transform.hough_line.
      • hough_line_peaks_out: (hspace, angles_peaks, dists) from skimage.feature.hough_line_peaks.
      • all_freqs: (freqs_original, freqs) where both are dict[np.float64, int] mapping angles to their occurrence frequency.
    from deskew import determine_skew_dev
    
    angle_rad, data = determine_skew_dev(image)
    if angle_rad is not None:
        print(f"Angle in radians: {angle_rad}")
        # Access raw Hough data for custom analysis
        hspace, angles, distances = data[0]
  9. Reference the deskew CLI flags and options

    master

    The following flags are available when using the deskew command line interface:

    FlagDefaultDescription
    -o, --outputNoneOutput file path for the corrected image.
    --sigma3.0Blur strength (Gaussian sigma). Higher values reduce noise but may miss fine details.
    --num-peaks20Number of peaks to detect. More peaks can improve accuracy but increase processing time.
    --num-angles180The number of angles to check (search precision). Higher values provide better precision but are slower.
    --backgroundNoneBackground color for rotated image corners. Use a single value for grayscale or comma-separated RGB values (e.g., 255,255,255).
    input(Required)The input file name.
    # Example with custom parameters
    deskew input.jpg --output out.jpg --sigma 2.0 --num-peaks 30 --background 255,255,255
  10. Use the deskew CLI to detect skew angle or correct images

    master

    The deskew CLI allows you to either estimate the skew angle of a tilted image or save a corrected (rotated) version of that image.

    By default, if no output file is specified, the tool prints the estimated angle to the console. If an output path is provided via --output, the tool saves the rotated image.

    Usage

    # Estimate the angle and print to console
    deskew input_image.png
    
    # Rotate the image and save to a file
    deskew input_image.png --output corrected_image.png
    deskew input_image.png --output corrected_image.png