Python 如何围绕x、y和z轴将3d阵列(NXN)旋转x度?
我用numpy创建了一个3d阵列,我想知道如何通过自定义角度旋转它,而不仅仅是numpy的Python 如何围绕x、y和z轴将3d阵列(NXN)旋转x度?,python,numpy,multidimensional-array,rotatetransform,Python,Numpy,Multidimensional Array,Rotatetransform,我用numpy创建了一个3d阵列,我想知道如何通过自定义角度旋转它,而不仅仅是numpy的rot90功能。有人能帮忙吗 3d矩阵表示图像(如立方体或其他形状),即 编辑: 移动解决方案以回答查看该功能 这是在scipy中而不是在numpy中的原因是,将图像旋转90度只需改变数组的索引即可。但是,如果要将图像旋转任意角度,则必须处理插值,这会增加问题的复杂性。这是因为当您将原始图像旋转90度时,原始图像中的所有像素与旋转图像中的像素“完全对齐”。通常情况下,旋转图像时不会出现这种情况。必须创建一个
rot90
功能。有人能帮忙吗
3d矩阵表示图像(如立方体或其他形状),即
编辑:
移动解决方案以回答查看该功能
这是在scipy中而不是在numpy中的原因是,将图像旋转90度只需改变数组的索引即可。但是,如果要将图像旋转任意角度,则必须处理插值,这会增加问题的复杂性。这是因为当您将原始图像旋转90度时,原始图像中的所有像素与旋转图像中的像素“完全对齐”。通常情况下,旋转图像时不会出现这种情况。必须创建一个旋转矩阵,然后将该矩阵乘以数组。这是信息 旋转矩阵信息
< P>我认为你应该考虑一个“矢量”表示你的数据,而不是当前的“栅格”表示。 矢量表示意味着,不是每个“体素”都由其在网格中的位置定义,而是有一些具有实际三维坐标的体素列表 因此,不需要MxNxD矩阵,其中每个体素是一个“黑/白”点,而可以使用Mx3矩阵,其中每行是一个点,列是X、Y和Z 这样,您可以将该列表乘以3x3旋转矩阵,并获得另一个变换坐标列表
您仍然需要解决将这些矢量点(或直线,更好)“渲染”到光栅矩阵(像素或体素,但示例图像看起来像是3D信息已投影到2D空间)的问题。有很多方法可以做到这一点。经过一些尝试和错误,我想出了一些代码(0表示数组中为空,另一个数字表示填充体素)
def rotate(self, deg_angle, axis):
d = len(self.matrix)
h = len(self.matrix[0])
w = len(self.matrix[0][0])
min_new_x = 0
max_new_x = 0
min_new_y = 0
max_new_y = 0
min_new_z = 0
max_new_z = 0
new_coords = []
angle = radians(deg_angle)
for z in range(d):
for y in range(h):
for x in range(w):
new_x = None
new_y = None
new_z = None
if axis == "x":
new_x = int(round(x))
new_y = int(round(y*cos(angle) - z*sin(angle)))
new_z = int(round(y*sin(angle) + z*cos(angle)))
elif axis == "y":
new_x = int(round(z*sin(angle) + x*cos(angle)))
new_y = int(round(y))
new_z = int(round(z*cos(angle) - x*sin(angle)))
elif axis == "z":
new_x = int(round(x*cos(angle) - y*sin(angle)))
new_y = int(round(x*sin(angle) + y*cos(angle)))
new_z = int(round(z))
val = self.matrix.item((z, y, x))
new_coords.append((val, new_x, new_y, new_z))
if new_x < min_new_x: min_new_x = new_x
if new_x > max_new_x: max_new_x = new_x
if new_y < min_new_y: min_new_y = new_y
if new_y > max_new_y: max_new_y = new_y
if new_z < min_new_z: min_new_z = new_z
if new_z > max_new_z: max_new_z = new_z
new_x_offset = abs(min_new_x)
new_y_offset = abs(min_new_y)
new_z_offset = abs(min_new_z)
new_width = abs(min_new_x - max_new_x)
new_height = abs(min_new_y - max_new_y)
new_depth = abs(min_new_z - max_new_z)
rotated = np.empty((new_depth + 1, new_height + 1, new_width + 1))
rotated.fill(0)
for coord in new_coords:
val = coord[0]
x = coord[1]
y = coord[2]
z = coord[3]
if rotated[new_z_offset + z][new_y_offset + y][new_x_offset + x] == 0:
rotated[new_z_offset + z][new_y_offset + y][new_x_offset + x] = val
self.matrix = rotated
Rect_Prism创建MxNxD矩阵,但在本例中为NxN
打印时的输出和结果:
# # # # # # # # # # # #
# # # # # # #
# # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # # # # # # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # # # #
# # # #
# # # # # # # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # #
# # # # # # #
# # # # # #
# # # # # # # # # # # #
数组代表什么?图像?平面?线?你的问题的答案取决于数组应该是什么。@tehhowch它应该是一个3d图像(编辑后会出错)可能是像素/体素图像(或更具体地说是光栅图像)的复制品.旋转矩阵用于3D和矢量图形,但不能将1000x1000x3矩阵(1Mpix RGB图像)乘以2x2旋转矩阵。函数很棒!您是如何定义“矩阵”类的此函数使用样条插值,我使用torchvision.transforms.functional.rotate得到的结果与使用torchvision.transforms.rotate得到的结果截然不同,torchvision.transforms.functional.rotate默认使用双线性插值(样条插值没有选项)。还尝试了skimage.transform.rotate。得到的结果与torchvision和scipy.speechless不同。。。
cube = Rect_Prism(20, 20, 20) # creates a 3d array similar to above example, just bigger
cube.rotate(20, "x")
cube.rotate(60, "y")
# # # # # # # # # # # #
# # # # # # #
# # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # # # # # # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # # # #
# # # #
# # # # # # # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # #
# # # # # # #
# # # # # #
# # # # # # # # # # # #