PolyDataContourToImageData
VTKExamples/Python/PolyData/PolyDataContourToImageData
Description¶
- Contributed by: Lars Friedrich, Peter Gruber
== Brief Description ==
This example generates a sphere, cuts it with a plane and, therefore, generates a circlular contour (vtkPolyData). Subsequently a binary image representation (vtkImageData) is extracted from it. Internally vtkPolyDataToImageStencil and vtkLinearExtrusionFilter are utilized. Both the circular poly data (circle.vtp) and the resultant image (labelImage.mhd) are saved to disk.
'''NOTE''': Similarily to example , I am not really sure whether or not the image origin needs to be adjusted as the sphere-image-overlay shows some offset in paraview visualization (at least I think ...). Maybe someone could verify that. Thanks!
Code¶
PolyDataContourToImageData.py
import vtk import math # 3D source sphere sphereSource = vtk.vtkSphereSource() sphereSource.SetPhiResolution(30) sphereSource.SetThetaResolution(30) sphereSource.SetCenter(40, 40, 0) sphereSource.SetRadius(20) # generate circle by cutting the sphere with an implicit plane # (through its center, axis-aligned) circleCutter = vtk.vtkCutter() circleCutter.SetInputConnection(sphereSource.GetOutputPort()) cutPlane = vtk.vtkPlane() cutPlane.SetOrigin(sphereSource.GetCenter()) cutPlane.SetNormal(0, 0, 1) circleCutter.SetCutFunction(cutPlane) stripper = vtk.vtkStripper() stripper.SetInputConnection(circleCutter.GetOutputPort()) # valid circle stripper.Update() # that's our circle circle = stripper.GetOutput() # write circle out polyDataWriter = vtk.vtkXMLPolyDataWriter() if vtk.VTK_MAJOR_VERSION <= 5: polyDataWriter.SetInput(circle) else: polyDataWriter.SetInputData(circle) polyDataWriter.SetFileName("circle.vtp") polyDataWriter.SetCompressorTypeToNone() polyDataWriter.SetDataModeToAscii() polyDataWriter.Write() # prepare the binary image's voxel grid whiteImage = vtk.vtkImageData() bounds = [0]*6 circle.GetBounds(bounds) spacing = [0]*3 # desired volume spacing spacing[0] = 0.5 spacing[1] = 0.5 spacing[2] = 0.5 whiteImage.SetSpacing(spacing) # compute dimensions dim = [0]*3 for i in range(3): dim[i] = int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])) + 1 if (dim[i] < 1): dim[i] = 1 whiteImage.SetDimensions(dim) whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1) origin = [0]*3 # NOTE: I am not sure whether or not we had to add some offset! origin[0] = bounds[0]# + spacing[0] / 2 origin[1] = bounds[2]# + spacing[1] / 2 origin[2] = bounds[4]# + spacing[2] / 2 whiteImage.SetOrigin(origin) if vtk.VTK_MAJOR_VERSION <= 5: whiteImage.SetScalarTypeToUnsignedChar() whiteImage.AllocateScalars() else: whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) # fill the image with foreground voxels: inval = 255 outval = 0 count = whiteImage.GetNumberOfPoints() #for (vtkIdType i = 0 i < count ++i) for i in range(count): whiteImage.GetPointData().GetScalars().SetTuple1(i, inval) # sweep polygonal data (this is the important thing with contours!) extruder = vtk.vtkLinearExtrusionFilter() if vtk.VTK_MAJOR_VERSION <= 5: extruder.SetInput(circle) else: extruder.SetInputData(circle) extruder.SetScaleFactor(1.) extruder.SetExtrusionTypeToNormalExtrusion() extruder.SetVector(0, 0, 1) extruder.Update() # polygonal data -. image stencil: pol2stenc = vtk.vtkPolyDataToImageStencil() pol2stenc.SetTolerance(0) # important if extruder.SetVector(0, 0, 1) !!! pol2stenc.SetInputConnection(extruder.GetOutputPort()) pol2stenc.SetOutputOrigin(origin) pol2stenc.SetOutputSpacing(spacing) pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent()) pol2stenc.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() if vtk.VTK_MAJOR_VERSION <= 5: imgstenc.SetInput(whiteImage) imgstenc.SetStencil(pol2stenc.GetOutput()) else: imgstenc.SetInputData(whiteImage) imgstenc.SetStencilConnection(pol2stenc.GetOutputPort()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(outval) imgstenc.Update() imageWriter = vtk.vtkMetaImageWriter() imageWriter.SetFileName("labelImage.mhd") imageWriter.SetInputConnection(imgstenc.GetOutputPort()) imageWriter.Write() imageWriter = vtk.vtkPNGWriter() imageWriter.SetFileName("labelImage.png") imageWriter.SetInputConnection(imgstenc.GetOutputPort()) imageWriter.Write()