我有一个3Dnumpy数组shape=(50, 50, 50)
,我想绕中心旋转,使用旋转矩阵R。
我正在尝试使用scipy.ndimage.affine_transform
来实现这一点,但我愿意接受更好的建议。
这是显示问题的代码:
import random
import numpy as np
import scipy
from PIL import Image
R = np.array([
[ 0.299297976, -0.817653322, -0.491796468],
[-0.425077904, -0.575710904, 0.698473858],
[-0.854242060, 0, -0.519875469],
])
print('Is R really orthogonal:', np.allclose(np.dot(R, R.T), np.identity(3))) # True
# initialize some random data:
a = (50 + np.random.rand(50, 50, 50)*200).astype(np.uint8)
print(a.shape) # (50, 50, 50)
Image.fromarray(a[:, :, 25]).show()
b = scipy.ndimage.affine_transform(a, R, offset=0)
Image.fromarray(b[:, :, 25]).show()
c = scipy.ndimage.affine_transform(a, R, offset=(50, 50, 50))
Image.fromarray(c[:, :, 25]).show()
字符串
x1c 0d1x的数据
的
的
令我意想不到的是:
- 以偏移量
0
旋转似乎不会围绕中心旋转 - 看最后一幅图像,这个矩阵所做的操作不仅仅是旋转,还有某种扭曲/剪切
我错过了什么?
编辑:@Nin17的答案是正确的,这是适应原始(3D)问题的版本:
import random
import numpy as np
import scipy
from PIL import Image
R = np.array([
[ 0.299297976, -0.817653322, -0.491796468, 0.],
[-0.425077904, -0.575710904, 0.698473858, 0.],
[-0.854242060, 0., -0.519875469, 0.],
[ 0., 0., 0., 1.],
])
N = 50
shift = np.array(
[
[1, 0, 0, N / 2],
[0, 1, 0, N / 2],
[0, 0, 1, N / 2],
[0, 0, 0, 1],
]
)
unshift = np.array(
[
[1, 0, 0, -N / 2],
[0, 1, 0, -N / 2],
[0, 0, 1, -N / 2],
[0, 0, 0, 1],
]
)
print('Is R orthogonal:', np.allclose(np.dot(R, R.T), np.identity(4))) # True
a = (50 + np.random.rand(N, N, N)*200).astype(np.uint8)
print(a.shape) # (50, 50, 50)
Image.fromarray(a[:, :, N//2]).show()
b = scipy.ndimage.affine_transform(a, shift @ R @ unshift, offset=0)
Image.fromarray(b[:, :, N//2]).show()
型
的
2条答案
按热度按时间rks48beu1#
在
affine_transform
的文档中,它指出:Given an output image pixel index vector o, the pixel value is determined from the input image at position np.dot(matrix, o) + offset.
个因此,纯旋转矩阵将围绕索引为(0,0)的像素旋转数组(在2d中)。为了围绕图像的中心旋转,您可以在旋转之前和之后应用平移来移动图像坐标,使得中心在(0,0)执行旋转,然后将图像移回,在2d中这可能看起来像这样:
字符串
输出量:
的数据
的
的
pdkcd3nj2#
第一个问题是由@Nin17回答的,至于第二个问题:
看最后一幅图像,这个矩阵所做的操作不仅仅是旋转,还有某种扭曲/剪切
我不认为你看到的是剪切,而是输出图像的平面与立方体(你的输入图像)相交的效果。根据你的旋转矩阵,那个平面可能会切掉立方体的一个角。如果你定义旋转是围绕立方体的一个轴,你就不会再看到这个了。例如:
字符串