围绕python中的一个点旋转3D堆栈

时间:2018-06-07 15:28:59

标签: python 3d rotation volume

我用于围绕y轴旋转3D堆叠(体积)并精确地在位于3D堆栈中的目标体素上旋转。我正在使用的代码进行翻译,但是,生成的卷没有目标体素(它们彼此相距很远)(见下图)。我不知道这是怎么回事,因为我做了移位(减去目标体素的坐标并在旋转后添加它们)。这是我使用的代码:

dim=40
vol=np.zeros((dim,dim,dim))
vol[:,dim/5:dim/4,dim/4:dim*3/4]=1

ax=np.arange(dim)
coords=np.meshgrid(ax,ax,ax)

target_point=np.array([0,8,10]) #for shifting
xyz=np.vstack([coords[0].reshape(-1)- target_point[0], 
coords[1].reshape(-1)-target_point[1],  
coords[2].reshape(-1)- target_point[2],  
np.ones((dim,dim,dim)).reshape(-1)]) # 1 for homogeneous coordinates

# create transformation matrix
mat=rotation_matrix(0.1*np.pi,(0,1,0)) #rotation around y axis

# apply transformation
transformed_xyz=np.dot(mat, xyz)

# extract coordinates, don't use transformed_xyz[3,:] that's the             
#homogeneous coordinate, always 1
x=transformed_xyz[0,:] +   target_point[0] #shift back
y=transformed_xyz[1,:] + target_point[1]    #shift back
vz=transformed_xyz[2,:] + target_point[2]   #shift back

x=x.reshape((dim,dim,dim))
y=y.reshape((dim,dim,dim))
z=z.reshape((dim,dim,dim))

new_xyz=[y,x,z]
# sample
new_vol=scipy.ndimage.map_coordinates(vol,new_xyz, order=0)



def rotation_matrix(angle, direction):
    #Return matrix to rotate about axis defined by point and 
    #direction.

    sina = math.sin(angle)
    cosa = math.cos(angle)
    direction = unit_vector(direction[:3])
    # rotation matrix around unit vector
    R = numpy.diag([cosa, cosa, cosa])
    R += numpy.outer(direction, direction) * (1.0 - cosa)
    direction *= sina
    R += numpy.array([[ 0.0,         -direction[2],  direction[1]],
                  [ direction[2], 0.0,          -direction[0]],
                  [-direction[1], direction[0],  0.0]])
    M = numpy.identity(4)
    M[:3, :3] = R

    return M


def unit_vector(data, axis=None, out=None):
    #Return ndarray normalized by length, i.e. Euclidean norm, along 
    #axis.

    if out is None:
        data = numpy.array(data, dtype=numpy.float64, copy=True)
        if data.ndim == 1:
            data /= math.sqrt(numpy.dot(data, data))
            return data
    else:
        if out is not data:
            out[:] = numpy.array(data, copy=False)
        data = out
    length = numpy.atleast_1d(numpy.sum(data*data, axis))
    numpy.sqrt(length, length)
    if axis is not None:
        length = numpy.expand_dims(length, axis)
    data /= length
    if out is None:
       return data

有任何解决此问题的建议吗?

谢谢

image

0 个答案:

没有答案