Skip to content

Instantly share code, notes, and snippets.

@Susensio
Forked from jsfenfen/output.png
Last active September 17, 2018 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Susensio/e2949da9702c444bb1407949822c8ccf to your computer and use it in GitHub Desktop.
Save Susensio/e2949da9702c444bb1407949822c8ccf to your computer and use it in GitHub Desktop.
Detecting rotation and line spacing of image of page of text using Radon transform
# -*- coding: utf-8 -*-
"""
Inspired in https://gist.github.com/jsfenfen/4c615775007b802117b7
Automatically detect rotation and line spacing of an image of text using
Fourier transforms
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)
"""
import numpy as np
import cv2 as cv
from scipy.ndimage import filters
import matplotlib.pyplot as plt
from matplotlib.mlab import rms_flat
filename = 'skew-linedetection.png'
# Load file, converting to grayscale
img = cv.imread(filename, 0)
plt.subplot(2, 2, 1)
plt.imshow(img)
# Do the 2D Fourier transform and display the result
# First apply 2D windowing
height, width = image.shape
window_matrix = np.outer(np.blackman(height), np.blackman(width))
windowed = image * window_matrix
# FFT 2D
fft = np.fft.fft2(image)
fft = np.fft.fftshift(f)
fft = np.log(np.abs(fshift))
# Reescale into a square shape to interpret angles properly
side = max(height, width)
fft = cv.resize(magnitude_spectrum, (side, side))
plt.subplot(2, 2, 2)
plt.imshow(fft)
# TO BE CONTINUED....
# 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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment