Reputation: 4005
What I want to do is to rotate a 2D numpy array over a given angle. The approach I'm taking is using a rotation matrix. The rotation matrix I defined as:
angle = 65.
theta = (angle/180.) * numpy.pi
rotMatrix = numpy.array([[numpy.cos(theta), -numpy.sin(theta)],
[numpy.sin(theta), numpy.cos(theta)]])
The matrix I want to rotate is shaped (1002,1004). However, just for testing purposes I created a 2D array with shape (7,6)
c = numpy.array([[0,0,6,0,6,0], [0,0,0,8,7,0], [0,0,0,0,5,0], [0,0,0,3,4,0], [0,0,2,0,1,0], [0,8,0,0,9,0], [0,0,0,0,15,0]])
Now, when I apply the rotation matrix on my 2D array I get the following error:
c = numpy.dot(rotMatrix, c)
print c
c = numpy.dot(rotMatrix, c)
ValueError: matrices are not aligned
Exception in thread Thread-1 (most likely raised during interpreter shutdown):
What am I doing wrong?
Upvotes: 2
Views: 59738
Reputation: 420
You seem to be looking for scipy.ndimage.rotate, or similar. If you specifically want 90, 180, or 270 degree rotations, which do not require interpolation, then numpy.rot90 is better.
Upvotes: 8
Reputation: 306
I guess there is a misunderstanding. You cannot rotate an image by multiplying it with the rotation matrix. What you actually need to do is to multiply a matrix containing the image coordinates (of shape 2 x (n*m)
for an image of shape n x m
) with the rotation matrix.
This might look like this in numpy:
import numpy as np
image = np.arange(10000).reshape((100, 100))
theta = np.radians(180) # rotate 180 degrees
rot_matrix = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
# some steps to create coordinate matrix
x_len, y_len = image.shape
x_range = np.arange(x_len)
y_range = np.arange(y_len)
x_coords, y_coords = np.meshgrid(x_range, y_range)
coordinates = np.vstack([x_coords.flatten(), y_coords.flatten()])
# example for coordniates for image with shape n x n like:
# x: x0, x1, x2, ... xn-2, xn-1, xn
# y: y0, y1, y2, ... yn-2, yn-1, yn
# here we apply matrix multiplication
rotated_coordinates = rot_matrix @ coordinates
rotated_coordinates = rotated_coordinates.astype(int)
rotated_image = np.zeros(image.shape)
# This might generate missing values that need to be interpolated! Will be skipped here
rotated_image[rotated_coordinates[0], rotated_coordinates[1]] = image.flatten()
Upvotes: 1
Reputation: 376
You can not rotate any ndim vector using 2D matrix.
I did not find an in built function in numpy. I was hoping that this is a very common functionality and should be there. Let me know if you find it.
Mean while I have create function of my own.
def rotate(vector, theta, rotation_around=None) -> np.ndarray:
"""
reference: https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions
:param vector: list of length 2 OR
list of list where inner list has size 2 OR
1D numpy array of length 2 OR
2D numpy array of size (number of points, 2)
:param theta: rotation angle in degree (+ve value of anti-clockwise rotation)
:param rotation_around: "vector" will be rotated around this point,
otherwise [0, 0] will be considered as rotation axis
:return: rotated "vector" about "theta" degree around rotation
axis "rotation_around" numpy array
"""
vector = np.array(vector)
if vector.ndim == 1:
vector = vector[np.newaxis, :]
if rotation_around is not None:
vector = vector - rotation_around
vector = vector.T
theta = np.radians(theta)
rotation_matrix = np.array([
[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]
])
output: np.ndarray = (rotation_matrix @ vector).T
if rotation_around is not None:
output = output + rotation_around
return output.squeeze()
if __name__ == '__main__':
angle = 30
print(rotate([1, 0], 30)) # passing one point
print(rotate([[1, 0], [0, 1]], 30)) # passing multiple points
Upvotes: 0
Reputation: 772
You may want to look at skimage.transform. This module has several useful functions including rotation. No sense in rewriting something that is already done.
Upvotes: 2
Reputation: 21351
Matrix dimensions will need to be compatible in order to obtain a matrix product. You are trying to multiply a 7x6 matrix with a 2x2 matrix. This is not mathematically coherent. It only really makes sense to apply a 2D rotation to a 2D vector to obtain the transformed coordinates.
The result of a matrix product is defined only when the left hand matrix has column count equal to right hand matrix row count.
Upvotes: 7