在python中旋转NXN矩阵

在python中旋转NXN矩阵,python,multidimensional-array,rotation,Python,Multidimensional Array,Rotation,我有一个大小为64x64x64的二进制数组,其中40x40x40的卷设置为1,其余为0。我一直在尝试使用skiliage.transform.rotate和Opencv围绕z轴旋转此立方体,如下所示: def rotateImage(image, angle): row, col = image.shape center = tuple(np.array([row, col]) / 2) rot_mat = cv2.getRotationMatrix2D(center,

我有一个大小为64x64x64的二进制数组,其中40x40x40的卷设置为1,其余为0。我一直在尝试使用skiliage.transform.rotate和Opencv围绕z轴旋转此立方体,如下所示:

def rotateImage(image, angle):
    row, col = image.shape
    center = tuple(np.array([row, col]) / 2)
    rot_mat = cv2.getRotationMatrix2D(center, angle, 1.0)
    new_image = cv2.warpAffine(image, rot_mat, (col, row))
    return new_image
在openCV的例子中,我尝试了对立方体中的每个I个切片进行2D旋转[:,:,n=1,2,3…p]


旋转后,数组中值的总和将发生变化。这可能是由旋转期间的插值引起的。如何在不向阵列添加任何内容的情况下旋转此类3D阵列?

好的,我现在明白您的要求了。我能想到的最接近的是scipy.ndimage。但是有一种方法可以更容易地从python与imagej进行接口。但以下是我对scipy.ndimage所做的:

    from scipy.ndimage import interpolation
    angle = 25 #angle should be in degrees
    Rotatedim = interpolation.rotate(yourimage, angle, reshape = False,output = np.int32, order = 5,prefilter = False) 

这对某些角度有效,以保留某些角度而不是其他角度,也许通过更多地使用参数,您可以获得所需的结果。

一个选项是转换为稀疏,并使用矩阵旋转变换坐标。然后转换回稠密状态。在二维中,这看起来像:

import numpy as np
import scipy.sparse
import math


N = 10
space = np.zeros((N, N), dtype=np.int8)
space[3:7, 3:7].fill(1)
print(space)
print(np.sum(space))

space_coo = scipy.sparse.coo_matrix(space)
Coords = np.array(space_coo.nonzero()) - 3

theta = 30 * 3.1416 / 180

R = np.array([[math.cos(theta), math.sin(theta)], [-math.sin(theta), math.cos(theta)]])
space2_coords = R.dot(Coords)
space2_coords = np.round(space2_coords)
space2_coords += 3
space2_sparse = scipy.sparse.coo_matrix(([1] * space2_coords.shape[1], (space2_coords[0], space2_coords[1])), shape=(N, N))
space2 = space2_sparse.todense()
print(space2)
print(np.sum(space2))
输出:

[[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 1 1 1 0 0 0]
 [0 0 0 1 1 1 1 0 0 0]
 [0 0 0 1 1 1 1 0 0 0]
 [0 0 0 1 1 1 1 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
16
[[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]
 [0 0 1 1 1 1 0 0 0 0]
 [0 0 1 1 1 1 1 0 0 0]
 [0 1 1 0 1 1 0 0 0 0]
 [0 0 0 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
16

这样做的好处是,在变换之前和之后,您将获得相同数量的1值。缺点是,您可能会得到如上所述的“孔”和/或重复坐标,在最终密集矩阵中给出“2”的值。

您可以使用用于[重新排列元素]的numpy函数[谢谢Kasra,但目的是能够旋转,比如说22、45、90、135度等等。我只能对90180270…角度使用重新排列元素。这里是一个例子,但问题是这些值是通过插值重新采样的。我更新了我的帖子,但是你能告诉我imagej旋转是否适用于所有角度到保留总和?我必须说imagej非常成熟,他们在图像处理方面做得非常出色。谢谢,我尝试使用imagej旋转3D堆栈图像,但没有任何插值,结果得到的像素数量与旋转前相同,值为1。我想知道,如何在python中实现这一点。因此,基本上,我想围绕z轴旋转一个大小为64x64x64的3D数组,旋转原点位于数组的中心。没有任何过滤或插值。我对python非常陌生,所以任何帮助都非常有用。谢谢!出于好奇,你在imagej中旋转了多大角度?抱歉,延迟了!作为一个测试案例,我尝试了旋转一个100x100的正方形,使用h 60x60像素设置为1,或者在ImageJ的情况下设置为255。这意味着,即使我们旋转整个阵列以保持初始阵列大小不变,我们也不会丢失1区域中的任何内容。因为60*sqrt2=~85,并且带零的区域不相关。以下是所有角度的测试案例。因此,我希望所有位置都是60*60=3600。h在这里,图像名为test*angle,总面积为:test0 3600 test30 3600 test40 3600 test45 3612 test10 3596 test20 3596 test50 3600 test45 3612 test55 3596 test60 3600 test_65 3600 test70 3596 test75 3600 test80 3596 test85 3596 test90 3600我以前试过scipy.ndimage,我想尽可能地关闭插值我把顺序改成了1。我怎么能在没有任何过滤或插值的情况下进行旋转呢?