如何高效地将一个数组旋转±180度?

8

如何在使用最少的内存和操作的情况下,使用C语言及其衍生语言(Python、Cython、纯C)对M×N的非正方形数组进行中心180度旋转的最佳算法是什么?


1
你是在问是否需要一个简单的np.flip()吗? - sascha
旋转180度被称为 "反转"。你是不是想说旋转90度? - DaBler
反转(reverse)如果你愿意的话,无论名称是什么,我的意思是180°。 - Aurélien Pierre
所以,下面的答案是不正确的,因为它显示了90度的旋转。 - DaBler
numpy.flip函数执行翻转操作。 - DaBler
显示剩余11条评论
2个回答

10
假设out是一个已初始化的array副本,MN是它们的行数和列数,我们使用从0到(M-1)和(N-1)的语言来索引数组:
在Python中:
def rotate_180(array, M, N, out):
    for i in range(M):
        for j in range(N):
            out[i, N-1-j] = array[M-1-i, j]

这需要在一个4000x3000的数组上花费5.82秒。

使用Memviews的并行化Cython + OpenMP:

cdef void rotate_180(float[:, :] array, int M, int N, float[:, :] out) nogil:

    cdef size_t i, j

    with parallel(num_threads=8):
        for i in prange(M):
            for j in range(N):
                out[i, N-1-j] = array[M-1-i, j]

这在一个4000×3000的数组上需要5.45秒。

相比之下,使用np.rot90(array, 2)的numpy只需要8.58微秒。

编辑:为了避免不相关的评论,这里是它的作用:

a = array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])

rotate_180(a, 3, 3, b)

b = array([[9, 8, 7],
           [6, 5, 4],
           [3, 2, 1]])

使用numpy内置函数进行2次连续的90°旋转,我们得到:
np.rot90(a, 2)

out = array([[9, 8, 7],
             [6, 5, 4],
             [3, 2, 1]])

所以这个rotate_180()确实是一个180度的旋转。现在:

np.flip(a, 0)

out = array([[7, 8, 9],
             [4, 5, 6],
             [1, 2, 3]])

这不是一个旋转,而是沿着最后一条线对称。如果我们沿着每个方向组合两个对称:

np.flip(np.flip(a, 1), 0)

out = array([[9, 8, 7],
             [6, 5, 4],
             [3, 2, 1]])

我们还可以进行180度旋转。

所以,是的,谢谢,我的代码确实做到了它所说的。


8

虽然回答这个问题有些晚了,但还是比什么都不做好。

对于形状为H x W的2D numpy数组:

rotated_array = old_array[::-1,::-1] #rotate the array 180 degrees

对于形状为H x W x 3的2D numpy图像:

rotated_image = image[::-1,::-1] #rotate the image 180 degrees

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接