-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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