【问题标题】:rotate an nxnxn matrix in python在python中旋转一个nxnxn矩阵
【发布时间】:2015-06-12 04:47:56
【问题描述】:

我有一个大小为 64x64x64 的二进制数组,其中 40x40x40 的体积设置为“1”,其余为“0”。我一直在尝试使用skimage.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 的情况下,我尝试对立方体中的每个单独切片进行 2D 旋转(Cube[:,:,n=1,2,3...p])。

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

【问题讨论】:

  • 您可以使用用于[重新排列元素][docs.scipy.org/doc/numpy/reference/…numpy函数
  • 感谢 Kasra,但其目的是能够旋转,例如 22、45、90、135 等度数。我只能将重新排列元素用于 90,180,270... 角度。这是一个示例,但问题在于这些值是通过插值重新采样的。 stackoverflow.com/questions/4765341/how-can-i-rotate-a-3d-array
  • 我更新了我的帖子,但你能告诉我 imagej 旋转是否适用于所有角度以保持总和吗?不得不说imagej已经相当成熟了,他们在图像处理方面做得非常出色。

标签: python multidimensional-array rotation


【解决方案1】:

好的,我现在明白你在问什么了。我能想到的最接近的是 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) 

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

【讨论】:

  • 谢谢,我尝试使用 imagej 旋转 3D 堆栈图像,完全没有插值,最终得到与旋转前相同数量的值为“1”的像素。我想知道,如何在 python 中做到这一点。所以,基本上,我想围绕 z 轴旋转一个大小为 64x64x64 的 3D 数组,旋转原点位于数组的中心。没有任何过滤或插值。我对python很陌生,所以任何帮助都非常有用。谢谢!
  • 出于好奇,您在 imagej 中旋转了多少角度?
  • 抱歉耽搁了!作为一个测试用例,我尝试旋转一个 100x100 的正方形,将 60x60 像素设置为 1,或者在 ImageJ 的情况下设置为 255。这意味着,即使我们旋转整个数组以保持初始数组大小不变,我们也不会丢失该区域中的任何内容。因为 60*sqrt(2) =~85,与零的区域无关。以下是所有角度的测试用例。
  • 所以,我预计到处都是 60*60 =3600。在这里,图像被命名为“测试*角度”和总面积是:test0 3600 Test30 3600 Test40 3600 Test45 Test10 3596 Test20 3596 Test50 3696 Test50 3600 Test50 3600 Test45 3612 Test55 3596 Test60 3600 Test_65 3600 Test70 3596 Test75 3600 Test80 3596 Test85 3596 Test90 3600我试过Scipy .ndimage 之前,我想尽可能地关闭插值。我将顺序切换为 1。如何在没有任何过滤或插值的情况下进行旋转?
【解决方案2】:

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

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”值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多