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()
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
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.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
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 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
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 """ VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( VOI_mesh.GetBounds() ) VOIStencil.SetInformationInput(im) VOIStencil.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() imgstenc.SetInput(im) imgstenc.SetStencil(VOIStencil.GetOutput()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(5000) 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
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
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]))
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 _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()
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 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)
def extract_lesionSI_mha(self, T2image, lesion3D, image_pos_pat, image_ori_pat, loadDisplay): """ extract_lesionSI: Use lesion segmentation to extract lesion SI INPUTS: ======= images: (vtkImageData) list of Input image to Transform lesion3D: (vtkPolyData) segmentation OUTPUTS: ======= lesionSI (float) Signal intensity from lesion lesion_scalar_range (float[3]) SI range inside lesion """ ## Transform T2 img loadDisplay = Display() # Proceed to build reference frame for display objects based on DICOM coords t_T2image = loadDisplay.mhaTransform(T2image, image_pos_pat, image_ori_pat) # Update info t_T2image.UpdateInformation() # create a simple box VOI mask shape using previously found boundsPlane_preselected VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( lesion3D.GetBounds() ) VOIStencil.SetInformationInput(t_T2image) VOIStencil.Update() self.boxWidget.PlaceWidget( lesion3D.GetBounds() ) self.boxWidget.On() # cut the corresponding VOI region and set the background: extractVOIlesion_imgstenc = vtk.vtkImageStencil() extractVOIlesion_imgstenc.SetInput(t_T2image) extractVOIlesion_imgstenc.SetStencil(VOIStencil.GetOutput()) extractVOIlesion_imgstenc.ReverseStencilOff() extractVOIlesion_imgstenc.SetBackgroundValue(5000) extractVOIlesion_imgstenc.Update() # take out average image finallesionSIIm = vtk.vtkImageData() finallesionSIIm = extractVOIlesion_imgstenc.GetOutput() ## extract scalars dims = finallesionSIIm.GetDimensions() scalars = finallesionSIIm.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) lesionSI = np_scalars[np_scalars<5000] print "\nLesion_scalar Range:" lesion_scalar_range = [lesionSI.min(), lesionSI.max()] print lesion_scalar_range[0], lesion_scalar_range[1] return lesionSI, lesion_scalar_range
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
def maskVolumeWithSegment(self, segmentationNode, segmentID, operationMode, fillValues, inputVolumeNode, outputVolumeNode): """ Fill voxels of the input volume inside/outside the masking model with the provided fill value """ segmentIDs = vtk.vtkStringArray() segmentIDs.InsertNextValue(segmentID) maskVolumeNode = slicer.modules.volumes.logic().CreateAndAddLabelVolume(inputVolumeNode, "TemporaryVolumeMask") if not maskVolumeNode: logging.error("maskVolumeWithSegment failed: invalid maskVolumeNode") return False if not slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(segmentationNode, segmentIDs, maskVolumeNode, inputVolumeNode): logging.error("maskVolumeWithSegment failed: ExportSegmentsToLabelmapNode error") slicer.mrmlScene.RemoveNode(maskVolumeNode.GetDisplayNode().GetColorNode()) slicer.mrmlScene.RemoveNode(maskVolumeNode.GetDisplayNode()) slicer.mrmlScene.RemoveNode(maskVolumeNode) return False maskToStencil = vtk.vtkImageToImageStencil() maskToStencil.ThresholdByLower(0) maskToStencil.SetInputData(maskVolumeNode.GetImageData()) stencil = vtk.vtkImageStencil() if operationMode == "FILL_INSIDE_AND_OUTSIDE": # Set input to constant value thresh = vtk.vtkImageThreshold() thresh.SetInputData(inputVolumeNode.GetImageData()) thresh.ThresholdByLower(0) thresh.SetInValue(fillValues[1]) thresh.SetOutValue(fillValues[1]) thresh.SetOutputScalarType(inputVolumeNode.GetImageData().GetScalarType()) thresh.Update() stencil.SetInputData(thresh.GetOutput()) else: stencil.SetInputData(inputVolumeNode.GetImageData()) stencil.SetStencilConnection(maskToStencil.GetOutputPort()) stencil.SetReverseStencil(operationMode == "FILL_OUTSIDE") stencil.SetBackgroundValue(fillValues[0]) stencil.Update() outputVolumeNode.SetAndObserveImageData(stencil.GetOutput()) # Set the same geometry and parent transform as the input volume ijkToRas = vtk.vtkMatrix4x4() inputVolumeNode.GetIJKToRASMatrix(ijkToRas) outputVolumeNode.SetIJKToRASMatrix(ijkToRas) inputVolumeNode.SetAndObserveTransformNodeID(inputVolumeNode.GetTransformNodeID()) slicer.mrmlScene.RemoveNode(maskVolumeNode.GetDisplayNode().GetColorNode()) slicer.mrmlScene.RemoveNode(maskVolumeNode.GetDisplayNode()) slicer.mrmlScene.RemoveNode(maskVolumeNode) return True
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())
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkImageStencil(), 'Processing.', ('vtkImageData', 'vtkImageData', 'vtkImageStencilData'), ('vtkImageData', ), replaceDoc=True, inputFunctions=None, outputFunctions=None)
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
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
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()
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()
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
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
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()
reader.SetDataOrigin(0.0,0.0,0.0) reader.SetFileName("" + str(VTK_DATA_ROOT) + "/Data/fullhead15.png") reader.Update() sphere = vtk.vtkSphere() sphere.SetCenter(128,128,0) sphere.SetRadius(80) functionToStencil = vtk.vtkImplicitFunctionToImageStencil() functionToStencil.SetInput(sphere) functionToStencil.SetInformationInput(reader.GetOutput()) functionToStencil.Update() # test making a copying of the stencil (for coverage) stencilOriginal = functionToStencil.GetOutput() stencilCopy = stencilOriginal.NewInstance() stencilCopy.DeepCopy(functionToStencil.GetOutput()) shiftScale = vtk.vtkImageShiftScale() shiftScale.SetInputConnection(reader.GetOutputPort()) shiftScale.SetScale(0.2) shiftScale.Update() stencil = vtk.vtkImageStencil() stencil.SetInputConnection(reader.GetOutputPort()) stencil.SetBackgroundInputData(shiftScale.GetOutput()) stencil.SetStencilData(stencilCopy) stencilCopy.UnRegister(stencil) # not needed in python viewer = vtk.vtkImageViewer() viewer.SetInputConnection(stencil.GetOutputPort()) viewer.SetZSlice(0) viewer.SetColorWindow(2000) viewer.SetColorLevel(1000) viewer.Render() # --- end of script --
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()
def vortvelvolumei(args): #inputfile, outputfile, sx, ex, sy, ey, sz, ez, dataset): p = args[0] cubenum = args[1] print("Cube", cubenum) #Check for additonal parameters if (p["param1"] != ''): comptype = p["param1"] else: comptype = "q" #Default to q criterion if (p["param2"] != ''): thresh = float(p["param2"]) else: thresh = 783.3 #Default for q threshold on isotropic data inputfile = p["inputfile"] +str(cubenum) + ".npy" outputfile = p["outputfile"] + str(cubenum) + ".vti" #always VTK Image Data for this. sx = p["sx"] sy = p["sy"] sz = p["sz"] ex = p["ex"] ey = p["ey"] ez = p["ez"] print ("Loading file, %s" % inputfile) #Determine if file is h5 or numpy rs = timeit.default_timer() vel = np.load(inputfile) print ("File Loaded") re = timeit.default_timer() #convert numpy array to vtk cs = timeit.default_timer() #convert numpy array to vtk vtkdata = numpy_support.numpy_to_vtk(vel.flat, deep=True, array_type=vtk.VTK_FLOAT) vtkdata.SetNumberOfComponents(3) vtkdata.SetName("Velocity") image = vtk.vtkImageData() image.GetPointData().SetVectors(vtkdata) image.SetExtent(sx,ex,sy,ey,sz,ez) #NOTE: Hardcoding Spacing image.SetSpacing(.006135923, .006135923, .006135923) ce = timeit.default_timer() vs = timeit.default_timer() print ("Beginning computation: " + comptype) if (comptype == "v"): vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) vorticity.Update() elif (comptype == "q"): vorticity = vtk.vtkGradientFilter() vorticity.SetInputData(image) vorticity.SetInputScalars(image.FIELD_ASSOCIATION_POINTS,"Velocity") vorticity.ComputeQCriterionOn() vorticity.SetComputeGradient(0) vorticity.Update() ve = timeit.default_timer() print("Initial calculation done") ms = timeit.default_timer() if (comptype == "v"): mag = vtk.vtkImageMagnitude() cp = vtk.vtkCellDataToPointData() cp.SetInputData(vorticity.GetOutput()) cp.Update() image.GetPointData().SetScalars(cp.GetOutput().GetPointData().GetVectors()) mag.SetInputData(image) mag.Update() m = mag.GetOutput() m.GetPointData().RemoveArray("Velocity") else: image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetVectors("Q-criterion")) me = timeit.default_timer() print("Generating screenshot") c = vtk.vtkContourFilter() c.SetValue(0,thresh) c.SetInputData(image) c.Update() contour = c.GetOutput() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(contour) mapper.ScalarVisibilityOn() mapper.SetScalarRange(-1,1) mapper.SetScalarModeToUsePointFieldData() mapper.ColorByArrayComponent("Velocity", 0) actor = vtk.vtkActor() actor.SetMapper(mapper) ren = vtk.vtkRenderer() ren.AddActor(actor) ren.SetBackground(1,1,1) camera = vtk.vtkCamera() ren.SetActiveCamera(camera) ren.ResetCamera() camera.Zoom(1.5) #This reduces the whitespace around the image renWin = vtk.vtkRenderWindow() renWin.SetSize(1024,1024) renWin.AddRenderer(ren) renWin.SetOffScreenRendering(1) windowToImageFilter = vtk.vtkWindowToImageFilter() windowToImageFilter.SetInput(renWin) windowToImageFilter.Update() w = vtk.vtkPNGWriter() pngfilename = p["outputfile"] + str(cubenum) + ".png" w.SetFileName(pngfilename) w.SetInputConnection(windowToImageFilter.GetOutputPort()) w.Write() #Shift camera angle and take snapshots around the cube. for aznum in range(4): camera.Azimuth(90) windowToImageFilter = vtk.vtkWindowToImageFilter() windowToImageFilter.SetInput(renWin) windowToImageFilter.Update() pngfilename = p["outputfile"] + str(cubenum) + "-r" + str(aznum)+ ".png" w.SetFileName(pngfilename) w.SetInputConnection(windowToImageFilter.GetOutputPort()) w.Write() camera.Elevation(90) #Rotate camera to top windowToImageFilter = vtk.vtkWindowToImageFilter() windowToImageFilter.SetInput(renWin) windowToImageFilter.Update() pngfilename = p["outputfile"] + str(cubenum) + "-t1.png" w.SetFileName(pngfilename) w.SetInputConnection(windowToImageFilter.GetOutputPort()) w.Write() camera.Elevation(180) #Rotate camera to bottom windowToImageFilter = vtk.vtkWindowToImageFilter() windowToImageFilter.SetInput(renWin) windowToImageFilter.Update() pngfilename = p["outputfile"] + str(cubenum) + "-b1.png" w.SetFileName(pngfilename) w.SetInputConnection(windowToImageFilter.GetOutputPort()) w.Write() print ("Thresholding.") ts = timeit.default_timer() t = vtk.vtkImageThreshold() #Dense represenation (0's included, structured grid) #t = vtk.vtkThreshold() #sparse representation if (comptype == "q"): t.SetInputData(image) t.ThresholdByUpper(thresh) #.25*67.17^2 = 1127 #t.SetInputArrayToProcess(0,0,0, vorticity.GetOutput().FIELD_ASSOCIATION_POINTS, "Q-criterion") print("q criterion") else: t.SetInputData(m) t.SetInputArrayToProcess(0,0,0, mag.GetOutput().FIELD_ASSOCIATION_POINTS, "Magnitude") t.ThresholdByUpper(thresh) #44.79) #Set values in range to 1 and values out of range to 0 t.SetInValue(1) t.SetOutValue(0) #t.ReplaceInOn() #t.ReplaceOutOn() print("Update thresh") t.Update() #wt = vtk.vtkXMLImageDataWriter() #wt.SetInputData(t.GetOutput()) #wt.SetFileName("thresh.vti") #wt.Write() d = vtk.vtkImageDilateErode3D() d.SetInputData(t.GetOutput()) d.SetKernelSize(4,4,4) d.SetDilateValue(1) d.SetErodeValue(0) print ("Update dilate") d.Update() iis = vtk.vtkImageToImageStencil() iis.SetInputData(d.GetOutput()) iis.ThresholdByUpper(1) stencil = vtk.vtkImageStencil() stencil.SetInputConnection(2, iis.GetOutputPort()) stencil.SetBackgroundValue(0) #image.GetPointData().RemoveArray("Vorticity") #Set scalars to velocity so it can be cut by the stencil image.GetPointData().SetScalars(image.GetPointData().GetVectors()) #if (comptype == "q"): #Use this to get just q-criterion data instead of velocity data. Do we need both? # image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetScalars("Q-criterion")) stencil.SetInputData(image) print ("Update stencil") stencil.Update() te = timeit.default_timer() print("Setting up write") ws = timeit.default_timer() #Make velocity a vector again velarray = stencil.GetOutput().GetPointData().GetScalars() image.GetPointData().RemoveArray("Velocity") image.GetPointData().SetVectors(velarray) w = vtk.vtkXMLImageDataWriter() w.SetCompressorTypeToZLib() #w.SetCompressorTypeToNone() Need to figure out why this fails. w.SetEncodeAppendedData(0) #turn of base 64 encoding for fast write w.SetFileName(outputfile) w.SetInputData(image) if (0): w.SetCompressorTypeToZfp() w.GetCompressor().SetNx(ex-sx+1) w.GetCompressor().SetNy(ey-sy+1) w.GetCompressor().SetNz(ez-sz+1) w.GetCompressor().SetTolerance(1e-2) w.GetCompressor().SetNumComponents(3) #result = w.Write() result = 1 #don't write for benchmarking we = timeit.default_timer() print("Results:") print("Read time: %s" % str(re-rs)) print ("Convert to vtk: %s" % str(ce-cs)) if (comptype == "q"): print ("Q Computation: %s" % str(ve-vs)) print ("Q Magnitude: %s" % str(me-ms)) else: print ("Vorticity Computation: %s" % str(ve-vs)) print ("Vorticity Magnitude: %s" % str(me-ms)) print ("Threshold: %s" % str(te-ts)) print ("Write %s" % str(we-ws)) print ("Total time: %s" % str(we-rs)) if (result): p["message"] = "Success" p["computetime"] = str(we-rs) return p #return the packet
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()
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)
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 if vtk.VTK_MAJOR_VERSION >= 9: convertToPolyData = vtk.vtkDiscreteFlyingEdges3D() convertToPolyData.ComputeGradientsOff() convertToPolyData.ComputeNormalsOff() convertToPolyData.ComputeScalarsOff() else: 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())
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 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)
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
extruder.SetScaleFactor(1.) extruder.SetExtrusionTypeToNormalExtrusion() extruder.SetVector(0, 0, 1) extruder.Update() # polygonal data -. image stencil: pol2stenc = vtk.vtkPolyDataToImageStencil() pol2stenc.SetTolerance(0) # important if extruder.SetVector(0, 0, 1) !!! pol2stenc.SetInputConnection(extruder.GetOutputPort()) pol2stenc.SetOutputOrigin(origin) pol2stenc.SetOutputSpacing(spacing) pol2stenc.SetOutputWholeExtent(whiteImage.GetExtent()) pol2stenc.Update() # cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() if vtk.VTK_MAJOR_VERSION <= 5: imgstenc.SetInput(whiteImage) imgstenc.SetStencil(pol2stenc.GetOutput()) else: imgstenc.SetInputData(whiteImage) imgstenc.SetStencilConnection(pol2stenc.GetOutputPort()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(outval) imgstenc.Update() imageWriter = vtk.vtkMetaImageWriter() imageWriter.SetFileName("labelImage.mhd") imageWriter.SetInputConnection(imgstenc.GetOutputPort()) imageWriter.Write()
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
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)
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 __init__(self, parent=None): ScriptedLoadableModuleLogic.__init__(self, parent) self.resliceLogic = slicer.modulelogic.vtkSlicerVolumeResliceDriverLogic( ) # Find or create the 5DOFCalculatedTo6DOF transform self.FiveCalculatedToSixTransform = slicer.util.getNode( "FiveCalculatedToSixTransform") if self.FiveCalculatedToSixTransform == None: # Create the node self.FiveCalculatedToSixTransform = slicer.vtkMRMLLinearTransformNode( ) self.FiveCalculatedToSixTransform.SetName( "FiveCalculatedToSixTransform") self.FiveCalculatedToSixTransform.SetHideFromEditors(True) slicer.mrmlScene.AddNode(self.FiveCalculatedToSixTransform) self.base5DOFTo6DOFZOffset = 0.0 self.imageObserverTag = None self.sixDOFObserverTag = None self.iceVolumeNode = None self.maskedICEVolumeNode = None self.maskVolumeNode = None self.sixDOFTransformNode = None self.fiveDOFTransformNode = None self.sixDOFModelTo6DOFTransformNode = None self.fiveDOFModelTo5DOFCalculatedTransformNode = None self.jawModelNode = None self.noseModelNode = None self.guidanceOn = False self.imageToStencil = vtk.vtkImageToImageStencil() self.imageToStencil.ThresholdByUpper(254) self.imageStencil = vtk.vtkImageStencil() self.imageStencil.SetStencilConnection( self.imageToStencil.GetOutputPort()) self.imageStencil.SetBackgroundValue(0) self.teeConnectorNode = slicer.util.getNode(self.moduleName + 'TEEServerConnector') if self.teeConnectorNode == None: self.teeConnectorNode = slicer.vtkMRMLIGTLConnectorNode() slicer.mrmlScene.AddNode(self.teeConnectorNode) self.teeConnectorNode.SetName(self.moduleName + 'TEEServerConnector') self.teeConnectorNode.SetTypeClient("localhost", 18945) self.teeConnectorNode.Start() self.iceConnectorNode = slicer.util.getNode(self.moduleName + 'ICEServerConnector') if self.iceConnectorNode == None: self.iceConnectorNode = slicer.vtkMRMLIGTLConnectorNode() slicer.mrmlScene.AddNode(self.iceConnectorNode) self.iceConnectorNode.SetName(self.moduleName + 'ICEServerConnector') self.iceConnectorNode.SetTypeClient("localhost", 18944) self.iceConnectorNode.Start()
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
def voxelization(vtk_poly_data, voxels_size=1): """ Transform a mesh vtk poly data mesh representation objet to a list of voxels position, according to a voxels size float. Parameters ---------- vtk_poly_data : vtkPolyData vtkPolyData is a data object that is a concrete implementation of vtkDataSet. vtkPolyData represents a geometric structure consisting of vertices, lines, polygons, and/or triangle strips. Point and cell attribute values (e.g., scalars, vectors, etc.) also are represented. voxels_size : float, optional Size of the voxels verbose : bool, optional If True, print for some information of each part of the algorithms Returns ------- vtk_image_data : vtkImageData Topologically and geometrically regular array of data vtkImageData is a data object that is a concrete implementation of vtkDataSet. vtkImageData represents a geometric structure that is a topological and geometrical regular array of points. Examples include volumes (voxel data) and pixmaps """ # ========================================================================== # Build White Image white_image = vtk.vtkImageData() bounds = [0.0] * 6 vtk_poly_data.GetBounds(bounds) # desired volume spacing spacing = [voxels_size, voxels_size, voxels_size] white_image.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])) white_image.SetDimensions(dim) white_image.SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1) origin = [0.0] * 3 for i in range(3): origin[i] = bounds[i * 2] + spacing[i] / 2.0 white_image.SetOrigin(origin) # ========================================================================== white_image.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) inval = 255 outval = 0 count = white_image.GetNumberOfPoints() for i in range(count): white_image.GetPointData().GetScalars().SetTuple1(i, inval) # ========================================================================== # polygonal data --> image stencil: edges = vtk.vtkFeatureEdges() edges.SetInputData(vtk_poly_data) edges.FeatureEdgesOff() edges.NonManifoldEdgesOn() edges.BoundaryEdgesOn() edges.Update() pol2stenc = vtk.vtkPolyDataToImageStencil() pol2stenc.SetOutputOrigin(origin) pol2stenc.SetInputData(vtk_poly_data) pol2stenc.SetOutputSpacing(spacing) pol2stenc.SetOutputWholeExtent(white_image.GetExtent()) pol2stenc.Update() vtk.vtkCleanPolyData() # ========================================================================== # Cut the corresponding white image and set the background: imgstenc = vtk.vtkImageStencil() imgstenc.SetInputData(white_image) imgstenc.SetStencilConnection(pol2stenc.GetOutputPort()) imgstenc.ReverseStencilOff() imgstenc.SetBackgroundValue(outval) imgstenc.Update() # ========================================================================== return imgstenc.GetOutput()
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
def load_muscleSI_mha(self, T2image, image_pos_pat, image_ori_pat, m_bounds, iren): """ load_muscleSI: Place automatically a widget over muscle location from file INPUTS: ======= images: (vtkImageData) list of Input image to Transform OUTPUTS: ======= muscleSI (float) Signal intensity from muscle muscleSIcoords (float[3]) cords where Signal intensity from muscle is measured """ ## Transform T2 img loadDisplay = Display() # Proceed to build reference frame for display objects based on DICOM coords t_T2image = loadDisplay.mhaTransform(T2image, image_pos_pat, image_ori_pat) # Calculate the center of the volume t_T2image.UpdateInformation() print "\nBoxwidget placed..." ################################################################# # The box widget observes the events invoked by the render window # interactor. These events come from user interaction in the render # window. # Place the interactor initially. The output of the reader is used to # place the box widget. self.boxWidget = vtk.vtkBoxWidget() self.boxWidget.SetInteractor(iren) self.boxWidget.SetPlaceFactor(1) self.boxWidget.SetInput(t_T2image) self.boxWidget.ScalingEnabledOff() self.boxWidget.OutlineCursorWiresOn() # Construct a bounding box bwidg = [0,0,0,0,0,0] bwidg[0] = m_bounds[0]; bwidg[1] = m_bounds[1]; bwidg[2] = m_bounds[2]; bwidg[3] = m_bounds[3]; bwidg[4] = m_bounds[4]; bwidg[5] = m_bounds[5]; self.bounds_muscleSI = bwidg print "\nbounds_muscleSI " print self.bounds_muscleSI # add to visualize self.boxWidget.PlaceWidget( self.bounds_muscleSI ) self.boxWidget.On() ########## ### Set image stencil for muscle # create a simple box VOI mask shape using previously found boundsPlane_preselected VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( self.bounds_muscleSI ) VOIStencil.SetInformationInput(t_T2image) VOIStencil.Update() # cut the corresponding VOI region and set the background: extractVOI_imgstenc = vtk.vtkImageStencil() extractVOI_imgstenc.SetInput(t_T2image) extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput()) extractVOI_imgstenc.ReverseStencilOff() extractVOI_imgstenc.SetBackgroundValue(5000) extractVOI_imgstenc.Update() # take out average image finalmuscleSIIm = vtk.vtkImageData() finalmuscleSIIm = extractVOI_imgstenc.GetOutput() finalmuscleSIIm.Update() ## Display histogram dims = finalmuscleSIIm .GetDimensions() scalars = finalmuscleSIIm.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) muscleSI = np_scalars[np_scalars<5000] muscle_scalar_range = [muscleSI.min(), muscleSI.max()] print "\nMuscle scalar Range:" print muscle_scalar_range[0], muscle_scalar_range[1] return muscleSI, muscle_scalar_range, self.bounds_muscleSI
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() 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() stencilDataMask = vtk.vtkPolyDataToImageStencil() stencilDataMask.SetInput(cortMask.GetOutput()) stencilDataMask.SetInformationInput(image) stencilMask = vtk.vtkImageStencil() stencilMask.SetInput(image) stencilMask.SetBackgroundValue(0)
#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() #Log ("Image bounds:", ("%.4f" + " %.4f"*5) % imageBoundstest) # Create transform that rotates image to desired orientation transform = vtk.vtkTransform()
def getthresh(args): inputfile = args[0] outputfile = args[1] sx = args[2] ex = args[3] sy = args[4] ey = args[5] sz = args[6] ez = args[7] dataset = args[8] comptype = args[9] print ("Loading file, %s" % inputfile) #Determine if file is h5 or numpy if (inputfile.split(".")[1] == "npy"): rs = timeit.default_timer() vel = np.load(inputfile) re = timeit.default_timer() else: #read in file rs = timeit.default_timer() data_file = h5py.File(inputfile, 'r') vel = np.array(data_file[dataset]) data_file.close() re = timeit.default_timer() cs = timeit.default_timer() #convert numpy array to vtk vtkdata = numpy_support.numpy_to_vtk(vel.flat, deep=True, array_type=vtk.VTK_FLOAT) vtkdata.SetNumberOfComponents(3) vtkdata.SetName("Velocity") image = vtk.vtkImageData() image.GetPointData().SetVectors(vtkdata) image.SetExtent(sx,ex,sy,ey,sz,ez) #NOTE: Hardcoding Spacing image.SetSpacing(.006135923, .006135923, .006135923) print ("Doing computation") ce = timeit.default_timer() vs = timeit.default_timer() if (comptype == "v"): vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) vorticity.Update() elif (comptype == "q"): vorticity = vtk.vtkGradientFilter() vorticity.SetInputData(image) vorticity.SetInputScalars(image.FIELD_ASSOCIATION_POINTS,"Velocity") vorticity.ComputeQCriterionOn() vorticity.SetComputeGradient(0) vorticity.Update() ve = timeit.default_timer() #Generate contour for comparison c = vtk.vtkContourFilter() c.SetValue(0,1128) if (comptype == "q"): image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetVectors("Q-criterion")) else: image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetVectors()) c.SetInputData(image) c.Update() w = vtk.vtkXMLPolyDataWriter() w.SetEncodeAppendedData(0) #turn of base 64 encoding for fast write w.SetFileName("contour.vtp") w.SetInputData(c.GetOutput()) ws = timeit.default_timer() w.Write() ms = timeit.default_timer() if (comptype == "v"): mag = vtk.vtkImageMagnitude() cp = vtk.vtkCellDataToPointData() cp.SetInputData(vorticity.GetOutput()) cp.Update() image.GetPointData().SetScalars(cp.GetOutput().GetPointData().GetVectors()) mag.SetInputData(image) mag.Update() m = mag.GetOutput() m.GetPointData().RemoveArray("Velocity") else: image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetVectors("Q-criterion")) me = timeit.default_timer() print ("Thresholding.") ts = timeit.default_timer() t = vtk.vtkImageThreshold() #t = vtk.vtkThreshold() #sparse representation if (comptype == "q"): t.SetInputData(image) t.ThresholdByUpper(783.3) #.25*67.17^2 = 1127 #t.SetInputArrayToProcess(0,0,0, vorticity.GetOutput().FIELD_ASSOCIATION_POINTS, "Q-criterion") print("q criterion") else: t.SetInputData(m) t.SetInputArrayToProcess(0,0,0, mag.GetOutput().FIELD_ASSOCIATION_POINTS, "Magnitude") t.ThresholdByUpper(44.79) #44.79) #Set values in range to 1 and values out of range to 0 t.SetInValue(1) t.SetOutValue(0) #t.ReplaceInOn() #t.ReplaceOutOn() print("Update thresh") t.Update() #wt = vtk.vtkXMLImageDataWriter() #wt.SetInputData(t.GetOutput()) #wt.SetFileName("thresh.vti") #wt.Write() d = vtk.vtkImageDilateErode3D() d.SetInputData(t.GetOutput()) d.SetKernelSize(3,3,3) d.SetDilateValue(1) d.SetErodeValue(0) print ("Update dilate") d.Update() iis = vtk.vtkImageToImageStencil() iis.SetInputData(d.GetOutput()) iis.ThresholdByUpper(1) stencil = vtk.vtkImageStencil() stencil.SetInputConnection(2, iis.GetOutputPort()) stencil.SetBackgroundValue(0) #image.GetPointData().RemoveArray("Vorticity") #Set scalars to velocity so it can be cut by the stencil image.GetPointData().SetScalars(image.GetPointData().GetVectors()) #if (comptype == "q"): #Use this to get just q-criterion data instead of velocity data. Do we need both? # image.GetPointData().SetScalars(vorticity.GetOutput().GetPointData().GetScalars("Q-criterion")) stencil.SetInputData(image) print ("Update stencil") stencil.Update() te = timeit.default_timer() print("Setting up write") ws = timeit.default_timer() #Make velocity a vector again velarray = stencil.GetOutput().GetPointData().GetScalars() image.GetPointData().RemoveArray("Velocity") image.GetPointData().SetVectors(velarray) w = vtk.vtkXMLImageDataWriter() w.SetCompressorTypeToZLib() #w.SetCompressorTypeToNone() Need to figure out why this fails. w.SetEncodeAppendedData(0) #turn of base 64 encoding for fast write w.SetFileName(outputfile) w.SetInputData(image) if (0): w.SetCompressorTypeToZfp() w.GetCompressor().SetNx(ex-sx+1) w.GetCompressor().SetNy(ey-sy+1) w.GetCompressor().SetNz(ez-sz+1) w.GetCompressor().SetTolerance(1e-1) w.GetCompressor().SetNumComponents(3) w.Write() we = timeit.default_timer() print("Results:") print("Read time: %s" % str(re-rs)) print ("Convert to vtk: %s" % str(ce-cs)) if (comptype == "q"): print ("Q Computation: %s" % str(ve-vs)) print ("Q Magnitude: %s" % str(me-ms)) else: print ("Vorticity Computation: %s" % str(ve-vs)) print ("Vorticity Magnitude: %s" % str(me-ms)) print ("Threshold: %s" % str(te-ts)) print ("Write %s" % str(we-ws)) print ("Total time: %s" % str(we-rs))
roiStencil1.SetSlicePoints(0,points1) roiStencil1.SetInformationInput(reader.GetOutput()) roiStencil2 = vtk.vtkLassoStencilSource() roiStencil2.SetShapeToPolygon() roiStencil2.SetPoints(points2) roiStencil2.SetInformationInput(reader.GetOutput()) roiStencil3 = vtk.vtkLassoStencilSource() roiStencil3.SetShapeToSpline() roiStencil3.SetPoints(points1) roiStencil3.SetInformationInput(reader.GetOutput()) roiStencil4 = vtk.vtkLassoStencilSource() roiStencil4.SetShapeToSpline() roiStencil4.SetSlicePoints(0,points2) roiStencil4.SetInformationInput(reader.GetOutput()) roiStencil4.Update() stencil1 = vtk.vtkImageStencil() stencil1.SetInputConnection(reader.GetOutputPort()) stencil1.SetBackgroundInputData(shiftScale.GetOutput()) stencil1.SetStencilConnection(roiStencil1.GetOutputPort()) stencil2 = vtk.vtkImageStencil() stencil2.SetInputConnection(reader.GetOutputPort()) stencil2.SetBackgroundInputData(shiftScale.GetOutput()) stencil2.SetStencilConnection(roiStencil2.GetOutputPort()) stencil3 = vtk.vtkImageStencil() stencil3.SetInputConnection(reader.GetOutputPort()) stencil3.SetBackgroundInputData(shiftScale.GetOutput()) stencil3.SetStencilConnection(roiStencil3.GetOutputPort()) stencil4 = vtk.vtkImageStencil() stencil4.SetInputConnection(reader.GetOutputPort()) stencil4.SetBackgroundInputData(shiftScale.GetOutput()) stencil4.SetStencilConnection(roiStencil4.GetOutputPort())
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())
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
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;
def segmentFromSeeds(self, images, image_pos_pat, image_ori_pat, seeds, iren, xplane, yplane, zplane): """ segmentFromSeeds: Extracts VOI from seeds INPUTS: ======= images: (vtkImageData) list of Input image to Transform seeds: vtkPoints list of seeded coordinates from picker OUTPUTS: ======= transformed_image (vtkImageData) Transformed imaged mapped to dicom coords frame transform (vtkTransform) Transform used """ for postS in range(1,len(images)): print "\n Segmenting image post no : %s " % str(postS) subimage = self.loadDisplay.subImage(images, postS) # Proceed to build reference frame for display objects based on DICOM coords [transformed_image, transform_cube] = self.loadDisplay.dicomTransform(subimage, image_pos_pat, image_ori_pat) # Calculate the center of the volume transformed_image.UpdateInformation() print "\nBoxwidget placed..." ################################################################# # The box widget observes the events invoked by the render window # interactor. These events come from user interaction in the render # window. # Place the interactor initially. The output of the reader is used to # place the box widget. self.boxWidget = vtk.vtkBoxWidget() self.boxWidget.SetInteractor(iren) self.boxWidget.SetPlaceFactor(1) self.boxWidget.SetInput(transformed_image) if( self.boundsPlane_presel != []): self.boxWidget.PlaceWidget( self.boundsPlane_presel ) # Construct a bounding box around the seeds init_seedsBounds = [0,0,0,0,0,0] seeds.GetBounds( init_seedsBounds ) if postS == 1: # polygonal data --> image stencil: # create a simple box VOI mask shape using previously found boundsPlane_preselected VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( init_seedsBounds ) VOIStencil.SetInformationInput(transformed_image) VOIStencil.Update() # cut the corresponding VOI region and set the background: extractVOI_imgstenc = vtk.vtkImageStencil() extractVOI_imgstenc.SetInput(transformed_image) extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput()) extractVOI_imgstenc.ReverseStencilOff() extractVOI_imgstenc.SetBackgroundValue(0.0) extractVOI_imgstenc.Update() allSeededIm = vtk.vtkImageData() allSeededIm.DeepCopy( extractVOI_imgstenc.GetOutput() ) # Add some bounding box radius self.boxWidget.PlaceWidget( init_seedsBounds ) self.boundsPlane_presel = init_seedsBounds print "seeds.GetBounds" print init_seedsBounds self.boxWidget.AddObserver("InteractionEvent", self.SelectPolygons) self.boxWidget.On() # turn off planes xplane.Off() yplane.Off() iren.Start() self.boxWidget.Off() # polygonal data --> image stencil: print "\n Create vtkPolyDataToImageStencil with bounds:" print self.boundsPlane_presel # create a simple box VOI mask shape using previously found boundsPlane_preselected VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( self.boundsPlane_presel ) VOIStencil.SetInformationInput(transformed_image) VOIStencil.Update() # cut the corresponding VOI region and set the background: extractVOI_imgstenc = vtk.vtkImageStencil() extractVOI_imgstenc.SetInput(transformed_image) extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput()) extractVOI_imgstenc.ReverseStencilOff() extractVOI_imgstenc.SetBackgroundValue(0.0) extractVOI_imgstenc.Update() # add subsecuent VOI stencils addsegROI = vtk.vtkImageMathematics() addsegROI.SetInput(0, allSeededIm) addsegROI.SetInput(1, extractVOI_imgstenc.GetOutput()) addsegROI.SetOperationToAdd() addsegROI.Update() # turn off the box allSeededIm = addsegROI.GetOutput() avegSeededIm = vtk.vtkImageMathematics() avegSeededIm.SetInput(0, allSeededIm) avegSeededIm.SetOperationToMultiplyByK() avegSeededIm.SetConstantK( 0.2 ) avegSeededIm.Update() # take out average image finalSeedIm = avegSeededIm.GetOutput() xplane.SetInput( finalSeedIm ) yplane.SetInput( finalSeedIm ) zplane.SetInput( finalSeedIm ) image_scalar_range = finalSeedIm.GetScalarRange() lThre = image_scalar_range[0] uThre = image_scalar_range[1] print "\n Image Scalar Range:" print image_scalar_range[0], image_scalar_range[1] print "Uper thresholding by" print uThre*0.25 ## Display histogram scalars = finalSeedIm.GetPointData().GetScalars() np_scalars = vtk_to_numpy(scalars) pylab.figure() pylab.hist(np_scalars.flatten(), histtype='bar') pylab.show() # Now performed threshold on initialized VOI # vtkImageThresholdConnectivity will perform a flood fill on an image, given upper and lower pixel intensity # thresholds. It works similarly to vtkImageThreshold, but also allows the user to set seed points to limit # the threshold operation to contiguous regions of the image. The filled region, or the "inside", will be passed # through to the output by default, while the "outside" will be replaced with zeros. The scalar type of the output is the same as the input. thresh_sub = vtk.vtkImageThresholdConnectivity() thresh_sub.SetSeedPoints(seeds) thresh_sub.SetNeighborhoodRadius(3, 3, 2) #The radius of the neighborhood that must be within the threshold values in order for the voxel to be included in the mask. The default radius is zero (one single voxel). The radius is measured in voxels thresh_sub.SetNeighborhoodFraction(0.10) #The fraction of the neighborhood that must be within the thresholds. The default value is 0.5. thresh_sub.ThresholdBetween(0.25*uThre, uThre); thresh_sub.SetInput( finalSeedIm ) thresh_sub.Update() xplane.SetInput( thresh_sub.GetOutput() ) yplane.SetInput( thresh_sub.GetOutput() ) zplane.SetInput( thresh_sub.GetOutput() ) iren.Start() # Convert VOIlesion into polygonal struct VOIlesion_poly = vtk.vtkMarchingCubes() VOIlesion_poly.SetValue(0,255) VOIlesion_poly.SetInput(thresh_sub.GetOutput()) VOIlesion_poly.ComputeNormalsOff() VOIlesion_poly.Update() # Recalculate num_voxels and vol_lesion on VOI nvoxels = VOIlesion_poly.GetOutput().GetNumberOfCells() print "\n Number of Voxels: %d" % nvoxels # After the filter has executed, use GetNumberOfVoxels() to find out how many voxels were filled. return VOIlesion_poly.GetOutput()
def load_muscleSI(self, t_T2image, m_bounds, iren, ren, picker, xplane, yplane, zplane): """ load_muscleSI: Place automatically a widget over muscle location from file INPUTS: ======= images: (vtkImageData) list of Input image to Transform OUTPUTS: ======= muscleSI (float) Signal intensity from muscle muscleSIcoords (float[3]) cords where Signal intensity from muscle is measured """ ## Transform T2 img # loadDisplay = Display() # # # Proceed to build reference frame for display objects based on DICOM coords # [t_T2image, transform_cube] = loadDisplay.dicomTransform(T2image, image_pos_pat, image_ori_pat) # # # Calculate the center of the volume # t_T2image.UpdateInformation() print "\nBoxwidget placed..." ################################################################# # The box widget observes the events invoked by the render window # interactor. These events come from user interaction in the render # window. # Place the interactor initially. The output of the reader is used to # place the box widget. self.boxWidget = vtk.vtkBoxWidget() self.boxWidget.SetInteractor(iren) self.boxWidget.SetPlaceFactor(1) self.boxWidget.SetInput(t_T2image) self.boxWidget.ScalingEnabledOff() self.boxWidget.OutlineCursorWiresOn() # Construct a bounding box bwidg = [0,0,0,0,0,0] bwidg[0] = m_bounds[0]; bwidg[1] = m_bounds[1]; bwidg[2] = m_bounds[2]; bwidg[3] = m_bounds[3]; bwidg[4] = m_bounds[4]; bwidg[5] = m_bounds[5]; self.bounds_muscleSI = bwidg print "\nbounds_muscleSI " print self.bounds_muscleSI # add to visualize self.boxWidget.PlaceWidget( self.bounds_muscleSI ) self.boxWidget.On() #iren.Start() ############################# Do extract_muscleSI print "\n Re-extract muscle VOI? " rexorNot=0 rexorNot = int(raw_input('type 1 to Re-extract or anykey: ')) if rexorNot == 1: # custom interaction self.picker = picker self.textMapper = vtk.vtkTextMapper() tprop = self.textMapper.GetTextProperty() tprop.SetFontFamilyToArial() tprop.SetFontSize(10) tprop.BoldOn() tprop.ShadowOn() tprop.SetColor(1, 0, 0) self.textActor = vtk.vtkActor2D() self.textActor.VisibilityOff() self.textActor.SetMapper(self.textMapper) ren.AddActor2D(self.textActor) picker.AddObserver("EndPickEvent", self.annotatePick) iren.Start() # Construct a bounding box bwidg = [0,0,0,0,0,0] bwidg[0] = self.pickPos[0]; bwidg[1] = self.pickPos[0]+5; bwidg[2] = self.pickPos[1]; bwidg[3] = self.pickPos[1]+5; bwidg[4] = self.pickPos[2]; bwidg[5] = self.pickPos[2]+5; self.bounds_muscleSI = bwidg print "\nbounds_muscleSI " print self.bounds_muscleSI self.boxWidget.PlaceWidget( self.bounds_muscleSI ) # turn off planes xplane.Off() yplane.Off() self.boxWidget.On() ########## ### Set image stencil for muscle # create a simple box VOI mask shape using previously found boundsPlane_preselected VOIStencil = vtk.vtkROIStencilSource() VOIStencil.SetShapeToBox() VOIStencil.SetBounds( self.bounds_muscleSI ) VOIStencil.SetInformationInput(t_T2image) VOIStencil.Update() # cut the corresponding VOI region and set the background: extractVOI_imgstenc = vtk.vtkImageStencil() extractVOI_imgstenc.SetInput(t_T2image) extractVOI_imgstenc.SetStencil(VOIStencil.GetOutput()) extractVOI_imgstenc.ReverseStencilOff() extractVOI_imgstenc.SetBackgroundValue(5000) extractVOI_imgstenc.Update() # take out average image finalmuscleSIIm = vtk.vtkImageData() finalmuscleSIIm = extractVOI_imgstenc.GetOutput() finalmuscleSIIm.Update() ## Display histogram dims = finalmuscleSIIm .GetDimensions() scalars = finalmuscleSIIm.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) muscleSI = np_scalars[np_scalars<5000] print "ave. T2_muscleSI: %d" % mean(muscleSI) muscle_scalar_range = [muscleSI.min(), muscleSI.max()] print "\nMuscle scalar Range:" print muscle_scalar_range[0], muscle_scalar_range[1] return muscleSI, muscle_scalar_range, self.bounds_muscleSI