# How to align images of different orientations using python

See my original post on stackoverflow:

First Approach: To find the axis and with that the angle of your line I suggest to use a PCA on the non-zero values:

``````from scipy.ndimage.interpolation import rotate
#from skimage.transform import rotate ## Alternatively
from sklearn.decomposition.pca import PCA ## Or use its numpy variant
import numpy as np

def verticalize_img(img):
"""
Method to rotate a greyscale image based on its principal axis.

:param img: Two dimensional array-like object, values > 0 being interpreted as containing to a line
:return rotated_img:
"""# Get the coordinates of the points of interest:
X = np.array(np.where(img > 0)).T
# Perform a PCA and compute the angle of the first principal axes
pca = PCA(n_components=2).fit(X)
angle = np.arctan2(*pca.components_)
# Rotate the image by the computed angle:
rotated_img = rotate(img,angle/pi*180-90)
return rotated_img``````

As usually this function could also be written as one-liner:

``rotated_img = rotate(img,np.arctan2(*PCA(2).fit(np.array(np.where(img > 0)).T).components_)/pi*180-90)``

And here is an example:

``````from matplotlib import pyplot as plt
# Example data:
img = np.array([[0,0,0,0,0,0,0],
[0,1,0,0,0,0,0],
[0,0,1,1,0,0,0],
[0,0,0,1,1,0,0],
[0,0,1,0,0,1,0],
[0,0,0,0,0,0,1]])
# Or alternatively a straight line:
img = np.diag(ones(15))
img = np.around(rotate(img,25))

# Or a distorted blob:
from sklearn import cluster, datasets
X, y = datasets.make_blobs(n_samples=100, centers = [[0,0]])
distortion = [[0.6, -0.6], [-0.4, 0.8]]
rotation = np.array(((cos(theta),-sin(theta)), (sin(theta), cos(theta))))
X =  np.dot(np.dot(X, distortion),rotation)
img = np.histogram2d(*X.T) # > 0 ## uncomment for making the example binary

rotated_img = verticalize_img(img)
# Plot the results
plt.matshow(img)
plt.title('Original')
plt.matshow(rotated_img)
plt.title('Rotated'))``````

Note that for highly noisy data or images with no clear orientation this method will come up with arbitrary rotations.

And here is an example output:

Second Approach: Ok after clarification of the actual task in a more complicated setting (see comments) here a second approach based on template matching:

``````from matplotlib import pyplot as plt
import numpy as np
import pandas
from scipy.ndimage.interpolation import rotate
from scipy.signal import correlate2d#, fftconvolve
# Data from CSV file: