问题的背景是我将3D结构保存在需要处理的.vtk文件中(膨胀,腐蚀等)。以下代码段旨在按顺序运行,即,如果您一个接一个地运行它们,则应该没有问题(除了我提到的那些问题!)。
我是VTK的新手,对于任何非常基本的错误,我们深表歉意!
我的问题源于SimpleITK的问题,其中无法读取UnstructuredGrid或PolyData:
In [1]: import SimpleITK as sitk
In [2]: img_vtk = sitk.ReadImage(file_vtk)
Traceback (most recent call last):
File "<ipython-input-52-435ce999db50>", line 1, in <module>
img_vtk = sitk.ReadImage(file_vtk)
File "/usr/local/lib/python3.5/dist-packages/SimpleITK/SimpleITK.py", line 8614, in ReadImage
return _SimpleITK.ReadImage(*args)
RuntimeError: Exception thrown in SimpleITK ReadImage: /tmp/SimpleITK/Code/IO/src/sitkImageReaderBase.cxx:97:
sitk::ERROR: Unable to determine ImageIO reader for "/data/ROMPA_MRIandSeg/09S/Analysis/1_model/clip_dilate.vtk"
但是,SimpleITK可以读取StructuredGrid,因此我尝试通过使用VTK进行读取和转换来解决此问题。
import vtk
reader = vtk.vtkGenericDataObjectReader() # Using generic to allow it to match either Unstructured or PolyData
reader.SetFileName(file_vtk)
reader.Update()
output = reader.GetOutput()
但是,从那时起,我尝试过的每种方法似乎都失败了。
我试图将其转换为一个numpy数组(),然后插入一个虚拟变量为1的常规网格以指定结构上的值。
from vtk.utils import numpy_support
import scipy.interpolate
import numpy as np
nparray = numpy_support.vtk_to_numpy(output.GetPointData().GetArray(0))
output_bounds = output.GetBounds()
x_grid = range(math.floor(output_bounds[0]),math.ceil(output_bounds[1]),1)
y_grid = range(math.floor(output_bounds[2]),math.ceil(output_bounds[3]),1)
z_grid = range(math.floor(output_bounds[4]),math.ceil(output_bounds[5]),1)
grid = list()
for x in x_grid:
for y in y_grid:
for z in z_grid:
grid.append((x,y,z))
dummy = np.array([1 for i in range(nparray.shape[0])])
npgrid = scipy.interpolate.griddata(nparray,dummy,grid,fill_value=0)
npgrid.reshape(len(x_grid),len(y_grid),len(z_grid))
img = sitk.GetImageFromArray(npgrid)
sitk.WriteImage(img,file_out)
但是,当我将其加载到ParaView中时,将显示输出的边界框,但是输出的轮廓为空。
ShepardMethod
在将UnstructuredGrid转换为PolyData之后,我尝试使用内置的ShepardMethod
进行插值(就像我通常看到的ShepardMethod应用于PolyData一样)
bounds = output.GetBounds()
spacings = [1.0,1.0,1.0] # arbitrary spacing
dimensions = [0,0,0]
for i,spacing in enumerate(spacings):
dimensions[i] = int(math.ceil((bounds[i*2 + 1]-bounds[i*2])/spacing))
vtkPoints = vtk.vtkPoints()
for i in range(0,nparray.shape[0]):
x=nparray[i,0]
y=nparray[i,1]
z=nparray[i,2]
p=[x,y,z]
vtkPoints.InsertNextPoint(p)
poly = vtk.vtkPolyData()
poly.SetPoints(vtkPoints)
shepard = vtk.vtkShepardMethod()
shepard.SetInputData(poly)
shepard.SetSampleDimensions(dimensions)
shepard.SetModelBounds(output.GetBounds())
shepard.Update()
shepard_data = shepard.GetOutput().GetPointData().GetArray(0)
shepard_numpy = numpy_support.vtk_to_numpy(shepard_data)
shepard_numpy = shepard_numpy.reshape(dimensions[0],dimensions[1],dimensions[2])
shepard_img = sitk.GetImageFromArray(shepard_numpy)
sitk.WriteImage(shepard_img,file_out)
与上面的numpy一样,它在ParaView中提供了一个边界框。应用轮廓提供了两个三角形的结构,即几乎没有成功书写。另外,我尝试直接使用VTK编写输出。
shepard_data = shepard.GetOutput()
shepard_grid = vtk.vtkImageToStructuredGrid()
shepard_grid.SetInputData(shepard_data)
shepard_grid.Update()
writer = vtk.vtkStructuredGridWriter()
writer.SetFileName(file_out)
writer.SetInputData(shepard_grid.GetOutput())
writer.Write()
这产生了与以前相同的输出。
ProbeFilter
我尝试使用ProbeFilter
(同时转换为numpy
并直接编写)来进行上述操作。不幸的是,输出结果与上面相同。
mesh = vtk.vtkStructuredGrid()
mesh.SetDimensions(dimensions)
probe = vtk.vtkProbeFilter()
probe.SetInputData(mesh)
probe.SetSourceData(output)
probe.Update()
probe_out = probe.GetOutput()
writer = vtk.vtkStructuredGridWriter()
writer.SetFileName(file_out)
writer.SetInputData(probe.GetOutput())
writer.Write()
probe_data = probe.GetOutput().GetPointData().GetArray(0)
probe_numpy = numpy_support.vtk_to_numpy(probe_data)
probe_numpy = probe_numpy.reshape(dimensions[0],dimensions[1],dimensions[2])
probe_img = sitk.GetImageFromArray(probe_numpy)
sitk.WriteImage(probe_img,file_out)
但是,这似乎无法产生任何可行的输出(vtkStructuredGridWriter
产生了一个空文件,而probe_numpy
却没有了)。
我的原始数据来自结构化的.vtk文件,该文件是使用ParaView打开的,然后进行裁剪以删除网格中不需要的结构。保存输出会保存一个unstructuredGrid,并且我一直无法弄清楚是否可以更改它,并且首先避免了这种混乱!
答案 0 :(得分:0)
只需在ParaView中使用“使用数据集重新采样”过滤器即可。