#python #numpy #3d #vtk #mayavi
Вопрос:
Моя текущая задача-создать пространство 3D-изображений, в котором есть 3D-объекты (из iso-поверхностей), которые я разработал, и экспортировать их в виде стека изображений (numpy или tiff).
Я пришел к использованию Mayavi для создания 3D iso-поверхностей. Я знаю, что Mayavi изначально был разработан для самостоятельной 3D-визуализации,но я хотел бы найти способ экспортировать 3D-объект в стек 3D-изображений в виде numpy (z,y, x). Моя первоначальная идея состояла в том, чтобы итеративно делать снимки срезанного тома из объекта Mayavi mlab по оси z, но я не уверен, есть ли возможность сохранить срезанное изображение iso-поверхности в качестве снимка.
Лучшим сценарием было бы экспортировать стек 3D-изображений (tiff) точно из того, что я вижу из окна Mayavi. В противном случае я приму любые предложения по выполнению этой задачи в целом.
Вот пример кода.
import numpy as np
from mayavi import mlab
# Produce some nice data.
n_mer, n_long = 6, 11
pi = np.pi
dphi = pi/1000.0
phi = np.arange(0.0, 2*pi 0.5*dphi, dphi, 'd')
mu = phi*n_mer
x = np.cos(mu)*(1 np.cos(n_long*mu/n_mer)*0.5)
y = np.sin(mu)*(1 np.cos(n_long*mu/n_mer)*0.5)
z = np.sin(n_long*mu/n_mer)*0.5
# Init plot
source = mlab.points3d(x, y, z)
Ответ №1:
Вы могли бы пойти в класс vtk vtkImplicitModeller
. Например.:
import numpy as np
from vedo import Points, Volume
n_mer, n_long = 6, 11
dphi = np.pi/1000.0
phi = np.arange(0.0, 2*np.pi 0.5*dphi, dphi, 'd')
mu = phi*n_mer
x = np.cos(mu)*(1 np.cos(n_long*mu/n_mer)*0.5)
y = np.sin(mu)*(1 np.cos(n_long*mu/n_mer)*0.5)
z = np.sin(n_long*mu/n_mer)*0.5
source = Points([x, y, z], r=4)
modl = source.implicitModeller(
distance=0.15,
res=(60,60,30),
bounds=(-1.8,1.8,-1.8,1.8,-0.7,0.7),
)
modl.smoothLaplacian().computeNormals()
modl.c("blue9").lw(1).lighting("metallic").show(axes=1)
#######################################################
import vtk
imp = vtk.vtkImplicitModeller()
imp.SetInputData(source.polydata())
imp.SetSampleDimensions(50,50,30)
imp.SetModelBounds(-1.8,1.8,-1.8,1.8,-0.7,0.7)
imp.Update()
vol = Volume(imp.GetOutput())
arr = np.clip(vol.getDataArray(), 0, 1.2)
print(arr.shape)
Комментарии:
1. это работает на меня! У меня просто есть еще один вопрос. Похоже, обрезка в конце необходима для сохранения эффекта затенения (в противном случае все заполнено до краев). Установлен ли порог отсечения эмпирически или есть способ рассчитать эффективный порог отсечения?
2. это
np.clip
связано с тем, чтоvtkImplicitModeller
генерирует очень большие значения (не уверен, почему это происходит, этого не должно быть..). Границы задаются немного эмпирически, они должны быть примерно увеличены на требуемое значение расстояния, когда вы обращаетесь к объему.