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