Создание 3D-объекта (например, через Mayavi) и экспорт его в виде стека 3D-изображений (например, tiff)

#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)
 

Пример 3D-объекта, созданного Mayavi для визуализации

Ответ №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 генерирует очень большие значения (не уверен, почему это происходит, этого не должно быть..). Границы задаются немного эмпирически, они должны быть примерно увеличены на требуемое значение расстояния, когда вы обращаетесь к объему.