After smoothing the contour constructed by MatchingCubes with below codes,
contour=vtk.vtkMarchingCubes()
smoother = vtk.vtkWindowedSincPolyDataFilter()
The result seem like below. Some vertices are unevenly distributed. Is there any method to make them more 'evenly segmented'?
For other users looking for an answer from this post:
C++ using VTK https://github.com/valette/ACVD
python using pyvista / VTK https://github.com/pyvista/pyacvd ($ pip install pyacvd)
Example using pyacvd from a function that converts a simpleITK binary image to a VTK polydata:
import numpy as np
import SimpleITK as sitk
import vtk
from vtk.util import numpy_support
import pyvista as pv
import pyacvd
def sitk2vtk(self, sitk_pointer, nb_points=None):
numpy_array = sitk.GetArrayFromImage(sitk_pointer)
size = list(sitk_pointer.GetSize())
origin = list(sitk_pointer.GetOrigin())
spacing = list(sitk_pointer.GetSpacing())
label = numpy_support.numpy_to_vtk(num_array=numpy_array.ravel(), deep=True, array_type=vtk.VTK_FLOAT)
# Convert the VTK array to vtkImageData
img_vtk = vtk.vtkImageData()
img_vtk.SetDimensions(size)
img_vtk.SetSpacing(spacing)
img_vtk.SetOrigin(origin)
img_vtk.GetPointData().SetScalars(label)
MarchingCubeFilter = vtk.vtkDiscreteMarchingCubes()
MarchingCubeFilter.SetInputData(img_vtk)
MarchingCubeFilter.GenerateValues(1, 1, 1)
MarchingCubeFilter.Update()
if nb_points:
# wrapper vtk polydata to pyvista polydata
pv_temp = pv.PolyData(MarchingCubeFilter.GetOutput())
cluster = pyacvd.Clustering(pv_temp)
cluster.cluster(int(nb_points))
remesh = cluster.create_mesh()
remesh_vtk = vtk.vtkPolyData()
remesh_vtk.SetPoints(remesh.GetPoints())
remesh_vtk.SetVerts(remesh.GetVerts())
remesh_vtk.SetPolys(remesh.GetPolys())
return remesh_vtk
else:
return MarchingCubeFilter.GetOutput()
Some examples for ITK/VTK reader/writer/converter: https://github.com/guatavita/IOTools