Skip to content

Instantly share code, notes, and snippets.

@svaksha
Forked from endolith/output.png
Created December 2, 2020 08:34
Show Gist options
  • Save svaksha/da4f0774cd2f30ed98aa18c443fd79c1 to your computer and use it in GitHub Desktop.
Save svaksha/da4f0774cd2f30ed98aa18c443fd79c1 to your computer and use it in GitHub Desktop.

Revisions

  1. @endolith endolith revised this gist May 24, 2014. No changes.
  2. @endolith endolith revised this gist May 24, 2014. 2 changed files with 0 additions and 0 deletions.
    Binary file added output.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added skew-linedetection.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  3. @endolith endolith created this gist May 24, 2014.
    71 changes: 71 additions & 0 deletions rotation_spacing.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    # -*- coding: utf-8 -*-
    """
    Automatically detect rotation and line spacing of an image of text using
    Radon transform
    If image is rotated by the inverse of the output, the lines will be
    horizontal (though they may be upside-down depending on the original image)
    It doesn't work with black borders
    """

    from __future__ import division, print_function
    from skimage.transform import radon
    from PIL import Image
    from numpy import asarray, mean, array, blackman
    import numpy
    from numpy.fft import rfft
    import matplotlib.pyplot as plt
    from matplotlib.mlab import rms_flat
    try:
    # More accurate peak finding from
    # https://gist.github.com/endolith/255291#file-parabolic-py
    from parabolic import parabolic

    def argmax(x):
    return parabolic(x, numpy.argmax(x))[0]
    except ImportError:
    from numpy import argmax

    filename = 'skew-linedetection.png'

    # Load file, converting to grayscale
    I = asarray(Image.open(filename).convert('L'))
    I = I - mean(I) # Demean; make the brightness extend above and below zero
    plt.subplot(2, 2, 1)
    plt.imshow(I)

    # Do the radon transform and display the result
    sinogram = radon(I)

    plt.subplot(2, 2, 2)
    plt.imshow(sinogram.T, aspect='auto')
    plt.gray()

    # Find the RMS value of each row and find "busiest" rotation,
    # where the transform is lined up perfectly with the alternating dark
    # text and white lines
    r = array([rms_flat(line) for line in sinogram.transpose()])
    rotation = argmax(r)
    print('Rotation: {:.2f} degrees'.format(90 - rotation))
    plt.axhline(rotation, color='r')

    # Plot the busy row
    row = sinogram[:, rotation]
    N = len(row)
    plt.subplot(2, 2, 3)
    plt.plot(row)

    # Take spectrum of busy row and find line spacing
    window = blackman(N)
    spectrum = rfft(row * window)
    plt.plot(row * window)
    frequency = argmax(abs(spectrum))
    line_spacing = N / frequency # pixels
    print('Line spacing: {:.2f} pixels'.format(line_spacing))

    plt.subplot(2, 2, 4)
    plt.plot(abs(spectrum))
    plt.axvline(frequency, color='r')
    plt.yscale('log')
    plt.show()