我试图通过RGB堆栈制作一个由一系列2D平面组成的3D图,如下所示:
我知道可以使用mpl_toolkits.mplot3d
来实现这一点,方法是将每个像素的x,y,z坐标和RGB(A)颜色传递给plot_surface
:
import numpy as np
from matplotlib import pyplot as pp
from mpl_toolkits.mplot3d.axes3d import Axes3D
def plot_stack_slices(rgbstack, scale=(1., 1., 1.), z_interval=10.):
fig, ax = pp.subplots(1,1,subplot_kw={'projection':'3d'})
ax.invert_zaxis()
ax.hold(True)
sx, sy, sz = scale
nz, ny, nx, nc = rgbstack.shape
stack_xyz = np.mgrid[:nx*sx:nx*1j, :ny*sy:ny*1j, :nz*sz:nz*1j]
slices = rgbstack[::-z_interval]
slice_xyz = np.rollaxis(stack_xyz, 3, 0)[::-z_interval]
surflist = []
for (img,xyz) in zip(slices, slice_xyz):
x, y, z = xyz
s = ax.plot_surface(x, y, z, facecolors=img**0.75,
rstride=50, cstride=50)
surflist.append(s)
return fig, ax, surflist
不幸的是,如果我设置rstride=1, cstride=1
,以便以全分辨率显示纹理,这将变得极其慢。
我还知道Mayavi可以轻松地处理以全分辨率显示多个2D纹理:
from mayavi import mlab
def plot_stack_slices2(stack, scale=(1., 1., 20.), z_interval=10.):
mfig = mlab.figure(bgcolor=(1,)*3)
sx, sy, sz = scale
nz, ny, nx = stack.shape
slices = stack[::-z_interval]
slice_z = np.linspace(0,nz*sz,nz)[::z_interval]
surflist = []
for (img,z) in zip(slices, slice_z):
im = mlab.imshow(img.T, colormap='gray', figure=mfig)
im.actor.scale = [sx,sy,sz]
im.actor.position = [0, 0, z]
surflist.append(z)
return fig, surflist
然而,现在的问题是,似乎没有任何方法可以使用Mayavi显示真彩色RGB纹理-根据文档,我只能指定单个(R, G, B)
元组或预定义的colourmap。
有人知道在3D图中显示真彩色2D RGB纹理的更好方法吗?
如果有足够的时间,我可能会弄清楚如何在Vtk甚至纯OpenGL中完成这一工作,但我真的希望现有的库可以完成这项工作。
2条答案
按热度按时间ifsvaxew1#
非常感谢aestrivex提供了使用Mayavi/VTK的工作解决方案--这是我在未来做更复杂的事情时可能需要的有用信息。
最后,我选择了cgohlke的建议,使用visvis,结果证明它实现起来要简单得多:
toe950272#
我不知道其他的库-- volshow看起来不错,但我没有测试过--但是你可以在vtk中做到这一点。
我一直在用mayavi做这件事(参见How to directly set RGB/RGBA colors in mayavi),但是对于某些图像源,mayavi用一种根本就不是为了处理这个问题而设计的。我的努力转换一个2D vtk。从mlab开始将ImageData转换为真彩色。每一步都遇到了阻力,但我做到了。
首先,这里是我如何在mayavi中使用mlab实现这一点的。这是太黑客和“魔术”依赖,甚至对我的标准:
但在纯tvtk中,情况并没有那么糟糕:
当然,在vtk中做是更多的工作。你甚至可以把它 Package 得很好,这样就很合理了。
我想修复mayavi来正确处理这个问题,但正如你从我的代码片段中可以看到的那样,这并不简单,可能需要一段时间。