在3D绘图中显示真彩色2D RGB纹理?

ali*_*i_m 8 python 3d textures matplotlib mayavi

我正在尝试通过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
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果我设置为以全分辨率显示纹理,这将变得非常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
Run Code Online (Sandbox Code Playgroud)

但是,现在的问题是似乎没有任何方法可以使用Mayavi显示真彩色RGB纹理 - 根据文档,我只能指定单个(R, G, B)元组或预定义的colourmap.

有谁知道在3D绘图中显示真彩色2D RGB纹理的更好方法?

如果有足够的时间我可以弄清楚如何在Vtk或甚至纯OpenGL中做到这一点,但我真的希望有现有的库可以完成这项工作.

ali*_*i_m 6

非常感谢aestrivex使用Mayavi/VTK提供工作解决方案 - 这是我将来可能需要做的更复杂的事情的有用信息.

最后,我居然选择去使用的cgohlke的建议visvis,这竟然是很多容易实现:

import visvis as vv
vv.use('wx')

import numpy as np
from matplotlib.image import imread
from matplotlib.cbook import get_sample_data

imgdata = imread(get_sample_data('lena.png'))

nr, nc = imgdata.shape[:2]
x,y = np.mgrid[:nr, :nc]
z = np.ones((nr, nc))

for ii in xrange(5):
    vv.functions.surf(x, y, z*ii*100, imgdata, aa=3)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述