使用旋转矩阵将 2D 数组旋转一定角度

问题描述 投票:0回答:5

我想要做的是将 2D numpy 数组旋转给定角度。我采用的方法是使用旋转矩阵。我定义的旋转矩阵为:

angle = 65.
theta = (angle/180.) * numpy.pi

rotMatrix = numpy.array([[numpy.cos(theta), -numpy.sin(theta)], 
                         [numpy.sin(theta),  numpy.cos(theta)]])

我要旋转的矩阵形状为(1002,1004)。然而,仅出于测试目的,我创建了一个形状为 (7,6) 的 2D 数组

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]])

现在,当我在 2D 数组上应用旋转矩阵时,出现以下错误:

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):

我做错了什么?

python arrays matrix rotation 2d
5个回答
8
投票

您似乎正在寻找 scipy.ndimage.rotate 或类似的。如果您特别想要 90、180 或 270 度旋转(不需要插值),那么 numpy.rot90 更好。


7
投票

矩阵维度需要兼容才能获得矩阵乘积。您正在尝试将 7x6 矩阵与 2x2 矩阵相乘。这在数学上是不连贯的。只有对 2D 向量应用 2D 旋转以获得变换后的坐标才真正有意义。

仅当左手矩阵的列数等于右手矩阵的行数时,矩阵乘积的结果才被定义。


2
投票

您可能想查看skimage.transform。该模块有几个有用的功能,包括旋转。重写已经完成的事情是没有意义的。


1
投票

我想这里面有一个误会。您不能通过将图像与旋转矩阵相乘来旋转图像。您实际上需要做的是将包含图像坐标的矩阵(对于形状为

2 x (n*m)
的图像,形状为
n x m
)与旋转矩阵相乘。 这在 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()

0
投票

您无法使用 2D 矩阵旋转任何 ndim 向量。

我没有在 numpy 中找到内置函数。我希望这是一个非常常见的功能并且应该存在。如果你找到了请告诉我。

也就是说,我有自己的创建功能。

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


© www.soinside.com 2019 - 2024. All rights reserved.