使用numpy/scipy转换和重新采样3D卷

lhk*_*lhk 5 python numpy scipy geometry-shader ndimage

更新:

我创建了一个记录良好的ipython笔记本.如果您只想要代码,请查看第一个答案.

我有40x40x40的灰度值.这需要旋转/移位/剪切.

这是一个有用的同类转换集合:http://www.lfd.uci.edu/~gohlke/code/transformations.py.html

我需要像处理一对(位置矢量,值)来处理我体积中的每个体素.然后我将变换位置并从变换矢量集合中为每个坐标采样新值.

抽样似乎相当困难,我很高兴找到这个:https: //docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.ndimage.affine_transform.html#scipy.ndimage.affine_transform

给定的矩阵和偏移用于通过仿射变换为输出中的每个点找到输入中的对应坐标.这些坐标处的输入值由所请求顺序的样条插值确定.根据给定的模式填充输入边界之外的点.

听起来很完美.

但用法非常棘手.这里有人使用该代码来旋转图像.他的旋转矩阵是2x2,所以它不是同质坐标.我尝试将同源坐标(2D)中的平移矩阵传递给函数:

dim =10
arr=np.zeros((dim,dim))
arr[0,0]=1
mat=np.array([[1,0,1],[0,1,0],[0,0,1]])
out3=scipy.ndimage.affine_transform(arr,mat)
print("out3: ",out3)
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

Traceback (most recent call last):
  File "C:/Users/212590884/PycharmProjects/3DAugmentation/main.py", line 32, in <module>
    out3=scipy.ndimage.affine_transform(arr,mat)
  File "C:\Users\212590884\AppData\Local\Continuum\Anaconda2\lib\site-packages\scipy\ndimage\interpolation.py", line 417, in affine_transform
    raise RuntimeError('affine matrix has wrong number of rows')
RuntimeError: affine matrix has wrong number of rows
Run Code Online (Sandbox Code Playgroud)

显然,这不适用于齐次坐标.如何使用它来移动数据?

这只是在2D中,在3D中我甚至无法旋转音量:

dim =10
arr=np.zeros((dim,dim,dim))
arr[0,0]=1

angle=10/180*np.pi
c=np.cos(angle)
s=np.sin(angle)
mat=np.array([[c,-s,0,0],[s,c,0,0],[0,0,1,0],[0,0,0,1]])
out3=scipy.ndimage.affine_transform(arr,mat)
print("out3: ",out3)
Run Code Online (Sandbox Code Playgroud)

错误消息是相同的: affine matrix has wrong number of rows

是否可以使用此方法来转换我的音量?

我发现了一组辅助方法,它们提供移位和旋转但不剪切:https: //docs.scipy.org/doc/scipy-0.14.0/reference/ndimage.html

但我更喜欢使用自定义转换矩阵.

lhk*_*lhk 4

我找到了另一个选项:map_coordinates

使用 numpy 可以生成坐标网格,然后对它们进行整形/堆叠以形成位置向量。这些向量被变换并转换回网格坐标格式。最终map_coordinates解决了采样问题。

我认为这是一个常见问题,并创建了一个 ipython 笔记本,它逐步解释了所有内容:

http://nbviewer.jupyter.org/gist/lhk/f05ee20b5a826e4c8b9bb3e528348688

还有一个问题:坐标的顺序很奇怪。您需要以一种不直观的方式重新排序网格。可能是我的代码中的错误。

请注意,坐标的重新排序会影响变换的轴。如果你想绕x轴旋转某个东西,对应的向量不是(1,0,0)而是(0,1,0),这真的很奇怪。

但它确实有效,而且我认为原理很明确。