Example #1
0
def contourSequence2Volume(cs, spacing=[1, 1, 1]):
    polylines = drt2polylines.contourSequence2PolyLines(cs)

    stencil = vtk.vtkPolyDataToImageStencil()
    stencil.SetInputData(polylines)

    bounds = polylines.GetBounds()
    i = 0
    bounds2 = []
    for x in bounds:
        if i & 1:
            y = math.ceil(x) + 1
        else:
            y = math.floor(x) - 1
        bounds2.append(y)
        i = i + 1

    stencil.SetOutputWholeExtent(bounds2[0], bounds2[1], bounds2[2],
                                 bounds2[3], bounds2[4], bounds2[5])

    stencil.SetOutputSpacing(spacing[0], spacing[1], spacing[2])
    stencil.Update()

    sten2img = vtk.vtkImageStencilToImage()
    sten2img.SetInputConnection(stencil.GetOutputPort())
    sten2img.SetOutsideValue(0)
    sten2img.SetInsideValue(255)
    sten2img.Update()
    vtkimg = sten2img.GetOutput()
    return vtkimg
Example #2
0
   def createMaskfromMesh(self, VOI_mesh, im):
       """ Takes an image and a VOI_mesh and returns a boolean image with only 1s inside the VOI_mesh """                
       
       # Create an Image of Fext
       white_image = vtk.vtkImageData()
       white_image.DeepCopy(im) 
 
       # polygonal data --> image stencil:
       pol2stenc = vtk.vtkPolyDataToImageStencil()
       pol2stenc.SetInput(VOI_mesh)
       pol2stenc.SetOutputOrigin(im.GetOrigin())
       pol2stenc.SetOutputSpacing(im.GetSpacing())
       pol2stenc.SetOutputWholeExtent(white_image.GetExtent())
       pol2stenc.Update()
        
       # cut the corresponding white image and set the background:
       imgstenc = vtk.vtkImageStencil()
       imgstenc.SetInput(white_image)
       imgstenc.SetStencil(pol2stenc.GetOutput())
       imgstenc.ReverseStencilOff()
       imgstenc.SetBackgroundValue(0.0)
       imgstenc.Update()
       
       # write to image        
       dims = im.GetDimensions()
       scalars = imgstenc.GetOutput().GetPointData().GetScalars()
       np_scalars = vtk_to_numpy(scalars)     
       np_scalars = np_scalars.reshape(dims[2], dims[1], dims[0]) 
       np_scalars = np_scalars.transpose(2,1,0)
       
       return np_scalars
Example #3
0
    def createVTKMaskfromMesh(self, VOI_mesh, im):
        """ Takes an image and a VOI_mesh and returns a boolean image with only 1s inside the VOI_mesh """

        # Create an Image of Fext
        white_image = vtk.vtkImageData()
        white_image.DeepCopy(im)
        white_image.SetScalarTypeToUnsignedChar()
        white_image.AllocateScalars()
        count = white_image.GetNumberOfPoints()
        for i in range(count):
            white_image.GetPointData().GetScalars().SetTuple1(i, 1.0)

        # polygonal data --> image stencil:
        pol2stenc = vtk.vtkPolyDataToImageStencil()
        pol2stenc.SetInput(VOI_mesh)
        pol2stenc.SetOutputOrigin(im.GetOrigin())
        pol2stenc.SetOutputSpacing(im.GetSpacing())
        pol2stenc.SetOutputWholeExtent(im.GetExtent())
        pol2stenc.Update()

        # cut the corresponding white image and set the background:
        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInput(white_image)
        imgstenc.SetStencil(pol2stenc.GetOutput())
        imgstenc.ReverseStencilOff()
        imgstenc.SetBackgroundValue(0.0)
        imgstenc.Update()

        return imgstenc.GetOutput()
   def createMaskfromMesh(self, VOI_mesh, im):
       """ Takes an image and a VOI_mesh and returns a boolean image with only 1s inside the VOI_mesh """                
       
       # Create an Image of Fext
       white_image = vtk.vtkImageData()
       white_image.DeepCopy(im) 
 
       # polygonal data --> image stencil:
       pol2stenc = vtk.vtkPolyDataToImageStencil()
       pol2stenc.SetInputData(VOI_mesh)
       pol2stenc.SetOutputOrigin(im.GetOrigin())
       pol2stenc.SetOutputSpacing(im.GetSpacing())
       pol2stenc.SetOutputWholeExtent(white_image.GetExtent())
       pol2stenc.SetInformationInput(white_image)
       pol2stenc.Update()
        
       # cut the corresponding white image and set the background:
       imgstenc = vtk.vtkImageStencil()
       imgstenc.SetInputData(white_image)
       imgstenc.SetStencilData(pol2stenc.GetOutput())
       imgstenc.ReverseStencilOff()
       imgstenc.SetBackgroundValue(0.0)
       imgstenc.Update()
       
       # write to image        
       dims = im.GetDimensions()
       scalars = imgstenc.GetOutput().GetPointData().GetScalars()
       np_scalars = vtk_to_numpy(scalars)     
       np_scalars = np_scalars.reshape(dims[2], dims[1], dims[0]) 
       np_scalars = np_scalars.transpose(2,1,0)
       
       return np_scalars
Example #5
0
def convertPolyDataToImageData(poly, ref_im):
    """
    Convert the vtk polydata to imagedata 
    Args:
        poly: vtkPolyData
        ref_im: reference vtkImage to match the polydata with
    Returns:
        output: resulted vtkImageData
    """

    ref_im.GetPointData().SetScalars(
        numpy_to_vtk(
            np.zeros(vtk_to_numpy(ref_im.GetPointData().GetScalars()).shape)))
    ply2im = vtk.vtkPolyDataToImageStencil()
    ply2im.SetTolerance(0.05)
    ply2im.SetInputData(poly)
    ply2im.SetOutputSpacing(ref_im.GetSpacing())
    ply2im.SetInformationInput(ref_im)
    ply2im.Update()

    stencil = vtk.vtkImageStencil()
    stencil.SetInputData(ref_im)
    stencil.ReverseStencilOn()
    stencil.SetStencilData(ply2im.GetOutput())
    stencil.Update()
    output = stencil.GetOutput()

    return output
 def __init__(self, module_manager):
     SimpleVTKClassModuleBase.__init__(
         self, module_manager,
         vtk.vtkPolyDataToImageStencil(), 'Processing.',
         ('vtkPolyData',), ('vtkImageStencilData',),
         replaceDoc=True,
         inputFunctions=None, outputFunctions=None)
Example #7
0
def importSTL(filename):
 
    reader = vtk.vtkSTLReader()
    reader.SetFileName(filename)
    reader.Update()

    outputVol = np.zeros((500,500,500))
    outputVTK = vtk_import_numpy_array(outputVol)

    dataToStencil = vtk.vtkPolyDataToImageStencil()
    dataToStencil.SetInputConnection(reader.GetOutputPort())
    
    dataToStencil.SetOutputSpacing(0.5, 0.5, 0.5)
    dataToStencil.SetOutputOrigin(0.0, 0.0, 0.0)
    dataToStencil.Update()
      
    stencil = vtk.vtkImageStencil() 
    stencil.SetInput(outputVTK.GetOutput())
    stencil.SetStencil(dataToStencil.GetOutput())
    stencil.ReverseStencilOn()
    stencil.Update()
    
    im =  stencil.GetOutput()
    rows, cols, lines = im.GetDimensions()
    sc = im.GetPointData().GetScalars()
    
    a = vtk_to_numpy(sc)
    a = a.reshape((lines,cols,rows))
    return a 
Example #8
0
def convert_polydata_to_image_data(poly, ref_im, reverse=True):
    """
    Convert the vtk polydata to imagedata 

    Args:
        poly: vtkPolyData
        ref_im: reference vtkImage to match the polydata with
    Returns:
        output: resulted vtkImageData
    """
    from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk
    # Have to copy to create a zeroed vtk image data
    ref_im_zeros = vtk.vtkImageData()
    ref_im_zeros.DeepCopy(ref_im)
    ref_im_zeros.GetPointData().SetScalars(
        numpy_to_vtk(
            np.zeros(
                vtk_to_numpy(ref_im_zeros.GetPointData().GetScalars()).shape)))
    ply2im = vtk.vtkPolyDataToImageStencil()
    ply2im.SetTolerance(0.05)
    ply2im.SetInputData(poly)
    ply2im.SetOutputSpacing(ref_im.GetSpacing())
    ply2im.SetInformationInput(ref_im_zeros)
    ply2im.Update()

    stencil = vtk.vtkImageStencil()
    stencil.SetInputData(ref_im_zeros)
    if reverse:
        stencil.ReverseStencilOn()
    stencil.SetStencilData(ply2im.GetOutput())
    stencil.Update()
    output = stencil.GetOutput()

    return output
Example #9
0
def MeshToVolume(Filename):
	reader = vtk.vtkPolyDataReader()
	pol2stenc = vtk.vtkPolyDataToImageStencil()
	imgstenc = vtk.vtkImageStencil()

	reader.SetFileName(os.path.join(subjects_dir,subject_dir,Filename))
	reader.Update()

	ref_mesh = reader.GetOutput()
	ref_volume = vtk.vtkImageData()

	# define output volume dimension
	spacing = (0.5,0.5,0.5)

	ref_volume.SetSpacing(spacing)

	bounds = ref_mesh.GetBounds()

	dim = [math.ceil(bounds[ii*2+1] - bounds[ii*2] / spacing[ii]) for ii in range(0,3)]
	origin = [bounds[ii*2] + spacing[ii] / 2 for ii in range(0,3)]
	extent = (0,dim[0] - 1,0,dim[1] -1 ,0,dim[2]-1)

	ref_volume.SetOrigin(origin)
	ref_volume.SetDimensions(dim)
	ref_volume.SetExtent(extent)

	ref_volume.SetScalarTypeToUnsignedChar()
	ref_volume.AllocateScalars()

	# Fill the image with white voxels
	for i in range(0,ref_volume.GetNumberOfPoints()):
		ref_volume.GetPointData().GetScalars().SetTuple1(i,255)

	print ref_volume.GetNumberOfPoints()

	pol2stenc.SetInput(ref_mesh)

	pol2stenc.SetOutputOrigin(origin)
	pol2stenc.SetOutputSpacing(spacing)
	pol2stenc.SetOutputWholeExtent(ref_volume.GetExtent())

	pol2stenc.Update()

	imgstenc.SetInput(ref_volume)
	imgstenc.SetStencil(pol2stenc.GetOutput())

	imgstenc.ReverseStencilOff()
	imgstenc.SetBackgroundValue(0)
	imgstenc.Update()
	tmp = imgstenc.GetOutput()

	writer = vtk.vtkImageWriter()
	writer.SetFileName('prova.nii.gz')
	writer.SetInput(ref_volume)
	writer.Update()

	out = v2n(tmp.GetPointData().GetScalars())

	return np.reshape(out, (dim[0],dim[1],dim[2]))
Example #10
0
def surf_fill_vtk(vertices, polys, mat, shape):

    import vtk
    from vtk.util import numpy_support

    voxverts = nb.affines.apply_affine(np.linalg.inv(mat), vertices)
    points = vtk.vtkPoints()
    points.SetNumberOfPoints(len(voxverts))
    for i, pt in enumerate(voxverts):
        points.InsertPoint(i, pt)

    tris = vtk.vtkCellArray()
    for vert in polys:
        tris.InsertNextCell(len(vert))
        for v in vert:
            tris.InsertCellPoint(v)

    pd = vtk.vtkPolyData()
    pd.SetPoints(points)
    pd.SetPolys(tris)
    del points, tris

    whiteimg = vtk.vtkImageData()
    whiteimg.SetDimensions(shape)
    if vtk.VTK_MAJOR_VERSION <= 5:
        whiteimg.SetScalarType(vtk.VTK_UNSIGNED_CHAR)
    else:
        info = vtk.vtkInformation()
        whiteimg.SetPointDataActiveScalarInfo(info, vtk.VTK_UNSIGNED_CHAR, 1)

    ones = np.ones(np.prod(shape), dtype=np.uint8)
    whiteimg.GetPointData().SetScalars(numpy_support.numpy_to_vtk(ones))

    pdtis = vtk.vtkPolyDataToImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
        pdtis.SetInput(pd)
    else:
        pdtis.SetInputData(pd)

    pdtis.SetOutputWholeExtent(whiteimg.GetExtent())
    pdtis.Update()

    imgstenc = vtk.vtkImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
        imgstenc.SetInput(whiteimg)
        imgstenc.SetStencil(pdtis.GetOutput())
    else:
        imgstenc.SetInputData(whiteimg)
        imgstenc.SetStencilConnection(pdtis.GetOutputPort())
    imgstenc.SetBackgroundValue(0)

    imgstenc.Update()

    data = numpy_support.vtk_to_numpy(
        imgstenc.GetOutput().GetPointData().GetScalars()).reshape(
            shape).transpose(2, 1, 0)
    del pd, voxverts, whiteimg, pdtis, imgstenc
    return data
Example #11
0
    def _polydataToLabelmap(polydata,
                            spacing=1.0,
                            extraMarginToBounds=0,
                            referenceImage=None):

        binaryLabelmap = vtk.vtkImageData()

        if referenceImage:
            origin = referenceImage.GetOrigin()
            spacing3 = referenceImage.GetSpacing()
            extent = referenceImage.GetExtent()
        else:
            bounds = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
            polydata.GetBounds(bounds)
            bounds[0] -= extraMarginToBounds
            bounds[2] -= extraMarginToBounds
            bounds[4] -= extraMarginToBounds
            bounds[1] += extraMarginToBounds
            bounds[3] += extraMarginToBounds
            bounds[5] += extraMarginToBounds

            spacing3 = np.ones(3) * spacing
            dim = [0, 0, 0]
            for i in range(3):
                # Add 3 to the dimensions to have at least 1 voxel thickness and 1 voxel margin on both sides
                dim[i] = int(
                    math.ceil(
                        (bounds[i * 2 + 1] - bounds[i * 2]) / spacing3[i])) + 3

            # Subtract one spacing to ensure there is a margin
            origin = [
                bounds[0] - spacing3[0], bounds[2] - spacing3[1],
                bounds[4] - spacing3[2]
            ]

            extent = [0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1]

        binaryLabelmap.SetOrigin(origin)
        binaryLabelmap.SetSpacing(spacing3)
        binaryLabelmap.SetExtent(extent)

        binaryLabelmap.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
        binaryLabelmap.GetPointData().GetScalars().Fill(0)

        pol2stenc = vtk.vtkPolyDataToImageStencil()
        pol2stenc.SetInputData(polydata)
        pol2stenc.SetOutputOrigin(origin)
        pol2stenc.SetOutputSpacing(spacing3)
        pol2stenc.SetOutputWholeExtent(binaryLabelmap.GetExtent())

        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInputData(binaryLabelmap)
        imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
        imgstenc.ReverseStencilOn()
        imgstenc.SetBackgroundValue(1)
        imgstenc.Update()

        return imgstenc.GetOutput()
Example #12
0
def surf_fill_vtk(vertices, polys, mat, shape):

    import vtk
    from vtk.util import numpy_support

    voxverts = nb.affines.apply_affine(np.linalg.inv(mat), vertices)
    points = vtk.vtkPoints()
    points.SetNumberOfPoints(len(voxverts))
    for i, pt in enumerate(voxverts):
        points.InsertPoint(i, pt)

    tris = vtk.vtkCellArray()
    for vert in polys:
        tris.InsertNextCell(len(vert))
        for v in vert:
            tris.InsertCellPoint(v)

    pd = vtk.vtkPolyData()
    pd.SetPoints(points)
    pd.SetPolys(tris)
    del points, tris

    whiteimg = vtk.vtkImageData()
    whiteimg.SetDimensions(shape)
    if vtk.VTK_MAJOR_VERSION <= 5:
        whiteimg.SetScalarType(vtk.VTK_UNSIGNED_CHAR)
    else:
        info = vtk.vtkInformation()
        whiteimg.SetPointDataActiveScalarInfo(info, vtk.VTK_UNSIGNED_CHAR, 1)

    ones = np.ones(np.prod(shape), dtype=np.uint8)
    whiteimg.GetPointData().SetScalars(numpy_support.numpy_to_vtk(ones))

    pdtis = vtk.vtkPolyDataToImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
        pdtis.SetInput(pd)
    else:
        pdtis.SetInputData(pd)

    pdtis.SetOutputWholeExtent(whiteimg.GetExtent())
    pdtis.Update()

    imgstenc = vtk.vtkImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
        imgstenc.SetInput(whiteimg)
        imgstenc.SetStencil(pdtis.GetOutput())
    else:
        imgstenc.SetInputData(whiteimg)
        imgstenc.SetStencilConnection(pdtis.GetOutputPort())
    imgstenc.SetBackgroundValue(0)

    imgstenc.Update()

    data = (
        numpy_support.vtk_to_numpy(imgstenc.GetOutput().GetPointData().GetScalars()).reshape(shape).transpose(2, 1, 0)
    )
    del pd, voxverts, whiteimg, pdtis, imgstenc
    return data
 def __init__(self, module_manager):
     SimpleVTKClassModuleBase.__init__(self,
                                       module_manager,
                                       vtk.vtkPolyDataToImageStencil(),
                                       'Processing.', ('vtkPolyData', ),
                                       ('vtkImageStencilData', ),
                                       replaceDoc=True,
                                       inputFunctions=None,
                                       outputFunctions=None)
Example #14
0
def poly_data_to_nii(poly_data, reference_path, result_path):
    """
    TODO: stop reading and writing so much stuff
    Write to buffer? Bytes? Investigate this
    """
    nii = nib.load(str(reference_path))
    image_stencil_array = np.ones(nii.shape, dtype=np.uint8)
    image_stencil_nii = nib.Nifti1Image(image_stencil_array, nii.get_qform())

    with NamedTemporaryFile(suffix='.nii') as f:
        stencil_path = f.name
        image_stencil_nii.to_filename(stencil_path)
        image_stencil_reader = vtk.vtkNIFTIImageReader()
        image_stencil_reader.SetFileName(stencil_path)
        image_stencil_reader.Update()

    image_stencil = image_stencil_reader.GetOutput()
    xyz_to_ijk = image_stencil_reader.GetQFormMatrix()
    if xyz_to_ijk is None:
        import warnings
        warnings.warn('No qform found. Using sform')
        xyz_to_ijk = image_stencil_reader.GetSFormMatrix()
    xyz_to_ijk.Invert()

    transform = vtk.vtkTransform()
    transform.SetMatrix(xyz_to_ijk)

    transform_poly_data = vtk.vtkTransformPolyDataFilter()
    transform_poly_data.SetTransform(transform)
    transform_poly_data.SetInputData(poly_data)
    transform_poly_data.Update()
    pd_ijk = transform_poly_data.GetOutput()

    polyDataToImageStencil = vtk.vtkPolyDataToImageStencil()
    polyDataToImageStencil.SetInputData(pd_ijk)
    polyDataToImageStencil.SetOutputSpacing(image_stencil.GetSpacing())
    polyDataToImageStencil.SetOutputOrigin(image_stencil.GetOrigin())
    polyDataToImageStencil.SetOutputWholeExtent(image_stencil.GetExtent())
    polyDataToImageStencil.Update()

    stencil = vtk.vtkImageStencil()
    stencil.SetInputData(image_stencil)
    stencil.SetStencilData(polyDataToImageStencil.GetOutput())
    stencil.SetBackgroundValue(0)
    stencil.Update()

    image_output = stencil.GetOutput()

    data_object = dsa.WrapDataObject(image_output)
    array = data_object.PointData['NIFTI']
    array = array.reshape(nii.shape, order='F')  # C didn't work :)
    array = check_qfac(nii, array)

    output_nii = nib.Nifti1Image(array, nii.affine)
    output_nii.header['sform_code'] = 0
    output_nii.header['qform_code'] = 1
    output_nii.to_filename(result_path)
Example #15
0
def voxelizer(polydata, scale=SCALE, radius=RADIUS):
    """ volume voxelization not anti-aliased """

    # Get selection boundaries.
    (minX, maxX, minY, maxY, minZ,
     maxZ) = [int(x * scale)
              for x in polydata.GetBounds()]  # convert tuple of floats to ints

    # print("  Selection bounds are %s" % str((minX, maxX, minY, maxY, minZ, maxZ)))  # dimensions of the resulting image
    # print("  Dimensions: %s" % str((maxX - minX, maxY - minY, maxZ - minZ)))

    padd = radius + 6
    (minX, maxX, minY, maxY, minZ,
     maxZ) = (minX - padd, maxX + padd, minY - padd, maxY + padd, minZ - padd,
              maxZ + padd)

    ps1 = 1.0 / float(
        scale)  # pixel size for the stencil, make sure it's a float division!
    ps2 = 1.0  # pixel size for the image

    ## Convert a surface mesh into an image stencil that can be used to mask an image with vtkImageStencil.
    polyToStencilFilter = vtk.vtkPolyDataToImageStencil()
    polyToStencilFilter.SetInputData(polydata)
    polyToStencilFilter.SetOutputWholeExtent(minX, maxX, minY, maxY, minZ,
                                             maxZ)
    polyToStencilFilter.SetOutputSpacing(ps1, ps1, ps1)
    polyToStencilFilter.SetOutputOrigin(0.0, 0.0, 0.0)
    polyToStencilFilter.Update()

    # Create an empty (3D) image of appropriate size.
    image = vtk.vtkImageData()
    image.SetSpacing(ps2, ps2, ps2)
    image.SetOrigin(0.0, 0.0, 0.0)
    image.SetExtent(minX, maxX, minY, maxY, minZ, maxZ)
    image.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)

    # Mask the empty image with the image stencil.
    # First All the background to 0
    # Needed otherwise introduces noise
    stencil = vtk.vtkImageStencil()
    stencil.SetInputData(image)
    stencil.SetStencilData(polyToStencilFilter.GetOutput())
    stencil.ReverseStencilOff()
    stencil.SetBackgroundValue(0)
    stencil.Update()

    # Foreground to 255
    stencil2 = vtk.vtkImageStencil()
    stencil2.SetInputData(stencil.GetOutput())
    stencil2.SetStencilData(polyToStencilFilter.GetOutput())
    stencil2.ReverseStencilOn()
    stencil2.SetBackgroundValue(255)

    stencil2.Update()
    finishImage = stencil2.GetOutput()
    print(finishImage.GetNumberOfCells())
    return stencil2.GetOutput()
Example #16
0
    def generateTree_vtk(self):
        """
        | Funkce na vygenerování objemu stromu ze zadaných dat.
        | Veze pro generování pomocí VTK
        | !!! funguje špatně -> vstupní data musí být pouze povrchové body, jinak generuje ve výstupních datech dutiny

        """
        # get vtkPolyData
        tree_data = gen_vtk_tree.process_tree(self.rawdata['Graph'])
        polyData = gen_vtk_tree.gen_tree(tree_data)

        polyData.GetBounds()
        # bounds = polyData.GetBounds()

        white_image = vtk.vtkImageData()
        white_image.SetSpacing(self.voxelsize_mm)
        white_image.SetDimensions(self.shape)
        white_image.SetExtent(
            [0, self.shape[0] - 1, 0, self.shape[1] - 1, 0, self.shape[2] - 1])
        # origin = [(bounds[0] + self.shape[0])/2, (bounds[1] + self.shape[1])/2, (bounds[2] + self.shape[2])/2]
        # white_image.SetOrigin(origin) #neni potreba?
        # white_image.SetScalarTypeToUnsignedChar()
        white_image.AllocateScalars()

        # fill the image with foreground voxels: (still black until stecil)
        inval = 255
        outval = 0
        count = white_image.GetNumberOfPoints()
        for i in range(0, count):
            white_image.GetPointData().GetScalars().SetTuple1(i, inval)

        pol2stencil = vtk.vtkPolyDataToImageStencil()
        pol2stencil.SetInput(polyData)

        # pol2stencil.SetOutputOrigin(origin) # TOHLE BLBNE
        pol2stencil.SetOutputSpacing(self.voxelsize_mm)
        pol2stencil.SetOutputWholeExtent(white_image.GetExtent())
        pol2stencil.Update()

        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInput(white_image)
        imgstenc.SetStencil(pol2stencil.GetOutput())
        imgstenc.ReverseStencilOff()
        imgstenc.SetBackgroundValue(outval)
        imgstenc.Update()

        # VTK -> Numpy
        vtk_img_data = imgstenc.GetOutput()
        vtk_data = vtk_img_data.GetPointData().GetScalars()
        numpy_data = numpy_support.vtk_to_numpy(vtk_data)
        numpy_data = numpy_data.reshape(
            self.shape[0], self.shape[1], self.shape[2])
        numpy_data = numpy_data.transpose(2, 1, 0)

        self.data3d = numpy_data
Example #17
0
def mesh2Volume(mesh, spacing=(1, 1, 1)):
    """
    Convert a mesh it into a ``Volume``
    where the foreground (exterior) voxels value is 1 and the background
    (interior) voxels value is 0.
    Internally the ``vtkPolyDataToImageStencil`` class is used.

    |mesh2volume| |mesh2volume.py|_
    """
    # https://vtk.org/Wiki/VTK/Examples/Cxx/PolyData/PolyDataToImageData
    pd = mesh.polydata()

    whiteImage = vtk.vtkImageData()
    bounds = pd.GetBounds()

    whiteImage.SetSpacing(spacing)

    # compute dimensions
    dim = [0, 0, 0]
    for i in [0, 1, 2]:
        dim[i] = int(np.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]))
    whiteImage.SetDimensions(dim)
    whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1)

    origin = [0, 0, 0]
    origin[0] = bounds[0] + spacing[0] / 2
    origin[1] = bounds[2] + spacing[1] / 2
    origin[2] = bounds[4] + spacing[2] / 2
    whiteImage.SetOrigin(origin)
    whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)

    # fill the image with foreground voxels:
    inval = 255
    count = whiteImage.GetNumberOfPoints()
    for i in range(count):
        whiteImage.GetPointData().GetScalars().SetTuple1(i, inval)

    # polygonal data --> image stencil:
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetInputData(pd)
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    # cut the corresponding white image and set the background:
    outval = 0
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(whiteImage)
    imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(outval)
    imgstenc.Update()
    return Volume(imgstenc.GetOutput())
Example #18
0
def processStlToImageData(dicomImageData, m_Origin, stlfilepaths):
    resultary = None
    for stlfilepath in stlfilepaths:
        if not os.path.exists(stlfilepath):
            continue
        polyData = readStlFile(stlfilepath)

        orginlData = dicomImageData
        spacing = orginlData.GetSpacing()
        outval = 0
        whiteData = vtk.vtkImageData()
        whiteData.DeepCopy(orginlData)

        pointdata = whiteData.GetPointData()
        pointscalars = pointdata.GetScalars()

        # 通过矩阵计算将whiteData中点的颜色全部设置成白色
        sc = vtk_to_numpy(pointscalars)
        sc = np.where(sc < 255, 255, 255)
        newscalars = numpy_to_vtk(sc)
        pointdata.SetScalars(newscalars)
        whiteData.Modified()

        pol2stenc = vtk.vtkPolyDataToImageStencil()
        pol2stenc.SetInputData(polyData)
        pol2stenc.SetOutputOrigin(m_Origin)
        pol2stenc.SetOutputSpacing(spacing)
        pol2stenc.SetOutputWholeExtent(orginlData.GetExtent())
        pol2stenc.Update()

        imgstenc = vtk.vtkImageStencil()
        imgstenc.SetInputData(whiteData)
        imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
        imgstenc.ReverseStencilOff()
        imgstenc.SetBackgroundValue(outval)
        imgstenc.Update()
        flip = vtk.vtkImageFlip()
        flip.SetInputData(imgstenc.GetOutput())
        flip.SetFilteredAxes(1)
        flip.Update()
        flip2 = vtk.vtkImageFlip()

        flip2.SetInputData(flip.GetOutput())
        flip2.SetFilteredAxes(2)
        flip2.Update()
        if resultary is None:
            resultary = [flip2.GetOutput()]
        else:
            resultary.append(flip2.GetOutput())
    return resultary
Example #19
0
def load_vtp_as_vtk_image(
        poly_data_fname: str,
        ref_vtk_img: vtk.vtkImageData,
        roi_value: int = 255) -> Tuple[np.ndarray, vtk.vtkStructuredPoints]:
    """
    load  vtk poly data file as vtk image data
    :param poly_data_fname: filename
    :param ref_vtk_img: reference vtk image data
    :param roi_value: roi value
    :return: img(npy format), img(vtk format)
    """

    reader = vtk.vtkXMLPolyDataReader()
    reader.SetFileName(poly_data_fname)
    reader.Update()
    whiteImage = vtk.vtkImageData()
    whiteImage.SetSpacing(ref_vtk_img.GetSpacing())
    whiteImage.SetDimensions(ref_vtk_img.GetDimensions())
    whiteImage.SetExtent(ref_vtk_img.GetExtent())
    whiteImage.SetOrigin(ref_vtk_img.GetOrigin())
    whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
    tmp = np.ones(ref_vtk_img.GetDimensions()[::-1],
                  dtype=np.uint8) * roi_value
    whiteImage.GetPointData().SetScalars(
        numpy_support.numpy_to_vtk(tmp.flatten(),
                                   deep=True,
                                   array_type=vtk.VTK_INT))

    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetInputData(reader.GetOutput())
    pol2stenc.SetOutputOrigin(ref_vtk_img.GetOrigin())
    pol2stenc.SetOutputSpacing(ref_vtk_img.GetSpacing())
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(whiteImage)
    imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(0)
    imgstenc.Update()

    vtk_img = imgstenc.GetOutput()
    img = numpy_support.vtk_to_numpy(
        vtk_img.GetPointData().GetScalars()).reshape(
            vtk_img.GetDimensions()[::-1])

    return img, vtk_img
Example #20
0
   def createMaskfromMesh(self, VOI_mesh, im):
       """ Takes an image and a VOI_mesh and returns a boolean image with only 1s inside the VOI_mesh """                
       # Create an Image 
       white_image = vtk.vtkImageData()
       white_image.DeepCopy(im) 
       
       # extract VOI bounds in dicom space
       self.VOIbounds = VOI_mesh.GetBounds()
       print "self.VOIbounds:"
       print self.VOIbounds
       
       self.VOIbounds_expand = []
       self.VOIbounds_expand.append( self.VOIbounds[0] )
       self.VOIbounds_expand.append( self.VOIbounds[1]  )
       self.VOIbounds_expand.append( self.VOIbounds[2]  )
       self.VOIbounds_expand.append( self.VOIbounds[3] )
       self.VOIbounds_expand.append(  self.VOIbounds[4] )
       self.VOIbounds_expand.append( self.VOIbounds[5] )
           
       self.VOIbounds = self.VOIbounds_expand
           
       roiStencil = vtk.vtkCubeSource()
       roiStencil.SetBounds(self.VOIbounds)
       roiStencil.Update()
       print "\nGetXLength roiStencil: %d " % roiStencil.GetXLength()
       print "GetYLength roiStencil: %d " % roiStencil.GetYLength()
       print "GetZLength roiStencil: %d " % roiStencil.GetZLength()
 
       # polygonal data --> image stencil:
       pol2stenc = vtk.vtkPolyDataToImageStencil()
       pol2stenc.SetInput(roiStencil.GetOutput())
       pol2stenc.SetOutputOrigin(im.GetOrigin())
       pol2stenc.SetOutputSpacing(im.GetSpacing())
       pol2stenc.SetOutputWholeExtent(im.GetWholeExtent())
       pol2stenc.Update()
        
       # cut the corresponding white image and set the background:
       imgstenc = vtk.vtkImageStencil()
       imgstenc.SetInput(im)
       imgstenc.SetStencil(pol2stenc.GetOutput())
       imgstenc.ReverseStencilOff()
       imgstenc.SetBackgroundValue(0.0)
       imgstenc.Update()
       
       self.VOIdims = imgstenc.GetOutput().GetDimensions()
                 
       return imgstenc.GetOutput()
Example #21
0
    def ensureInSegment(self, image, lesionMesh, pathSegment, nameSegment, image_pos_pat, image_ori_pat):    
        
        # Proceed to build reference frame for display objects based on DICOM coords   
        [transformed_image, transform_cube] = self.loadDisplay.dicomTransform(image, image_pos_pat, image_ori_pat)
        
        dataToStencil = vtk.vtkPolyDataToImageStencil()
        dataToStencil.SetInput(lesionMesh)
        dataToStencil.SetOutputOrigin(transformed_image.GetOrigin())
        print transformed_image.GetOrigin()
        dataToStencil.SetOutputSpacing(transformed_image.GetSpacing())
        print transformed_image.GetSpacing()
        dataToStencil.SetOutputWholeExtent(transformed_image.GetExtent())
        dataToStencil.Update()
        
        stencil = vtk.vtkImageStencil()
        stencil.SetInput(transformed_image)
        stencil.SetStencil(dataToStencil.GetOutput())
        stencil.ReverseStencilOff()
        stencil.SetBackgroundValue(0.0)
        stencil.Update()
        
        newSegment = vtk.vtkMetaImageWriter()
        newSegment.SetFileName(pathSegment+'/'+nameSegment+'.mhd')
        newSegment.SetInput(stencil.GetOutput())
        newSegment.Write()

        thresh = vtk.vtkImageThreshold()
        thresh.SetInput(stencil.GetOutput())
        thresh.ThresholdByUpper(1)
        thresh.SetInValue(255)
        thresh.SetOutValue(0)
        thresh.Update()
                  
        contouriso = vtk.vtkMarchingCubes()
        contouriso.SetInput(thresh.GetOutput())
        contouriso.SetValue(0,125)
        contouriso.ComputeScalarsOn()
        contouriso.Update()
        
        # Recalculate num_voxels and vol_lesion on VOI
        nvoxels = contouriso.GetOutput().GetNumberOfCells()
        npoints = contouriso.GetOutput().GetNumberOfPoints()
        print "Number of points: %d" % npoints 
        print "Number of cells: %d" % nvoxels 
        
        return contouriso.GetOutput()
Example #22
0
    def SetPolyDataConnection(self, connection, imageData):
        if self._polydata is None:
            self._polydata = GeometryObject(self._name, self._name, connection)
        else:
            self._polydata.SetInputConnection(connection)

        self._polydata.SetWireFrameOn()
        self._polydata.SetVisibilityOff()

        # set proper tolerance for converter
        imageData.UpdateInformation()
        tolerance = 0.001 * min(imageData.GetSpacing())

        # update pipeline
        connection.GetProducer().Update()

        polyData = connection.GetProducer().GetOutputDataObject(0)

        b = polyData.GetBounds()
        s = imageData.GetSpacing()
        o = imageData.GetOrigin()
        extent = [int((b[0] - o[0]) / s[0]), int((b[1] - o[0]) / s[0]) + 1,
                  int((b[2] - o[1]) / s[1]), int((b[3] - o[1]) / s[1]) + 1,
                  int((b[4] - o[2]) / s[2]), int((b[5] - o[2]) / s[2]) + 1]

        stencil = vtk.vtkPolyDataToImageStencil()
        stencil.ReleaseDataFlagOn()
        stencil.SetTolerance(tolerance)
        stencil.SetInputConnection(connection)
        stencil.SetOutputSpacing(imageData.GetSpacing())
        stencil.SetOutputOrigin(imageData.GetOrigin())
        stencil.SetOutputWholeExtent(extent)

        # stencil.GetOutput().SetWholeExtent(extent)
        # stencil.GetOutput().SetUpdateExtentToWholeExtent()
        # stencil.GetOutput().SetExtent(imageData.GetExtent())
        # stencil.GetOutput().SetOrigin(imageData.GetOrigin())
        # stencil.GetOutput().SetSpacing(imageData.GetSpacing())
        try:
            stencil.GetOutput().Update()
        except:
            print sys.exc_type, sys.exc_value
            return -1

        self._stencil_data = stencil.GetOutput()
        self.ClearPolyData()
  def clipVolumeWithPolyData(self, inputVolume, polyData, clipOutsideSurface, fillValue, leftTransformMatrix = None):
    leftMatrix = vtk.vtkMatrix4x4()
    leftMatrix.Identity()
    if leftTransformMatrix:
      leftMatrix.DeepCopy(leftTransformMatrix)
    ijkToRas = vtk.vtkMatrix4x4()
    inputVolume.GetIJKToRASMatrix(ijkToRas)
    ijkToModel = vtk.vtkMatrix4x4()
    vtk.vtkMatrix4x4.Multiply4x4(leftMatrix, ijkToRas, ijkToModel)
    modelToIjkTransform = vtk.vtkTransform()
    modelToIjkTransform.SetMatrix(ijkToModel)
    modelToIjkTransform.Inverse()
    transformModelToIjk = vtk.vtkTransformPolyDataFilter()
    transformModelToIjk.SetTransform(modelToIjkTransform)
    transformModelToIjk.SetInputData(polyData)
    transformModelToIjk.Update()

    # Use the stencil to fill the volume

    # Convert model to stencil
    polyToStencil = vtk.vtkPolyDataToImageStencil()
    polyToStencil.SetInputConnection(transformModelToIjk.GetOutputPort())
    polyToStencil.SetOutputSpacing(inputVolume.GetImageData().GetSpacing())
    polyToStencil.SetOutputOrigin(inputVolume.GetImageData().GetOrigin())
    polyToStencil.SetOutputWholeExtent(inputVolume.GetImageData().GetExtent())

    # Apply the stencil to the volume
    stencilToImage = vtk.vtkImageStencil()
    stencilToImage.SetInputConnection(inputVolume.GetImageDataConnection())
    stencilToImage.SetStencilConnection(polyToStencil.GetOutputPort())
    if clipOutsideSurface:
      stencilToImage.ReverseStencilOff()
    else:
      stencilToImage.ReverseStencilOn()
    stencilToImage.SetBackgroundValue(fillValue)
    stencilToImage.Update()

    # Update the volume with the stencil operation result
    outputImageData = vtk.vtkImageData()
    outputImageData.DeepCopy(stencilToImage.GetOutput())
    return outputImageData
Example #24
0
def pd_to_numpy_vol(pd, spacing=[1.,1.,1.], shape=None, origin=None, foreground_value=255, backgroud_value = 0):
    if shape is None:
        bnds = np.array(pd.GetBounds())
        shape = np.ceil((bnds[1::2]-bnds[::2])/spacing).astype(int)+15
    if origin is None:
        origin = bnds[::2]+(bnds[1::2]-bnds[::2])/2

    #make image
    extent = np.zeros(6).astype(int)
    extent[1::2] = np.array(shape)-1

    imgvtk = vtk.vtkImageData()
    imgvtk.SetSpacing(spacing)
    imgvtk.SetOrigin(origin)
    imgvtk.SetExtent(extent)
    imgvtk.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)

    vtk_data_array = numpy_support.numpy_to_vtk(num_array=np.ones(shape[::-1]).ravel()*backgroud_value,  # ndarray contains the fitting result from the points. It is a 3D array
                                                deep=True, array_type=vtk.VTK_FLOAT)

    imgvtk.GetPointData().SetScalars(vtk_data_array)

    #poly2 stencil
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetInputData(pd)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputWholeExtent(extent)
    pol2stenc.Update()

    #stencil to image
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(imgvtk)
    imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
    imgstenc.ReverseStencilOn()
    imgstenc.SetBackgroundValue(foreground_value)
    imgstenc.Update()

    ndseg = numpy_support.vtk_to_numpy(imgstenc.GetOutputDataObject(0).GetPointData().GetArray(0))
    return ndseg.reshape(shape[::-1])
def triSurface2BinaryMask(v,
                          t,
                          imageShape,
                          voxelOrigin=None,
                          voxelSpacing=None,
                          bg=0):

    imgDtype = np.int16
    if voxelOrigin is None:
        voxelOrigin = [0.0, 0.0, 0.0]
    if voxelSpacing is None:
        voxelSpacing = [1.0, 1.0, 1.0]

    # make into vtkPolydata
    gfPoly = vtktools.tri2Polydata(v, t)

    # create mask vtkImage
    maskImageArray = np.ones(imageShape, dtype=imgDtype)
    maskVTKImage = vtktools.array2vtkImage(maskImageArray,
                                           imgDtype,
                                           flipDim=False)

    # create stencil from polydata
    stencilMaker = vtk.vtkPolyDataToImageStencil()
    stencilMaker.SetInput(gfPoly)
    stencilMaker.SetOutputOrigin(voxelOrigin)
    stencilMaker.SetOutputSpacing(voxelSpacing)
    stencilMaker.SetOutputWholeExtent(maskVTKImage.GetExtent())

    stencil = vtk.vtkImageStencil()
    stencil.SetInput(maskVTKImage)
    stencil.SetStencil(stencilMaker.GetOutput())
    stencil.SetBackgroundValue(bg)
    stencil.ReverseStencilOff()
    stencil.Update()

    maskImageArray = vtktools.vtkImage2Array(stencil.GetOutput(),
                                             imgDtype,
                                             flipDim=True)
    return maskImageArray, gfPoly
Example #26
0
def mesh2image(pd, spacing, bounds, value=255):
    """Generates an image in which pixels inside the surface set to value."""
    # start with white image
    dim, origin = bounds_dim_origin(bounds, spacing)
    whiteimage = image_from_value(spacing, dim, origin, value)

    # polygonal data to image stencil
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetInput(pd)
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputWholeExtent(0, dim[0], 0, dim[1], 0, dim[2])
    pol2stenc.Update()

    # cut the corresponding white image and set the background
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInput(whiteimage)
    imgstenc.SetStencil(pol2stenc.GetOutput())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(0)
    imgstenc.Update()
    return imgstenc.GetOutput()
def polydata_to_volume(polydata):
    """
    Parameters
    ----------
    polydata : vtkPolyData
        input polydata

    Returns
    -------
    (numpy arr, 3-tuple, vtkImageData)
        (volume, origin, imagedata)

    """

    bounds = polydata.GetBounds()
    spacing = [1., 1., 1.]

    origin = [
        bounds[0] + spacing[0] / 2, bounds[2] + spacing[1] / 2,
        bounds[4] + spacing[2] / 2
    ]

    whiteImage = vtk.vtkImageData()
    whiteImage.SetSpacing(spacing)
    whiteImage.SetOrigin(origin)

    dim = np.array([
        np.ceil(bounds[1] - bounds[0]) / spacing[0],
        np.ceil(bounds[3] - bounds[2]) / spacing[1],
        np.ceil(bounds[5] - bounds[4]) / spacing[2]
    ], np.int)

    whiteImage.SetDimensions(dim)
    whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1)

    # whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
    n_pts = whiteImage.GetNumberOfPoints()

    # t = time.time()
    #    inval = 255
    #    outval = 0
    #    for i in range(n_pts):
    #        whiteImage.GetPointData().GetScalars().SetTuple1(i, inval)
    whiteImage.GetPointData().SetScalars(
        numpy_support.numpy_to_vtk(
            255 * np.ones((n_pts, ), np.uint8),
            deep=True,
            array_type=vtk.VTK_UNSIGNED_CHAR))  # deep copy must be true
    # sys.stderr.write('time 1: %.2f\n' % (time.time() - t) )

    # t = time.time()

    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetInputData(polydata)
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    # sys.stderr.write('time 2: %.2f\n' % (time.time() - t) )

    # t = time.time()

    # cut the corresponding white image and set the background:
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(whiteImage)
    imgstenc.SetStencilData(pol2stenc.GetOutput())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(0)
    imgstenc.Update()

    # sys.stderr.write('time 3: %.2f\n' % (time.time() - t) )

    # t = time.time()

    im = imgstenc.GetOutput()
    x, y, z = im.GetDimensions()
    sc = im.GetPointData().GetScalars()
    a = numpy_support.vtk_to_numpy(sc)
    b = a.reshape(z, y, x)
    b = np.transpose(b, [1, 2, 0])

    # sys.stderr.write('time 4: %.2f\n' % (time.time() - t) )

    return b, origin, im
def main():
    # 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()
    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)
    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()
    extruder.SetInputData(circle)
    extruder.SetScaleFactor(1.0)
    #extruder.SetExtrusionTypeToNormalExtrusion() # not working
    extruder.SetExtrusionTypeToVectorExtrusion()
    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.SetInputData(circle)
    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    # cut the corresponding white image and set the background:
    imgstenc = vtk.vtkImageStencil()
    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()
Example #29
0
def mesh_2_mask(
    inputMesh, outputImage, inputImage=None, superRes=False, spacing=(1.0, 1.0, 1.0)
):
    """
    This program takes in a closed 3D surface, vtkPolyData, and converts it into volume
    representation (vtkImageData) where the foreground voxels are 1 and the background voxels
    are 0. Internally vtkPolyDataToImageStencil is utilized. The resultant image is saved to disk
    in NIFTIimage file format. SimpleITK is used to convert images to standard orientation used
    for 3D medical images.

    :param inputMesh: a vtkPolyData file of a 3D surface
    :param outputImage: output file path for NIFTI image
    :param inputImage: reference image to get desired spacing, origin, and direction.
    :param superRes:
    :param spacing:
    :return:
    """

    VTK_MAJOR_VERSION = str(vtk.vtkVersion().GetVTKVersion()).split(".")[0]

    outputImage = str(outputImage)
    if inputImage:
        inputImage = str(inputImage)

    # check output image extension
    out_ext = outputImage.split(".", 1)[-1]
    if "nii" in out_ext:
        writer = vtk.vtkNIFTIImageWriter()
    else:
        print(
            "ERROR: Output must be NIFTI image file. \n\tUnrecognized extension: {0}".format(
                out_ext
            )
        )
        return sys.exit(os.EX_IOERR)

    if inputImage:
        image = read_vtk_image(inputImage)
    else:
        image = None

    # read the mesh in
    pd = read_poly_data(inputMesh)
    pd = preprocess_mesh(pd)

    # allocate whiteImage
    whiteImage = vtk.vtkImageData()

    # polygonal data -. image stencil:
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    if VTK_MAJOR_VERSION <= 5:
        pol2stenc.SetInput(pd)
    else:
        pol2stenc.SetInputData(pd)

    # get the bounds
    bounds = pd.GetBounds()

    if image:
        spacing = image.GetSpacing()
        dim = image.GetDimensions()
        # set VTK direction to RAS
        vtk_direction = (-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0)

        # vtk does not get the correct origin
        # origin = image.GetOrigin ()

        # use SimpleITK instead
        image_sitk = sitk.ReadImage(inputImage)
        origin = image_sitk.GetOrigin()
        direction = image_sitk.GetDirection()

        print(direction)
        print(origin)
        print(spacing)

        # superRes slows down the script quite a bit
        if superRes:
            """Creates an image with pixels a fourth the size of the original
            This helps allivaite some of the partial voluming effect that
            can take place."""
            denom = 2
            spacing = (
                spacing[0] / float(denom),
                spacing[1] / float(denom),
                spacing[2] / float(denom),
            )
            dim = (dim[0] * denom, dim[1] * denom, dim[2] * denom)

        # VTKImages seem to always have the same direction
        origin = (
            origin[0] * vtk_direction[0],
            origin[1] * vtk_direction[4],
            origin[2] * vtk_direction[8],
        )
        if direction != vtk_direction:
            if direction == (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0):
                origin = (
                    origin[0] - spacing[0] * (dim[0] - 1),
                    origin[1] - spacing[1] * (dim[1] - 1),
                    origin[2],
                )
            else:
                print("ERROR: Not sure how to handle input image direction")
                sys.exit()
        print(origin)
    else:
        if superRes:
            spacing = (
                spacing[0] / float(2),
                spacing[1] / float(2),
                spacing[2] / float(2),
            )

        # compute dimensions
        dim = [0, 0, 0]
        for i in range(3):
            dim[i] = int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]))
        dim = tuple(dim)

        # get origin
        origin = [0, 0, 0]
        origin[0] = bounds[0] + spacing[0] / float(2)
        origin[1] = bounds[2] + spacing[1] / float(2)
        origin[2] = bounds[4] + spacing[2] / float(2)
        origin = tuple(origin)

    whiteImage.SetSpacing(spacing)
    whiteImage.SetOrigin(origin)

    pol2stenc.SetOutputOrigin(origin)
    pol2stenc.SetOutputSpacing(spacing)

    # set dimensions
    whiteImage.SetDimensions(dim)
    whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1)

    if VTK_MAJOR_VERSION <= 5:
        whiteImage.SetScalarTypeToUnsignedChar()
        whiteImage.AllocateScalars()
    else:
        whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)

    # fill the image with foreground voxels:
    inval = 1
    outval = 0
    count = whiteImage.GetNumberOfPoints()
    for i in range(count):
        whiteImage.GetPointData().GetScalars().SetTuple1(i, inval)

    # update pol2stenc
    pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent())
    pol2stenc.Update()

    # cut the corresponding white image and set the background:
    imgstenc = vtk.vtkImageStencil()
    if 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()

    # write image to file

    writer.SetFileName(outputImage)

    if inputImage != None and direction != vtk_direction:
        flipFilter = vtk.vtkImageFlip()
        flipFilter.SetFilteredAxis(1)  # flip y axis
        flipFilter.SetInputData(imgstenc.GetOutput())
        flipFilter.SetFlipAboutOrigin(1)
        flipFilter.Update()

        flipFilter2 = vtk.vtkImageFlip()
        flipFilter2.SetFilteredAxis(0)  # flip x axis
        flipFilter2.SetInputData(flipFilter.GetOutput())
        flipFilter2.SetFlipAboutOrigin(1)
        flipFilter2.Update()

        if VTK_MAJOR_VERSION <= 5:
            writer.SetInput(flipFilter2.GetOutput())
        else:
            writer.SetInputData(flipFilter2.GetOutput())
        writer.Write()

        itk_image = sitk.ReadImage(inputImage)
        out_image = sitk.ReadImage(outputImage)
        out_image.SetDirection(itk_image.GetDirection())
        out_image.SetOrigin(itk_image.GetOrigin())
        sitk.WriteImage(out_image, outputImage)
    else:
        if VTK_MAJOR_VERSION <= 5:
            writer.SetInput(imgstenc.GetOutput())
        else:
            writer.SetInputData(imgstenc.GetOutput())
        writer.Write()

    return os.path.abspath(outputImage)
  def apply(self, segmentMarkupNode, segmentModel, text, textDepth, mode):

    self.updateModel(segmentMarkupNode, segmentModel, text, textDepth)

    import vtkSegmentationCore

    if not segmentMarkupNode:
      raise AttributeError(f"{self.__class__.__name__}: segment markup node not set.")
    if not segmentModel:
      raise AttributeError(f"{self.__class__.__name__}: segment model not set.")

    if segmentMarkupNode and segmentModel.GetPolyData().GetNumberOfCells() > 0:
      segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
      if not segmentationNode:
        raise AttributeError(f"{self.__class__.__name__}: Segmentation node not set.")

      modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
      if not modifierLabelmap:
        raise AttributeError("{}: ModifierLabelmap not set. This can happen for various reasons:\n"
                             "No master volume set for segmentation,\n"
                             "No existing segments for segmentation, or\n"
                             "No referenceImageGeometry is specified in the segmentation".format(self.__class__.__name__))

      WorldToModifierLabelmapIjkTransform = vtk.vtkTransform()

      WorldToModifierLabelmapIjkTransformer = vtk.vtkTransformPolyDataFilter()
      WorldToModifierLabelmapIjkTransformer.SetTransform(WorldToModifierLabelmapIjkTransform)
      WorldToModifierLabelmapIjkTransformer.SetInputConnection(segmentModel.GetPolyDataConnection())

      segmentationToSegmentationIjkTransformMatrix = vtk.vtkMatrix4x4()
      modifierLabelmap.GetImageToWorldMatrix(segmentationToSegmentationIjkTransformMatrix)
      segmentationToSegmentationIjkTransformMatrix.Invert()
      WorldToModifierLabelmapIjkTransform.Concatenate(segmentationToSegmentationIjkTransformMatrix)

      worldToSegmentationTransformMatrix = vtk.vtkMatrix4x4()
      slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes(None, segmentationNode.GetParentTransformNode(),
                                                                 worldToSegmentationTransformMatrix)
      WorldToModifierLabelmapIjkTransform.Concatenate(worldToSegmentationTransformMatrix)
      WorldToModifierLabelmapIjkTransformer.Update()

      polyToStencil = vtk.vtkPolyDataToImageStencil()
      polyToStencil.SetOutputSpacing(1.0, 1.0, 1.0)
      polyToStencil.SetInputConnection(WorldToModifierLabelmapIjkTransformer.GetOutputPort())
      boundsIjk = WorldToModifierLabelmapIjkTransformer.GetOutput().GetBounds()
      modifierLabelmapExtent = self.scriptedEffect.modifierLabelmap().GetExtent()
      polyToStencil.SetOutputWholeExtent(modifierLabelmapExtent[0], modifierLabelmapExtent[1],
                                         modifierLabelmapExtent[2], modifierLabelmapExtent[3],
                                         int(round(boundsIjk[4])), int(round(boundsIjk[5])))
      polyToStencil.Update()

      stencilData = polyToStencil.GetOutput()
      stencilExtent = [0, -1, 0, -1, 0, -1]
      stencilData.SetExtent(stencilExtent)

      stencilToImage = vtk.vtkImageStencilToImage()
      stencilToImage.SetInputConnection(polyToStencil.GetOutputPort())
      stencilToImage.SetInsideValue(1.0)
      stencilToImage.SetOutsideValue(0.0)
      stencilToImage.SetOutputScalarType(modifierLabelmap.GetScalarType())

      stencilPositioner = vtk.vtkImageChangeInformation()
      stencilPositioner.SetInputConnection(stencilToImage.GetOutputPort())
      stencilPositioner.SetOutputSpacing(modifierLabelmap.GetSpacing())
      stencilPositioner.SetOutputOrigin(modifierLabelmap.GetOrigin())

      stencilPositioner.Update()
      orientedStencilPositionerOutput = vtkSegmentationCore.vtkOrientedImageData()
      orientedStencilPositionerOutput.ShallowCopy(stencilToImage.GetOutput())
      imageToWorld = vtk.vtkMatrix4x4()
      modifierLabelmap.GetImageToWorldMatrix(imageToWorld)
      orientedStencilPositionerOutput.SetImageToWorldMatrix(imageToWorld)

      vtkSegmentationCore.vtkOrientedImageDataResample.ModifyImage(
        modifierLabelmap, orientedStencilPositionerOutput,
        vtkSegmentationCore.vtkOrientedImageDataResample.OPERATION_MAXIMUM)

      modeName = self.scriptedEffect.parameter("Mode")
      if modeName == "EMBOSS":
        mode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd
      elif modeName == "ENGRAVE":
        mode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeRemove
      else:
        logging.error("Invalid mode: "+modeName+" (valid modes: EMBOSS, ENGRAVE)")
      self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, mode)

      # get plane parameters as space-separated string list
      planeParameters = []
      if segmentMarkupNode.GetIsPlaneValid():
        planeParameters.extend(segmentMarkupNode.GetOriginWorld())
        xAxis = [1, 0, 0]
        yAxis = [0, 1, 0]
        zAxis = [0, 0, 1]
        segmentMarkupNode.GetAxesWorld(xAxis, yAxis, zAxis)
        planeParameters.extend(xAxis)
        planeParameters.extend(yAxis)
        planeParameters.extend(zAxis)
        planeParameters.extend(segmentMarkupNode.GetPlaneBounds())
      planeParametersString = ' '.join(map(str, planeParameters))

      segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
      segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
      segment.SetTag("EngraveEffectPlaneParameters", planeParametersString)
Example #31
0
    def _poly2img(self, ind):
        """
        Helper function called by **deformableRegistration()** that generates
        images from polygonal surfaces in reference/deformed pairs. The voxel
        dimension of these images is determined by the value for **Precision**
        in **deformableSettings**.

        Parameters
        ----------
        ind : int
            The list index for the current object pair being analyzed.

        Returns
        -------
            (Reference Image, Deformed Image, Tranformed Reference Surface)
        """
        dim = int(np.ceil(old_div(1.0, self.deformableSettings['Precision']))) + 10
        rpoly = vtk.vtkPolyData()
        rpoly.DeepCopy(self.rsurfs[ind])
        dpoly = self.dsurfs[ind]
        if self.rigidInitial:
            rot = vtk.vtkTransformPolyDataFilter()
            rot.SetInputData(rpoly)
            rot.SetTransform(self.rigidTransforms[ind])
            rot.Update()
            rpoly = rot.GetOutput()

        rbounds = np.zeros(6, np.float32)
        dbounds = np.copy(rbounds)

        rpoly.GetBounds(rbounds)
        dpoly.GetBounds(dbounds)

        spacing = np.zeros(3, np.float32)
        for i in range(3):
            rspan = rbounds[2 * i + 1] - rbounds[2 * i]
            dspan = dbounds[2 * i + 1] - dbounds[2 * i]
            spacing[i] = (np.max([rspan, dspan])
                          * self.deformableSettings['Precision'])

        imgs = []
        half = old_div(float(dim), 2.0)
        for i in range(2):
            arr = np.ones((dim, dim, dim), np.uint8)
            arr2img = vti.vtkImageImportFromArray()
            arr2img.SetDataSpacing(spacing)
            arr2img.SetDataExtent((0, dim - 1, 0, dim - 1, 0, dim - 1))
            arr2img.SetArray(arr)
            arr2img.Update()
            if i == 0:
                rimg = arr2img.GetOutput()
                rimg.SetOrigin((np.mean(rbounds[0:2]) -
                                half * spacing[0] + old_div(spacing[0], 2),
                                np.mean(rbounds[2:4]) -
                                half * spacing[1] + old_div(spacing[1], 2),
                                np.mean(rbounds[4:]) -
                                half * spacing[2] + old_div(spacing[2], 2)))
            else:
                dimg = arr2img.GetOutput()
                dimg.SetOrigin((np.mean(dbounds[0:2]) -
                                half * spacing[0] + old_div(spacing[0], 2),
                                np.mean(dbounds[2:4]) -
                                half * spacing[1] + old_div(spacing[1], 2),
                                np.mean(dbounds[4:]) -
                                half * spacing[2] + old_div(spacing[2], 2)))
        imgs = []
        for (pd, img) in [(rpoly, rimg), (dpoly, dimg)]:
            pol2stenc = vtk.vtkPolyDataToImageStencil()
            pol2stenc.SetInputData(pd)
            pol2stenc.SetOutputOrigin(img.GetOrigin())
            pol2stenc.SetOutputSpacing(img.GetSpacing())
            pol2stenc.SetOutputWholeExtent(img.GetExtent())
            pol2stenc.SetTolerance(0.0001)
            pol2stenc.Update()

            imgstenc = vtk.vtkImageStencil()
            imgstenc.SetInputData(img)
            imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
            imgstenc.ReverseStencilOff()
            imgstenc.SetBackgroundValue(0)
            imgstenc.Update()

            arr = vtk_to_numpy(imgstenc.GetOutput().GetPointData().GetArray(0))
            arr = arr.reshape(dim, dim, dim)
            itk_img = sitk.GetImageFromArray(arr)
            itk_img.SetSpacing(img.GetSpacing())
            itk_img.SetOrigin(img.GetOrigin())
            imgs.append(itk_img)
        return (imgs[0], imgs[1], rpoly)
Example #32
0
    def Execute(self):
        if self.Surface == None:
            self.PrintError('Error: No Input Surface.')

        if self.InsideValue > 255:
            self.PrintError('Error: Cannot assign InsideValue of image to value greater than 255')

        # Step 1: Convert the input surface into an image mask of unsigned char type and spacing = PolyDataToImageDataSpacing
        #         Where voxels lying inside the surface are set to 255 and voxels outside the image are set to value 0. 

        # since we are creating a new image container from nothing, calculate the origin, extent, and dimensions for the
        # vtkImageDataObject from the surface parameters.
        bounds = self.Surface.GetBounds()
        dim = []   # list of size: 3, type: int
        for i in range(3):
            dim.append(int(math.ceil((bounds[i * 2 + 1] - bounds[i * 2]) / self.PolyDataToImageDataSpacing[i])))

        origin = [bounds[0] + self.PolyDataToImageDataSpacing[0] / 2,
                  bounds[2] + self.PolyDataToImageDataSpacing[1] / 2,
                  bounds[4] + self.PolyDataToImageDataSpacing[2] / 2]

        extent = [0, dim[0] - 1,
                  0, dim[1] - 1,
                  0, dim[2] - 1]

        whiteImage = vtk.vtkImageData()
        whiteImage.SetSpacing(self.PolyDataToImageDataSpacing[0],
                              self.PolyDataToImageDataSpacing[1], 
                              self.PolyDataToImageDataSpacing[2])
        whiteImage.SetDimensions(dim[0], dim[1], dim[2])
        whiteImage.SetExtent(extent[0], extent[1],
                             extent[2], extent[3],
                             extent[4], extent[5])
        whiteImage.SetOrigin(origin[0], origin[1], origin[2])
        whiteImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)

        # initially set all values of the image to a value self.InsideValue
        npFillImagePoints = np.zeros(whiteImage.GetNumberOfPoints(), dtype=np.uint8)
        npFillImagePoints[:] = self.InsideValue
        # it is much faster to use the vtk data set adaptor functions to fill the point data tupples that it is to
        # loop over each index and set values individually. 
        pointDataArray = dsa.numpyTovtkDataArray(npFillImagePoints, name='ImageScalars', array_type=vtk.VTK_UNSIGNED_CHAR)
        whiteImage.GetPointData().SetActiveScalars('ImageScalars')
        whiteImage.GetPointData().SetScalars(pointDataArray)

        # The vtkPolyDataToImageStencil class will convert polydata into an image stencil, masking an image. 
        # The polydata can either be a closed surface mesh or a series of polyline contours (one contour per slice).
        polyDataToImageStencilFilter = vtk.vtkPolyDataToImageStencil()
        polyDataToImageStencilFilter.SetInputData(self.Surface)
        polyDataToImageStencilFilter.SetOutputSpacing(self.PolyDataToImageDataSpacing[0], 
                                                      self.PolyDataToImageDataSpacing[1], 
                                                      self.PolyDataToImageDataSpacing[2])
        polyDataToImageStencilFilter.SetOutputOrigin(origin[0], origin[1], origin[2])
        polyDataToImageStencilFilter.Update()

        # vtkImageStencil combines to images together by using a "cookie-cutter" operation. 
        imageStencil = vtk.vtkImageStencil()
        imageStencil.SetInputData(whiteImage)
        imageStencil.SetStencilConnection(polyDataToImageStencilFilter.GetOutputPort())
        imageStencil.ReverseStencilOff()
        imageStencil.SetBackgroundValue(self.OutsideValue)
        imageStencil.Update()

        self.Image = imageStencil.GetOutput()
Example #33
0
imageBounds = image.GetBounds()

#Debugging
#Log ("Read %d points from test AIM file." % image.GetNumberOfPoints())
#imageBoundstest = image.GetBounds()
#Log ("Image bounds:", ("%.4f" + " %.4f"*5) % imageBoundstest)

cortMask = vtk.vtkPolyDataReader()
cortMask.SetFileName(inputCortMaskFile)
cortMask.Update()

#trabMask = vtk.vtkPolyDataReader()
#trabMask.SetFileName(trabMaskFile)
#trabMask.Update()

stencilData = vtk.vtkPolyDataToImageStencil()
stencilData.SetInput(cortMask.GetOutput())
stencilData.SetInformationInput(image)

stencil = vtk.vtkImageStencil()
stencil.SetInput(image)
stencil.SetBackgroundValue(-500)
stencil.SetStencil(stencilData.GetOutput())
stencil.Update()

imagetest = stencil.GetOutput()
imageBoundstest = imagetest.GetBounds()

#Debugging
#Log ("Read %d points from test AIM file." % imagetest.GetNumberOfPoints())
#imageBoundstest = imagetest.GetBounds()

# 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())
Example #35
0
    def _buildPipeline(self):
        """Build underlying pipeline and configure rest of pipeline-dependent
        UI. 
        """

        # add the renderer
        self._renderer = vtk.vtkRenderer()
        self._renderer.SetBackground(0.5, 0.5, 0.5)
        self._viewFrame.rwi.GetRenderWindow().AddRenderer(self._renderer)

        self._histogram = vtkdevide.vtkImageHistogram2D()

        # make sure the user can't do anything entirely stupid
        istyle = vtk.vtkInteractorStyleImage()
        self._viewFrame.rwi.SetInteractorStyle(istyle)

        # we'll use this to keep track of our ImagePlaneWidget
        self._ipw = None
        self._overlayipw = None
        self._scalarBarWidget = None

        #
        self._appendPD = vtk.vtkAppendPolyData()

        self._extrude = vtk.vtkLinearExtrusionFilter()
        self._extrude.SetInput(self._appendPD.GetOutput())
        self._extrude.SetScaleFactor(1)
        self._extrude.SetExtrusionTypeToNormalExtrusion()
        self._extrude.SetVector(0, 0, 1)

        self._pdToImageStencil = vtk.vtkPolyDataToImageStencil()
        self._pdToImageStencil.SetInput(self._extrude.GetOutput())

        # stupid trick to make image with all ones, but as large as its
        # input

        self._allOnes = vtk.vtkImageThreshold()
        self._allOnes.ThresholdByLower(0.0)
        self._allOnes.ThresholdByUpper(0.0)
        self._allOnes.SetInValue(1.0)
        self._allOnes.SetOutValue(1.0)
        self._allOnes.SetInput(self._histogram.GetOutput())

        self._stencil = vtk.vtkImageStencil()
        self._stencil.SetInput(self._allOnes.GetOutput())
        # self._stencil.SetStencil(self._pdToImageStencil.GetOutput())
        self._stencil.ReverseStencilOff()
        self._stencil.SetBackgroundValue(0)

        self._lookupAppend = vtk.vtkImageAppendComponents()

        self._lookup = vtkdevide.vtkHistogramLookupTable()
        self._lookup.SetInput1(self._lookupAppend.GetOutput())
        self._lookup.SetInput2(self._stencil.GetOutput())

        module_utils.create_standard_object_introspection(
            self,
            self._viewFrame,
            self._viewFrame.viewFramePanel,
            {"Module (self)": self, "vtkHistogram2D": self._histogram, "vtkRenderer": self._renderer},
            self._renderer.GetRenderWindow(),
        )

        # add the ECASH buttons
        module_utils.create_eoca_buttons(self, self._viewFrame, self._viewFrame.viewFramePanel)
Example #36
0
def __vtu2mhd__(vtp, spacing=[1.0, 1.0, 1.0]):
    from math import ceil

    bounds = [0.0] * 6
    vtp.GetBounds(bounds)
    #print bounds

    whiteImage = vtk.vtkImageData()
    whiteImage.SetSpacing(spacing)

    ## compute dimensions
    dim = [0.0, 0.0, 0.0]
    for i in range(3):
        #print (bounds[i * 2 + 1] - bounds[i * 2])/ spacing[i]
        dim[i] = ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i])

    print dim

    whiteImage.SetDimensions(dim)
    whiteImage.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1)

    origin = [0.0, 0.0, 0.0]
    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 i in range(count):
        whiteImage.GetPointData().GetScalars().SetTuple1(i, inval)

    ## Polygonal data --> image stencil:
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    if vtk.VTK_MAJOR_VERSION <= 5:
        pol2stenc.SetInput(vtp)
    else:
        pol2stenc.SetInputData(vtp)
    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()

    return pol2stenc
Example #37
0
def make_patterned_polydata(
    inputContours, fillareastyle=None, fillareaindex=None, fillareacolors=None, fillareaopacity=None, size=None
):
    if inputContours is None or fillareastyle == "solid":
        return None
    if inputContours.GetNumberOfCells() == 0:
        return None
    if fillareaindex is None:
        fillareaindex = 1
    if fillareaopacity is None:
        fillareaopacity = 100
    num_pixels = num_pixels_for_size(size)

    # Create the plane that will be textured with the pattern
    # The bounds of the plane match the bounds of the input polydata
    bounds = inputContours.GetBounds()

    patternPlane = vtk.vtkPlaneSource()
    patternPlane.SetOrigin(bounds[0], bounds[2], 0.0)
    patternPlane.SetPoint1(bounds[0], bounds[3], 0.0)
    patternPlane.SetPoint2(bounds[1], bounds[2], 0.0)
    # Generate texture coordinates for the plane
    textureMap = vtk.vtkTextureMapToPlane()
    textureMap.SetInputConnection(patternPlane.GetOutputPort())

    # Create the pattern image of the size of the input polydata
    # and type defined by fillareaindex
    xBounds = bounds[1] - bounds[0]
    yBounds = bounds[3] - bounds[2]

    if xBounds <= 1 and yBounds <= 1 and size is not None:
        xBounds *= size[0]
        yBounds *= size[1]
        xres, yres = int(xBounds), int(yBounds)

    xres = int(4.0 * xBounds)
    yres = int(4.0 * yBounds)

    # Handle the case when the bounds are less than 1 in physical dimensions

    patternImage = create_pattern(xres, yres, num_pixels, fillareastyle, fillareaindex, fillareacolors, fillareaopacity)
    if patternImage is None:
        return None

    # Extrude the contour since vtkPolyDataToImageStencil
    # requires 3D polydata
    extruder = vtk.vtkLinearExtrusionFilter()
    extruder.SetInputData(inputContours)
    extruder.SetScaleFactor(1.0)
    extruder.SetVector(0, 0, 1)
    extruder.SetExtrusionTypeToNormalExtrusion()

    # Create a binary image mask from the extruded polydata
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetTolerance(0)
    pol2stenc.SetInputConnection(extruder.GetOutputPort())
    pol2stenc.SetOutputOrigin(bounds[0], bounds[2], 0.0)
    pol2stenc.SetOutputSpacing((bounds[1] - bounds[0]) / xres, (bounds[3] - bounds[2]) / yres, 0.0)
    pol2stenc.SetOutputWholeExtent(patternImage.GetExtent())

    # Stencil out the fillarea from the pattern image
    stenc = vtk.vtkImageStencil()
    stenc.SetInputData(patternImage)
    stenc.SetStencilConnection(pol2stenc.GetOutputPort())
    stenc.ReverseStencilOff()
    stenc.SetBackgroundColor(0, 0, 0, 0)
    stenc.Update()
    patternImage = stenc.GetOutput()

    # Create the texture using the stenciled pattern
    patternTexture = vtk.vtkTexture()
    patternTexture.SetInputData(patternImage)
    patternTexture.InterpolateOn()
    patternTexture.RepeatOn()
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(textureMap.GetOutputPort())
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.SetTexture(patternTexture)
    return actor
Example #38
0
    def onApply(self):

        import vtkSegmentationCorePython as vtkSegmentationCore

        # Allow users revert to this state by clicking Undo
        self.scriptedEffect.saveStateForUndo()

        # This can be a long operation - indicate it to the user
        qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

        if self.segmentMarkupNode and (
                self.segmentModel.GetPolyData().GetNumberOfPolys() > 0):
            self.observeSegmentation(False)
            operationName = self.scriptedEffect.parameter("Operation")
            modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
            segmentationNode = self.scriptedEffect.parameterSetNode(
            ).GetSegmentationNode()
            WorldToModifierLabelmapIjkTransform = vtk.vtkTransform()

            WorldToModifierLabelmapIjkTransformer = vtk.vtkTransformPolyDataFilter(
            )
            WorldToModifierLabelmapIjkTransformer.SetTransform(
                WorldToModifierLabelmapIjkTransform)
            WorldToModifierLabelmapIjkTransformer.SetInputConnection(
                self.segmentModel.GetPolyDataConnection())

            segmentationToSegmentationIjkTransformMatrix = vtk.vtkMatrix4x4()
            modifierLabelmap.GetImageToWorldMatrix(
                segmentationToSegmentationIjkTransformMatrix)
            segmentationToSegmentationIjkTransformMatrix.Invert()
            WorldToModifierLabelmapIjkTransform.Concatenate(
                segmentationToSegmentationIjkTransformMatrix)

            worldToSegmentationTransformMatrix = vtk.vtkMatrix4x4()
            slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes(
                None, segmentationNode.GetParentTransformNode(),
                worldToSegmentationTransformMatrix)
            WorldToModifierLabelmapIjkTransform.Concatenate(
                worldToSegmentationTransformMatrix)
            WorldToModifierLabelmapIjkTransformer.Update()

            polyToStencil = vtk.vtkPolyDataToImageStencil()
            polyToStencil.SetOutputSpacing(1.0, 1.0, 1.0)
            polyToStencil.SetInputConnection(
                WorldToModifierLabelmapIjkTransformer.GetOutputPort())
            boundsIjk = WorldToModifierLabelmapIjkTransformer.GetOutput(
            ).GetBounds()
            modifierLabelmapExtent = self.scriptedEffect.modifierLabelmap(
            ).GetExtent()
            polyToStencil.SetOutputWholeExtent(modifierLabelmapExtent[0],
                                               modifierLabelmapExtent[1],
                                               modifierLabelmapExtent[2],
                                               modifierLabelmapExtent[3],
                                               int(round(boundsIjk[4])),
                                               int(round(boundsIjk[5])))
            polyToStencil.Update()

            stencilData = polyToStencil.GetOutput()
            stencilExtent = [0, -1, 0, -1, 0, -1]
            stencilData.SetExtent(stencilExtent)

            stencilToImage = vtk.vtkImageStencilToImage()
            stencilToImage.SetInputConnection(polyToStencil.GetOutputPort())
            if operationName in ("FILL_INSIDE", "ERASE_INSIDE", "SET"):
                stencilToImage.SetInsideValue(1.0)
                stencilToImage.SetOutsideValue(0.0)
            else:
                stencilToImage.SetInsideValue(0.0)
                stencilToImage.SetOutsideValue(1.0)
            stencilToImage.SetOutputScalarType(
                modifierLabelmap.GetScalarType())

            stencilPositioner = vtk.vtkImageChangeInformation()
            stencilPositioner.SetInputConnection(
                stencilToImage.GetOutputPort())
            stencilPositioner.SetOutputSpacing(modifierLabelmap.GetSpacing())
            stencilPositioner.SetOutputOrigin(modifierLabelmap.GetOrigin())

            stencilPositioner.Update()
            orientedStencilPositionerOuput = vtkSegmentationCore.vtkOrientedImageData(
            )
            orientedStencilPositionerOuput.ShallowCopy(
                stencilToImage.GetOutput())
            imageToWorld = vtk.vtkMatrix4x4()
            modifierLabelmap.GetImageToWorldMatrix(imageToWorld)
            orientedStencilPositionerOuput.SetImageToWorldMatrix(imageToWorld)

            vtkSegmentationCore.vtkOrientedImageDataResample.ModifyImage(
                modifierLabelmap, orientedStencilPositionerOuput,
                vtkSegmentationCore.vtkOrientedImageDataResample.
                OPERATION_MAXIMUM)

            modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd
            if operationName == "ERASE_INSIDE" or operationName == "ERASE_OUTSIDE":
                modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeRemove
            elif operationName == "SET":
                modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet

            self.scriptedEffect.modifySelectedSegmentByLabelmap(
                modifierLabelmap, modMode)

            import numpy
            n = self.segmentMarkupNode.GetNumberOfFiducials()
            # get fiducial positions
            fPos = numpy.zeros((n, 3))
            for i in xrange(n):
                coord = [0.0, 0.0, 0.0]
                self.segmentMarkupNode.GetNthFiducialPosition(i, coord)
                fPos[i] = coord
            segmentID = self.scriptedEffect.parameterSetNode(
            ).GetSelectedSegmentID()
            segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
            segment.SetTag("fP", fPos.tostring())
            segment.SetTag("fN", n)

        self.reset()
        self.createNewMarkupNode()
        self.fiducialPlacementToggle.setCurrentNode(self.segmentMarkupNode)
        self.observeSegmentation(True)
        qt.QApplication.restoreOverrideCursor()
  def smoothMultipleSegments(self):
    import vtkSegmentationCorePython as vtkSegmentationCore

    # Generate merged labelmap of all visible segments
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    visibleSegmentIds = vtk.vtkStringArray()
    segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(visibleSegmentIds)
    if visibleSegmentIds.GetNumberOfValues() == 0:
      logging.info("Smoothing operation skipped: there are no visible segments")
      return

    mergedImage = vtkSegmentationCore.vtkOrientedImageData()
    if not segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage,
                                                                 vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_SEGMENTS_PADDED,
                                                                 None, visibleSegmentIds):
      logging.error('Failed to apply smoothing: cannot get list of visible segments')
      return

    segmentLabelValues = [] # list of [segmentId, labelValue]
    for i in range(visibleSegmentIds.GetNumberOfValues()):
      segmentId = visibleSegmentIds.GetValue(i)
      segmentLabelValues.append([segmentId, i+1])

    # Perform smoothing in voxel space
    ici = vtk.vtkImageChangeInformation()
    ici.SetInputData(mergedImage)
    ici.SetOutputSpacing(1, 1, 1)
    ici.SetOutputOrigin(0, 0, 0)

    # Convert labelmap to combined polydata
    # vtkDiscreteFlyingEdges3D cannot be used here, as in the output of that filter,
    # each labeled region is completely disconnected from neighboring regions, and
    # for joint smoothing it is essential for the points to move together.
    convertToPolyData = vtk.vtkDiscreteMarchingCubes()
    convertToPolyData.SetInputConnection(ici.GetOutputPort())
    convertToPolyData.SetNumberOfContours(len(segmentLabelValues))

    contourIndex = 0
    for segmentId, labelValue in segmentLabelValues:
      convertToPolyData.SetValue(contourIndex, labelValue)
      contourIndex += 1

    # Low-pass filtering using Taubin's method
    smoothingFactor = self.scriptedEffect.doubleParameter("JointTaubinSmoothingFactor")
    smoothingIterations = 100 #  according to VTK documentation 10-20 iterations could be enough but we use a higher value to reduce chance of shrinking
    passBand = pow(10.0, -4.0*smoothingFactor) # gives a nice range of 1-0.0001 from a user input of 0-1
    smoother = vtk.vtkWindowedSincPolyDataFilter()
    smoother.SetInputConnection(convertToPolyData.GetOutputPort())
    smoother.SetNumberOfIterations(smoothingIterations)
    smoother.BoundarySmoothingOff()
    smoother.FeatureEdgeSmoothingOff()
    smoother.SetFeatureAngle(90.0)
    smoother.SetPassBand(passBand)
    smoother.NonManifoldSmoothingOn()
    smoother.NormalizeCoordinatesOn()

    # Extract a label
    threshold = vtk.vtkThreshold()
    threshold.SetInputConnection(smoother.GetOutputPort())

    # Convert to polydata
    geometryFilter = vtk.vtkGeometryFilter()
    geometryFilter.SetInputConnection(threshold.GetOutputPort())

    # Convert polydata to stencil
    polyDataToImageStencil = vtk.vtkPolyDataToImageStencil()
    polyDataToImageStencil.SetInputConnection(geometryFilter.GetOutputPort())
    polyDataToImageStencil.SetOutputSpacing(1,1,1)
    polyDataToImageStencil.SetOutputOrigin(0,0,0)
    polyDataToImageStencil.SetOutputWholeExtent(mergedImage.GetExtent())

    # Convert stencil to image
    stencil = vtk.vtkImageStencil()
    emptyBinaryLabelMap = vtk.vtkImageData()
    emptyBinaryLabelMap.SetExtent(mergedImage.GetExtent())
    emptyBinaryLabelMap.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
    vtkSegmentationCore.vtkOrientedImageDataResample.FillImage(emptyBinaryLabelMap, 0)
    stencil.SetInputData(emptyBinaryLabelMap)
    stencil.SetStencilConnection(polyDataToImageStencil.GetOutputPort())
    stencil.ReverseStencilOn()
    stencil.SetBackgroundValue(1) # General foreground value is 1 (background value because of reverse stencil)

    imageToWorldMatrix = vtk.vtkMatrix4x4()
    mergedImage.GetImageToWorldMatrix(imageToWorldMatrix)

    for segmentId, labelValue in segmentLabelValues:
      threshold.ThresholdBetween(labelValue, labelValue)
      stencil.Update()
      smoothedBinaryLabelMap = vtkSegmentationCore.vtkOrientedImageData()
      smoothedBinaryLabelMap.ShallowCopy(stencil.GetOutput())
      smoothedBinaryLabelMap.SetImageToWorldMatrix(imageToWorldMatrix)
      # Write results to segments directly, bypassing masking
      slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(smoothedBinaryLabelMap,
        segmentationNode, segmentId, slicer.vtkSlicerSegmentationsModuleLogic.MODE_REPLACE, smoothedBinaryLabelMap.GetExtent())
# A script to test the stencil filter with a polydata stencil.
# Image pipeline
reader = vtk.vtkPNGReader()
reader.SetDataSpacing(0.8,0.8,1.5)
reader.SetDataOrigin(0.0,0.0,0.0)
reader.SetFileName("" + str(VTK_DATA_ROOT) + "/Data/fullhead15.png")
sphere = vtk.vtkSphereSource()
sphere.SetPhiResolution(12)
sphere.SetThetaResolution(12)
sphere.SetCenter(102,102,0)
sphere.SetRadius(60)
triangle = vtk.vtkTriangleFilter()
triangle.SetInputConnection(sphere.GetOutputPort())
stripper = vtk.vtkStripper()
stripper.SetInputConnection(triangle.GetOutputPort())
dataToStencil = vtk.vtkPolyDataToImageStencil()
dataToStencil.SetInputConnection(stripper.GetOutputPort())
dataToStencil.SetOutputSpacing(0.8,0.8,1.5)
dataToStencil.SetOutputOrigin(0.0,0.0,0.0)
stencil = vtk.vtkImageStencil()
stencil.SetInputConnection(reader.GetOutputPort())
stencil.SetStencilConnection(dataToStencil.GetOutputPort())
stencil.ReverseStencilOn()
stencil.SetBackgroundValue(500)
# test again with a contour
reader2 = vtk.vtkPNGReader()
reader2.SetDataSpacing(0.8,0.8,1.5)
reader2.SetDataOrigin(0.0,0.0,0.0)
reader2.SetFileName("" + str(VTK_DATA_ROOT) + "/Data/fullhead15.png")
plane = vtk.vtkPlane()
plane.SetOrigin(0,0,0)
Example #41
0
def compute_topomesh_image(topomesh, img):

    image_start_time = time()
    print "<-- Computing topomesh image"

    polydata_img = np.ones_like(img)
        
    for c in list(topomesh.wisps(3)):
        if len(list(topomesh.borders(3,c))) > 0:
            polydata_start_time = time()
            sub_topomesh = cell_topomesh(topomesh,cells=[c]) 
            
            start_time = time()
            bounding_box = np.array([[0,polydata_img.shape[0]],[0,polydata_img.shape[1]],[0,polydata_img.shape[2]]])
            bounding_box[:,0] = np.floor(sub_topomesh.wisp_property('barycenter',0).values().min(axis=0)/np.array(img.resolution)).astype(int)-1
            bounding_box[:,0] = np.maximum(bounding_box[:,0],0)
            bounding_box[:,1] = np.ceil(sub_topomesh.wisp_property('barycenter',0).values().max(axis=0)/np.array(img.resolution)).astype(int)+1
            bounding_box[:,1] = np.minimum(bounding_box[:,1],np.array(img.shape)-1)
            
            sub_polydata_img = polydata_img[bounding_box[0,0]:bounding_box[0,1],bounding_box[1,0]:bounding_box[1,1],bounding_box[2,0]:bounding_box[2,1]]
            #world.add(sub_polydata_img,"topomesh_image",colormap='glasbey',alphamap='constant',bg_id=1,intensity_range=(0,1))

            reader = matrix_to_image_reader('sub_polydata_image',sub_polydata_img,sub_polydata_img.dtype)
            #reader = matrix_to_image_reader('polydata_image',polydata_img,polydata_img.dtype)

            end_time = time()
            print "  --> Extracting cell sub-image      [",end_time-start_time,"s]"

            start_time = time()
            topomesh_center = bounding_box[:,0]*np.array(img.resolution)
            positions = sub_topomesh.wisp_property('barycenter',0)
            
            polydata = vtk.vtkPolyData()
            vtk_points = vtk.vtkPoints()
            vtk_triangles = vtk.vtkCellArray()
            
            for t in sub_topomesh.wisps(2):
                triangle_points = []
                for v in sub_topomesh.borders(2,t,2):
                    p = vtk_points.InsertNextPoint(positions[v]-topomesh_center)
                    triangle_points.append(p)
                triangle_points = array_dict(triangle_points,list(sub_topomesh.borders(2,t,2)))
                poly = vtk_triangles.InsertNextCell(3)
                for v in sub_topomesh.borders(2,t,2):
                    vtk_triangles.InsertCellPoint(triangle_points[v])

            polydata.SetPoints(vtk_points)
            polydata.SetPolys(vtk_triangles)
            
            end_time = time()
            print "  --> Creating VTK PolyData      [",end_time-start_time,"s]"
            
            start_time = time()
            pol2stenc = vtk.vtkPolyDataToImageStencil()
            pol2stenc.SetTolerance(0)
            pol2stenc.SetOutputOrigin((0,0,0))
            #pol2stenc.SetOutputOrigin(tuple(-bounding_box[:,0]))
            pol2stenc.SetOutputSpacing(img.resolution)
            SetInput(pol2stenc,polydata)
            pol2stenc.Update()
            end_time = time()
            print "  --> Cell ",c," polydata stencil   [",end_time-start_time,"s]"
            
            start_time = time()
            imgstenc = vtk.vtkImageStencil()
            if vtk.VTK_MAJOR_VERSION <= 5:
                imgstenc.SetInput(reader.GetOutput())
                imgstenc.SetStencil(pol2stenc.GetOutput())
            else:
                imgstenc.SetInputData(reader.GetOutput())
                imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
            imgstenc.ReverseStencilOn()
            imgstenc.SetBackgroundValue(c)
            imgstenc.Update()
            end_time = time()
            print "  --> Cell ",c," image stencil   [",end_time-start_time,"s]"

            start_time = time()
            dim = tuple((bounding_box[:,1]-bounding_box[:,0])[::-1])
            array = np.ones(dim, img.dtype)
            export = vtk.vtkImageExport()
            export.SetInputConnection(imgstenc.GetOutputPort())
            export.Export(array)
            end_time = time()
            print "  --> Exporting image       [",end_time-start_time,"s]"
            
            start_time = time()
            array = np.transpose(array,(2,1,0))
            polydata_img[bounding_box[0,0]:bounding_box[0,1],bounding_box[1,0]:bounding_box[1,1],bounding_box[2,0]:bounding_box[2,1]] = array
            end_time = time()
            print "  --> Inserting cell sub-image       [",end_time-start_time,"s]"
            
            polydata_end_time = time()
            print "--> Inserting topomesh cell ",c,"   [",polydata_end_time-polydata_start_time,"s]"
        
    image_end_time = time()
    print "<-- Computing topomesh image   [",image_end_time-image_start_time,"s]"

    return polydata_img
Example #42
0
sphere.SetPhiResolution(12)
sphere.SetThetaResolution(12)
sphere.SetCenter(102, 102, 0)
sphere.SetRadius(60)
triangle = vtk.vtkTriangleFilter()
if vtk.VTK_MAJOR_VERSION <= 5:
    triangle.SetInput(sphere.GetOutput())
else:
    triangle.SetInputConnection(sphere.GetOutputPort())

stripper = vtk.vtkStripper()
if vtk.VTK_MAJOR_VERSION <= 5:
    stripper.SetInput(triangle.GetOutput())
else:
    stripper.SetInputConnection(triangle.GetOutputPort())
dataToStencil = vtk.vtkPolyDataToImageStencil()
if vtk.VTK_MAJOR_VERSION <= 5:
    dataToStencil.SetInput(stripper.GetOutput())
else:
    dataToStencil.SetInputConnection(stripper.GetOutputPort())
dataToStencil.SetOutputSpacing(0.8, 0.8, 1.5)
dataToStencil.SetOutputOrigin(0.0, 0.0, 0.0)

stencil = vtk.vtkImageStencil()
if vtk.VTK_MAJOR_VERSION <= 5:
    stencil.SetInput(reader.GetOutput())
    stencil.SetStencil(dataToStencil.GetOutput())
else:
    stencil.SetInputConnection(reader.GetOutputPort())
    stencil.SetStencilConnection(dataToStencil.GetOutputPort())
stencil.ReverseStencilOn()
Example #43
0
    def cutSurfaceWithModel(self, segmentMarkupNode, segmentModel):

        import vtkSegmentationCorePython as vtkSegmentationCore

        if not segmentMarkupNode:
            raise AttributeError("{}: segment markup node not set.".format(
                self.__class__.__name__))
        if not segmentModel:
            raise AttributeError("{}: segment model not set.".format(
                self.__class__.__name__))

        if segmentMarkupNode and segmentModel.GetPolyData().GetNumberOfPolys(
        ) > 0:
            operationName = self.scriptedEffect.parameter("Operation")

            segmentationNode = self.scriptedEffect.parameterSetNode(
            ).GetSegmentationNode()
            if not segmentationNode:
                raise AttributeError("{}: Segmentation node not set.".format(
                    self.__class__.__name__))

            modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
            if not modifierLabelmap:
                raise AttributeError(
                    "{}: ModifierLabelmap not set. This can happen for various reasons:\n"
                    "No master volume set for segmentation,\n"
                    "No existing segments for segmentation, or\n"
                    "No referenceImageGeometry is specified in the segmentation"
                    .format(self.__class__.__name__))

            WorldToModifierLabelmapIjkTransform = vtk.vtkTransform()

            WorldToModifierLabelmapIjkTransformer = vtk.vtkTransformPolyDataFilter(
            )
            WorldToModifierLabelmapIjkTransformer.SetTransform(
                WorldToModifierLabelmapIjkTransform)
            WorldToModifierLabelmapIjkTransformer.SetInputConnection(
                segmentModel.GetPolyDataConnection())

            segmentationToSegmentationIjkTransformMatrix = vtk.vtkMatrix4x4()
            modifierLabelmap.GetImageToWorldMatrix(
                segmentationToSegmentationIjkTransformMatrix)
            segmentationToSegmentationIjkTransformMatrix.Invert()
            WorldToModifierLabelmapIjkTransform.Concatenate(
                segmentationToSegmentationIjkTransformMatrix)

            worldToSegmentationTransformMatrix = vtk.vtkMatrix4x4()
            slicer.vtkMRMLTransformNode.GetMatrixTransformBetweenNodes(
                None, segmentationNode.GetParentTransformNode(),
                worldToSegmentationTransformMatrix)
            WorldToModifierLabelmapIjkTransform.Concatenate(
                worldToSegmentationTransformMatrix)
            WorldToModifierLabelmapIjkTransformer.Update()

            polyToStencil = vtk.vtkPolyDataToImageStencil()
            polyToStencil.SetOutputSpacing(1.0, 1.0, 1.0)
            polyToStencil.SetInputConnection(
                WorldToModifierLabelmapIjkTransformer.GetOutputPort())
            boundsIjk = WorldToModifierLabelmapIjkTransformer.GetOutput(
            ).GetBounds()
            modifierLabelmapExtent = self.scriptedEffect.modifierLabelmap(
            ).GetExtent()
            polyToStencil.SetOutputWholeExtent(modifierLabelmapExtent[0],
                                               modifierLabelmapExtent[1],
                                               modifierLabelmapExtent[2],
                                               modifierLabelmapExtent[3],
                                               int(round(boundsIjk[4])),
                                               int(round(boundsIjk[5])))
            polyToStencil.Update()

            stencilData = polyToStencil.GetOutput()
            stencilExtent = [0, -1, 0, -1, 0, -1]
            stencilData.SetExtent(stencilExtent)

            stencilToImage = vtk.vtkImageStencilToImage()
            stencilToImage.SetInputConnection(polyToStencil.GetOutputPort())
            if operationName in ("FILL_INSIDE", "ERASE_INSIDE", "SET"):
                stencilToImage.SetInsideValue(1.0)
                stencilToImage.SetOutsideValue(0.0)
            else:
                stencilToImage.SetInsideValue(0.0)
                stencilToImage.SetOutsideValue(1.0)
            stencilToImage.SetOutputScalarType(
                modifierLabelmap.GetScalarType())

            stencilPositioner = vtk.vtkImageChangeInformation()
            stencilPositioner.SetInputConnection(
                stencilToImage.GetOutputPort())
            stencilPositioner.SetOutputSpacing(modifierLabelmap.GetSpacing())
            stencilPositioner.SetOutputOrigin(modifierLabelmap.GetOrigin())

            stencilPositioner.Update()
            orientedStencilPositionerOutput = vtkSegmentationCore.vtkOrientedImageData(
            )
            orientedStencilPositionerOutput.ShallowCopy(
                stencilToImage.GetOutput())
            imageToWorld = vtk.vtkMatrix4x4()
            modifierLabelmap.GetImageToWorldMatrix(imageToWorld)
            orientedStencilPositionerOutput.SetImageToWorldMatrix(imageToWorld)

            vtkSegmentationCore.vtkOrientedImageDataResample.ModifyImage(
                modifierLabelmap, orientedStencilPositionerOutput,
                vtkSegmentationCore.vtkOrientedImageDataResample.
                OPERATION_MAXIMUM)

            modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd
            if operationName == "ERASE_INSIDE" or operationName == "ERASE_OUTSIDE":
                modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeRemove
            elif operationName == "SET":
                modMode = slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet

            self.scriptedEffect.modifySelectedSegmentByLabelmap(
                modifierLabelmap, modMode)

            # get fiducial positions as space-separated list
            import numpy
            n = segmentMarkupNode.GetNumberOfFiducials()
            fPos = []
            for i in range(n):
                coord = [0.0, 0.0, 0.0]
                segmentMarkupNode.GetNthFiducialPosition(i, coord)
                fPos.extend(coord)
            fPosString = ' '.join(map(str, fPos))

            segmentID = self.scriptedEffect.parameterSetNode(
            ).GetSelectedSegmentID()
            segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
            segment.SetTag("SurfaceCutEffectMarkupPositions", fPosString)
Example #44
0
  def clipVolumeWithModel(self, inputVolume, clippingModel, clipOutsideSurface, fillValue, outputVolume):
    """
    Fill voxels of the input volume inside/outside the clipping model with the provided fill value
    """
    
    # Determine the transform between the box and the image IJK coordinate systems
    
    rasToModel = vtk.vtkMatrix4x4()    
    if clippingModel.GetTransformNodeID() != None:
      modelTransformNode = slicer.mrmlScene.GetNodeByID(clippingModel.GetTransformNodeID())
      boxToRas = vtk.vtkMatrix4x4()
      modelTransformNode.GetMatrixTransformToWorld(boxToRas)
      rasToModel.DeepCopy(boxToRas)
      rasToModel.Invert()
      
    ijkToRas = vtk.vtkMatrix4x4()
    inputVolume.GetIJKToRASMatrix( ijkToRas )

    ijkToModel = vtk.vtkMatrix4x4()
    vtk.vtkMatrix4x4.Multiply4x4(rasToModel,ijkToRas,ijkToModel)
    modelToIjkTransform = vtk.vtkTransform()
    modelToIjkTransform.SetMatrix(ijkToModel)
    modelToIjkTransform.Inverse()
    
    transformModelToIjk=vtk.vtkTransformPolyDataFilter()
    transformModelToIjk.SetTransform(modelToIjkTransform)
    transformModelToIjk.SetInputConnection(clippingModel.GetPolyDataConnection())

    # Use the stencil to fill the volume
    
    # Convert model to stencil
    polyToStencil = vtk.vtkPolyDataToImageStencil()
    polyToStencil.SetInputConnection(transformModelToIjk.GetOutputPort())
    polyToStencil.SetOutputSpacing(inputVolume.GetImageData().GetSpacing())
    polyToStencil.SetOutputOrigin(inputVolume.GetImageData().GetOrigin())
    polyToStencil.SetOutputWholeExtent(inputVolume.GetImageData().GetExtent())
    
    # Apply the stencil to the volume
    stencilToImage=vtk.vtkImageStencil()
    stencilToImage.SetInputConnection(inputVolume.GetImageDataConnection())
    stencilToImage.SetStencilConnection(polyToStencil.GetOutputPort())
    if clipOutsideSurface:
      stencilToImage.ReverseStencilOff()
    else:
      stencilToImage.ReverseStencilOn()
    stencilToImage.SetBackgroundValue(fillValue)
    stencilToImage.Update()

    # Update the volume with the stencil operation result
    outputImageData = vtk.vtkImageData()
    outputImageData.DeepCopy(stencilToImage.GetOutput())
    
    outputVolume.SetAndObserveImageData(outputImageData);
    outputVolume.SetIJKToRASMatrix(ijkToRas)

    # Add a default display node to output volume node if it does not exist yet
    if not outputVolume.GetDisplayNode:
      displayNode=slicer.vtkMRMLScalarVolumeDisplayNode()
      displayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeGrey")
      slicer.mrmlScene.AddNode(displayNode)
      outputVolume.SetAndObserveDisplayNodeID(displayNode.GetID())

    return True
Example #45
0
    def _poly2img(self, ind):
        """
        Helper function called by **deformableRegistration()** that generates
        images from polygonal surfaces in reference/deformed pairs. The voxel
        dimension of these images is determined by the value for **Precision**
        in **deformableSettings**.

        Parameters
        ----------
        ind : int
            The list index for the current object pair being analyzed.

        Returns
        -------
            (Reference Image, Deformed Image, Tranformed Reference Surface)
        """
        dim = int(np.ceil(old_div(1.0,
                                  self.deformableSettings['Precision']))) + 10
        rpoly = vtk.vtkPolyData()
        rpoly.DeepCopy(self.rsurfs[ind])
        dpoly = self.dsurfs[ind]
        if self.rigidInitial:
            rot = vtk.vtkTransformPolyDataFilter()
            rot.SetInputData(rpoly)
            rot.SetTransform(self.rigidTransforms[ind])
            rot.Update()
            rpoly = rot.GetOutput()

        rbounds = np.zeros(6, np.float32)
        dbounds = np.copy(rbounds)

        rpoly.GetBounds(rbounds)
        dpoly.GetBounds(dbounds)

        spacing = np.zeros(3, np.float32)
        for i in range(3):
            rspan = rbounds[2 * i + 1] - rbounds[2 * i]
            dspan = dbounds[2 * i + 1] - dbounds[2 * i]
            spacing[i] = (np.max([rspan, dspan]) *
                          self.deformableSettings['Precision'])

        imgs = []
        half = old_div(float(dim), 2.0)
        for i in range(2):
            arr = np.ones((dim, dim, dim), np.uint8)
            arr2img = vti.vtkImageImportFromArray()
            arr2img.SetDataSpacing(spacing)
            arr2img.SetDataExtent((0, dim - 1, 0, dim - 1, 0, dim - 1))
            arr2img.SetArray(arr)
            arr2img.Update()
            if i == 0:
                rimg = arr2img.GetOutput()
                rimg.SetOrigin((np.mean(rbounds[0:2]) - half * spacing[0] +
                                old_div(spacing[0], 2), np.mean(rbounds[2:4]) -
                                half * spacing[1] + old_div(spacing[1], 2),
                                np.mean(rbounds[4:]) - half * spacing[2] +
                                old_div(spacing[2], 2)))
            else:
                dimg = arr2img.GetOutput()
                dimg.SetOrigin((np.mean(dbounds[0:2]) - half * spacing[0] +
                                old_div(spacing[0], 2), np.mean(dbounds[2:4]) -
                                half * spacing[1] + old_div(spacing[1], 2),
                                np.mean(dbounds[4:]) - half * spacing[2] +
                                old_div(spacing[2], 2)))
        imgs = []
        for (pd, img) in [(rpoly, rimg), (dpoly, dimg)]:
            pol2stenc = vtk.vtkPolyDataToImageStencil()
            pol2stenc.SetInputData(pd)
            pol2stenc.SetOutputOrigin(img.GetOrigin())
            pol2stenc.SetOutputSpacing(img.GetSpacing())
            pol2stenc.SetOutputWholeExtent(img.GetExtent())
            pol2stenc.SetTolerance(0.0001)
            pol2stenc.Update()

            imgstenc = vtk.vtkImageStencil()
            imgstenc.SetInputData(img)
            imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
            imgstenc.ReverseStencilOff()
            imgstenc.SetBackgroundValue(0)
            imgstenc.Update()

            arr = vtk_to_numpy(imgstenc.GetOutput().GetPointData().GetArray(0))
            arr = arr.reshape(dim, dim, dim)
            itk_img = sitk.GetImageFromArray(arr)
            itk_img.SetSpacing(img.GetSpacing())
            itk_img.SetOrigin(img.GetOrigin())
            imgs.append(itk_img)
        return (imgs[0], imgs[1], rpoly)
Example #46
0
 def opImplement(self):
     import vtkMeasure,math;
     measure = vtkMeasure.measure_factory(self.data);
     real_width,real_depth,real_height = measure.getPointSize();
     scaler = 1.1;
     width,depth,height =  [ real_width * scaler,real_depth* scaler , real_height* scaler ];
     xMin,xMax = measure.xSize
     yMin,yMax = measure.ySize
     zMin,zMax = measure.zSize
     #Basic image
     blankImage = vtk.vtkImageData();
     
     #The size of voxel
     spacing = [width/VOLUME_SETP,height/VOLUME_SETP,depth/VOLUME_SETP];
     #spacing = [0.1,0.1,0.1];
     self.resoulation = spacing;
     #How many voxel on each axis
     extent = [xMin,xMax,yMin,yMax,zMin,zMax];
     
     extent[0] = 0
     extent[1] = int(math.ceil(width/spacing[0] -1 ) )
     extent[2] = 0
     extent[3] = int(math.ceil(height/spacing[1] -1 )  )
     extent[4] = 0
     extent[5] = int(math.ceil(depth/spacing[2] -1))
     
     
     #Where start from first voxel
     origin = list(self.data.GetCenter());
     
     origin[0] = xMin+spacing[0]/2;
     origin[1] = yMin+spacing[1]/2;
     origin[2] = zMin+spacing[2]/2;
     
     
     blankImage.SetSpacing(*spacing)
     blankImage.SetOrigin(*origin);
     blankImage.SetExtent(*extent);
 
     blankImage.AllocateScalars(vtk.VTK_UNSIGNED_CHAR,1);
     xd,yd,zd = blankImage.GetDimensions();
     #Fill in inside val
     for x in range(0,xd):
         for y in range(0,yd):
             for z in range(0,zd):
                 blankImage.SetScalarComponentFromFloat(x,y,z,0,IMAGEOUT);
     
     #PolyData
     poly2Stenc = vtk.vtkPolyDataToImageStencil();
     poly2Stenc.SetInputData(self.data);
     poly2Stenc.SetInformationInput(blankImage)
     poly2Stenc.SetTolerance(80.0)
     poly2Stenc.SetOutputSpacing(spacing)
     poly2Stenc.SetOutputOrigin(origin)
     poly2Stenc.Update();
     
     #Mashup polydata and basic iamge
     imageStenc = vtk.vtkImageStencil();
     imageStenc.SetInputData(blankImage);
     imageStenc.SetStencilConnection(poly2Stenc.GetOutputPort());
     imageStenc.ReverseStencilOn();
     #Outside value
     imageStenc.SetBackgroundValue(IMAGEIN);
     imageStenc.Update();
     
     combined_image = imageStenc.GetOutput()
     self.preCommand.operation.reset();
     return combined_image;
Example #47
0
    def smoothMultipleSegments(self, maskImage=None, maskExtent=None):
        import vtkSegmentationCorePython as vtkSegmentationCore

        self.showStatusMessage(f'Joint smoothing ...')
        # Generate merged labelmap of all visible segments
        segmentationNode = self.scriptedEffect.parameterSetNode(
        ).GetSegmentationNode()
        visibleSegmentIds = vtk.vtkStringArray()
        segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(
            visibleSegmentIds)
        if visibleSegmentIds.GetNumberOfValues() == 0:
            logging.info(
                "Smoothing operation skipped: there are no visible segments")
            return

        mergedImage = slicer.vtkOrientedImageData()
        if not segmentationNode.GenerateMergedLabelmapForAllSegments(
                mergedImage, vtkSegmentationCore.vtkSegmentation.
                EXTENT_UNION_OF_SEGMENTS_PADDED, None, visibleSegmentIds):
            logging.error(
                'Failed to apply smoothing: cannot get list of visible segments'
            )
            return

        segmentLabelValues = []  # list of [segmentId, labelValue]
        for i in range(visibleSegmentIds.GetNumberOfValues()):
            segmentId = visibleSegmentIds.GetValue(i)
            segmentLabelValues.append([segmentId, i + 1])

        # Perform smoothing in voxel space
        ici = vtk.vtkImageChangeInformation()
        ici.SetInputData(mergedImage)
        ici.SetOutputSpacing(1, 1, 1)
        ici.SetOutputOrigin(0, 0, 0)

        # Convert labelmap to combined polydata
        # vtkDiscreteFlyingEdges3D cannot be used here, as in the output of that filter,
        # each labeled region is completely disconnected from neighboring regions, and
        # for joint smoothing it is essential for the points to move together.
        convertToPolyData = vtk.vtkDiscreteMarchingCubes()
        convertToPolyData.SetInputConnection(ici.GetOutputPort())
        convertToPolyData.SetNumberOfContours(len(segmentLabelValues))

        contourIndex = 0
        for segmentId, labelValue in segmentLabelValues:
            convertToPolyData.SetValue(contourIndex, labelValue)
            contourIndex += 1

        # Low-pass filtering using Taubin's method
        smoothingFactor = self.scriptedEffect.doubleParameter(
            "JointTaubinSmoothingFactor")
        smoothingIterations = 100  # according to VTK documentation 10-20 iterations could be enough but we use a higher value to reduce chance of shrinking
        passBand = pow(
            10.0, -4.0 * smoothingFactor
        )  # gives a nice range of 1-0.0001 from a user input of 0-1
        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputConnection(convertToPolyData.GetOutputPort())
        smoother.SetNumberOfIterations(smoothingIterations)
        smoother.BoundarySmoothingOff()
        smoother.FeatureEdgeSmoothingOff()
        smoother.SetFeatureAngle(90.0)
        smoother.SetPassBand(passBand)
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()

        # Extract a label
        threshold = vtk.vtkThreshold()
        threshold.SetInputConnection(smoother.GetOutputPort())

        # Convert to polydata
        geometryFilter = vtk.vtkGeometryFilter()
        geometryFilter.SetInputConnection(threshold.GetOutputPort())

        # Convert polydata to stencil
        polyDataToImageStencil = vtk.vtkPolyDataToImageStencil()
        polyDataToImageStencil.SetInputConnection(
            geometryFilter.GetOutputPort())
        polyDataToImageStencil.SetOutputSpacing(1, 1, 1)
        polyDataToImageStencil.SetOutputOrigin(0, 0, 0)
        polyDataToImageStencil.SetOutputWholeExtent(mergedImage.GetExtent())

        # Convert stencil to image
        stencil = vtk.vtkImageStencil()
        emptyBinaryLabelMap = vtk.vtkImageData()
        emptyBinaryLabelMap.SetExtent(mergedImage.GetExtent())
        emptyBinaryLabelMap.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
        vtkSegmentationCore.vtkOrientedImageDataResample.FillImage(
            emptyBinaryLabelMap, 0)
        stencil.SetInputData(emptyBinaryLabelMap)
        stencil.SetStencilConnection(polyDataToImageStencil.GetOutputPort())
        stencil.ReverseStencilOn()
        stencil.SetBackgroundValue(
            1
        )  # General foreground value is 1 (background value because of reverse stencil)

        imageToWorldMatrix = vtk.vtkMatrix4x4()
        mergedImage.GetImageToWorldMatrix(imageToWorldMatrix)

        # TODO: Temporarily setting the overwrite mode to OverwriteVisibleSegments is an approach that should be change once additional
        # layer control options have been implemented. Users may wish to keep segments on separate layers, and not allow them to be separated/merged automatically.
        # This effect could leverage those options once they have been implemented.
        oldOverwriteMode = self.scriptedEffect.parameterSetNode(
        ).GetOverwriteMode()
        self.scriptedEffect.parameterSetNode().SetOverwriteMode(
            slicer.vtkMRMLSegmentEditorNode.OverwriteVisibleSegments)
        for segmentId, labelValue in segmentLabelValues:
            threshold.ThresholdBetween(labelValue, labelValue)
            stencil.Update()
            smoothedBinaryLabelMap = slicer.vtkOrientedImageData()
            smoothedBinaryLabelMap.ShallowCopy(stencil.GetOutput())
            smoothedBinaryLabelMap.SetImageToWorldMatrix(imageToWorldMatrix)
            self.scriptedEffect.modifySegmentByLabelmap(
                segmentationNode, segmentId, smoothedBinaryLabelMap,
                slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet,
                False)
        self.scriptedEffect.parameterSetNode().SetOverwriteMode(
            oldOverwriteMode)
Example #48
0
def SimpleITKImageFromVTKTube(tube, SITKReferenceImage, debug=False):
    """
    Input: VTK tube, referenceImage (used for spacing, etc.)
    Output: SimpleITK image
    Note: Uses binary output (background 0, foreground 1)
    """
    size = list(SITKReferenceImage.GetSize())
    origin = list(SITKReferenceImage.GetOrigin())
    spacing = list(SITKReferenceImage.GetSpacing())
    ncomp = SITKReferenceImage.GetNumberOfComponentsPerPixel()

    # convert the SimpleITK image to a numpy array
    arr = sitk.GetArrayFromImage(SITKReferenceImage).transpose(2, 1,
                                                               0).flatten()

    # send the numpy array to VTK with a vtkImageImport object
    dataImporter = vtk.vtkImageImport()

    dataImporter.CopyImportVoidPointer(arr, len(arr))
    dataImporter.SetDataScalarTypeToUnsignedChar()
    dataImporter.SetNumberOfScalarComponents(ncomp)

    # Set the new VTK image's parameters
    dataImporter.SetDataExtent(0, size[0] - 1, 0, size[1] - 1, 0, size[2] - 1)
    dataImporter.SetWholeExtent(0, size[0] - 1, 0, size[1] - 1, 0, size[2] - 1)
    dataImporter.SetDataOrigin(origin)
    dataImporter.SetDataSpacing(spacing)

    dataImporter.Update()

    VTKReferenceImage = dataImporter.GetOutput()

    # fill the image with foreground voxels:
    inval = 1
    outval = 0
    VTKReferenceImage.GetPointData().GetScalars().Fill(inval)

    if debug:
        print("Using polydaya to generate stencil.")
    pol2stenc = vtk.vtkPolyDataToImageStencil()
    pol2stenc.SetTolerance(0.5)  # points within 0.5 voxels are included
    pol2stenc.SetInputConnection(tube.GetOutputPort())
    pol2stenc.SetOutputOrigin(VTKReferenceImage.GetOrigin())
    pol2stenc.SetOutputSpacing(VTKReferenceImage.GetSpacing())
    pol2stenc.SetOutputWholeExtent(VTKReferenceImage.GetExtent())
    pol2stenc.Update()

    if debug:
        print("using stencil to generate image.")
    imgstenc = vtk.vtkImageStencil()
    imgstenc.SetInputData(VTKReferenceImage)
    imgstenc.SetStencilConnection(pol2stenc.GetOutputPort())
    imgstenc.ReverseStencilOff()
    imgstenc.SetBackgroundValue(outval)
    imgstenc.Update()

    if debug:
        print("Generating SimpleITK image.")
    finalImage = imgstenc.GetOutput()
    finalArray = finalImage.GetPointData().GetScalars()
    finalArray = vtk_to_numpy(finalArray).reshape(
        SITKReferenceImage.GetSize()[::-1])
    if debug:
        print(f"Volume = {finalArray.sum()*sum(spacing):.3f} mm^3")
    finalImageSITK = sitk.GetImageFromArray(finalArray)
    finalImageSITK.CopyInformation(SITKReferenceImage)

    return finalImageSITK