def __init__(self, parent=None): ScriptedLoadableModuleWidget.__init__(self, parent) settings = qt.QSettings() self.developerMode = SlicerUtil.IsDevelopment if not parent: self.parent = slicer.qMRMLWidget() self.parent.setLayout(qt.QVBoxLayout()) self.parent.setMRMLScene(slicer.mrmlScene) else: self.parent = parent self.layout = self.parent.layout() if not parent: self.setup() self.parent.show() self.priority = 2 self.calcificationType = 0 self.ThresholdMin = 130.0 self.ThresholdMax = 1000.0 self.MinimumLesionSize = 1 self.MaximumLesionSize = 500 self.croppedVolumeNode = slicer.vtkMRMLScalarVolumeNode() self.threshImage = vtk.vtkImageData() self.marchingCubes = vtk.vtkDiscreteMarchingCubes() self.transformPolyData = vtk.vtkTransformPolyDataFilter() self.selectedLabelList = [] self.labelScores = [] self.selectedLabels = {} self.modelNodes = [] self.voxelVolume = 1. self.sx = 1. self.sy = 1. self.sz = 1. self.selectedRGB = [1,0,0] self.observerTags = [] self.xy = [] self.summary_reports=["Agatston Score","Mass Score","Volume"] self.labelScores = dict() self.totalScores=dict() for sr in self.summary_reports: self.labelScores[sr]=[] self.totalScores[sr]=0 self.columnsDict = OrderedDict() self.columnsDict["CaseID"] = "CaseID" for sr in self.summary_reports: self.columnsDict[sr.replace(" ","")]=sr
def extract(color, isovalue): skinExtractor = vtk.vtkDiscreteMarchingCubes() skinExtractor.SetInputConnection(dataImporter.GetOutputPort()) skinExtractor.SetValue(0, isovalue) smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(skinExtractor.GetOutputPort()) smooth.SetNumberOfIterations(15) smooth.SetRelaxationFactor(0.2) smooth.FeatureEdgeSmoothingOff() smooth.BoundarySmoothingOn() smooth.Update() skinStripper = vtk.vtkStripper() skinStripper.SetInputConnection(smooth.GetOutputPort()) skinMapper = vtk.vtkOpenGLPolyDataMapper() skinMapper.SetInputConnection(skinStripper.GetOutputPort()) skinMapper.ScalarVisibilityOff() skin = vtk.vtkOpenGLActor() skin.SetMapper(skinMapper) skin.GetProperty().SetDiffuseColor(colors.GetColor3d(color)) skin.GetProperty().SetSpecular(.3) skin.GetProperty().SetSpecularPower(20) return skin
def update_mask(self, src): # Filter cast_filter = vtk.vtkImageCast() cast_filter.SetOutputScalarTypeToUnsignedInt() cast_filter.SetInputData(src) cast_filter.Update() # Create mesh using marching cube march = vtk.vtkDiscreteMarchingCubes() march.ComputeNormalsOn() march.ComputeGradientsOn() for i, organ in enumerate(Settings.organs): march.SetValue(i, Settings.labels[organ]['value']) march.SetInputData(cast_filter.GetOutput()) march.Update() # Filtrate the masks smooth = vtk.vtkWindowedSincPolyDataFilter() smooth.SetInputConnection(march.GetOutputPort()) smooth.SetNumberOfIterations(15) smooth.BoundarySmoothingOff() smooth.FeatureEdgeSmoothingOff() smooth.SetFeatureAngle(120.0) smooth.SetPassBand(.001) smooth.NonManifoldSmoothingOn() smooth.NormalizeCoordinatesOn() smooth.Update() self.surface_mapper.SetInputConnection(smooth.GetOutputPort())
def vtk_marching_cube_multi(vtkLabel, bg_id, smooth=None): """ Use the VTK marching cube to create isosrufaces for all classes excluding the background Args: labels: vtk image contraining the label map bg_id: id number of background class smooth: smoothing iteration Returns: mesh: vtk PolyData of the surface mesh """ ids = np.unique(vtk_to_numpy(vtkLabel.GetPointData().GetScalars())) ids = np.delete(ids, np.where(ids == bg_id)) #smooth the label map #vtkLabel = utils.gaussianSmoothImage(vtkLabel, 2.) contour = vtk.vtkDiscreteMarchingCubes() contour.SetInputData(vtkLabel) for index, i in enumerate(ids): print("Setting iso-contour value: ", i) contour.SetValue(index, i) contour.Update() mesh = contour.GetOutput() return mesh
def MCBRecons(X): img = convert_to_vtk(X) dmc = vtk.vtkDiscreteMarchingCubes() #dmc.SetInputConnection(dataImporter.GetOutputPort()) dmc.SetInputData(img) dmc.GenerateValues(1, 1, 1) dmc.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(dmc.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) renderer = vtk.vtkRenderer() renderer.AddActor(actor) renderer.SetBackground(1.0, 1.0, 1.0) renderWin = vtk.vtkRenderWindow() renderWin.AddRenderer(renderer) renderInteractor = vtk.vtkRenderWindowInteractor() renderInteractor.SetRenderWindow(renderWin) renderWin.SetSize(1000, 1000) renderWin.AddObserver("AbortCheckEvent", exitCheck) renderInteractor.Initialize() renderWin.Render() renderInteractor.Start()
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkDiscreteMarchingCubes(), 'Processing.', ('vtkImageData',), ('vtkPolyData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def create_mesh(label_pix, labels_to_use, inds_to_phys=None): # convert the numpy representation to VTK, so we can create a mesh # using marching cubes for display later vtk_import = vtkImageImport() vtk_import.SetImportVoidPointer(label_pix, True) vtk_import.SetDataScalarType(VTK_UNSIGNED_CHAR) vtk_import.SetNumberOfScalarComponents(1) vtk_import.SetDataExtent(0, label_pix.shape[2] - 1, 0, label_pix.shape[1] - 1, 0, label_pix.shape[0] - 1) vtk_import.SetWholeExtent(0, label_pix.shape[2] - 1, 0, label_pix.shape[1] - 1, 0, label_pix.shape[0] - 1) vtk_import.Update() flipper = vtkImageFlip() flipper.SetInputData(vtk_import.GetOutput()) flipper.SetFilteredAxis(1) flipper.FlipAboutOriginOff() flipper.Update() vtk_img = flipper.GetOutput() marching_cubes = vtkDiscreteMarchingCubes() marching_cubes.SetInputData(vtk_img) num_labels_to_use = len(labels_to_use) marching_cubes.SetNumberOfContours(num_labels_to_use) for i in range(num_labels_to_use): marching_cubes.SetValue(i, labels_to_use[i]) marching_cubes.Update() smoother = vtkWindowedSincPolyDataFilter() smoother.SetInputData(marching_cubes.GetOutput()) smoother.SetNumberOfIterations(25) smoother.SetPassBand(0.1) smoother.SetBoundarySmoothing(False) smoother.SetFeatureEdgeSmoothing(False) smoother.SetFeatureAngle(120.0) smoother.SetNonManifoldSmoothing(True) smoother.NormalizeCoordinatesOn() smoother.Update() mesh_reduce = vtkQuadricDecimation() mesh_reduce.SetInputData(smoother.GetOutput()) mesh_reduce.SetTargetReduction(0.25) mesh_reduce.Update() vertex_xform = np.mat(np.eye(4)) vertex_xform[1, 1] = -1 vertex_xform[1, 3] = label_pix.shape[1] + 1 vertex_xform = inds_to_phys * vertex_xform return xform_mesh(mesh_reduce.GetOutput(), vertex_xform)
def discrete(reader, r): d = vtk.vtkDiscreteMarchingCubes() d.SetInputConnection(reader.GetOutputPort()) d.GenerateValues(1, r[0], r[1]) #1,1,10 d.ComputeNormalsOn() d.Update() return d
def save_stl(array, spacing, origin, name): # array to vtkImageData flatten_array = array.ravel() shape = np.array(array.shape) vtk_data_array = numpy_to_vtk( num_array= flatten_array, # ndarray contains the fitting result from the points. It is a 3D array deep=True, array_type=vtk.VTK_FLOAT) # convert vessel array to poly and save as STL img_vtk = vtk.vtkImageData() img_vtk.SetDimensions(shape[::-1]) img_vtk.SetSpacing(spacing) img_vtk.SetOrigin(origin) img_vtk.SetDirectionMatrix(-1, 0, 0, 0, -1, 0, 0, 0, 1) img_vtk.GetPointData().SetScalars(vtk_data_array) surf = vtk.vtkDiscreteMarchingCubes() surf.SetInputData(img_vtk) surf.SetValue(0, array.max()) # smoothing the mesh smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(surf.GetOutputPort()) smoother.SetNumberOfIterations(50) smoother.SetRelaxationFactor(0.1) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() smoother.Update() stl_writer = vtk.vtkSTLWriter() stl_writer.SetFileName(name) stl_writer.SetInputData(smoother.GetOutput()) stl_writer.Write()
def vox2vtk(voxels, zero_point=None): """ converts voxels to vkt mesh object reduce_poly: 0-1, less to more simplification zero_point: if a zero point is provided, the extent of the vtk file is set so that the zero point is in the center """ # import voxels xs, ys, zs = voxels.shape dataImporter = vtk.vtkImageImport() data_string = voxels.tostring() dataImporter.CopyImportVoidPointer(data_string, len(data_string)) dataImporter.SetDataScalarTypeToUnsignedChar() dataImporter.SetNumberOfScalarComponents(1) # whole extent needs to be relative to original dataImporter.SetDataExtent(0, zs - 1, 0, ys - 1, 0, xs - 1) if zero_point is None: dataImporter.SetWholeExtent(0, xs - 1, 0, ys - 1, 0, zs - 1) else: dataImporter.SetWholeExtent(-zero_point[0], zs - 1, -zero_point[1], ys - 1, -zero_point[2], xs - 1) # convert to mesh dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(dataImporter.GetOutputPort()) dmc.GenerateValues(1, 1, 1) dmc.Update() return dmc
def DiscreteMarchingCubes(image): # Main part of discretemarchingcubes discreteCubes = vtk.vtkDiscreteMarchingCubes() discreteCubes.SetInputData(image) discreteCubes.GenerateValues( 116, 1-50,116-50); discreteCubes.Update() for i in range(0,116): print discreteCubes.GetValue(i) lut = CreateLookUpTable(color_map); # visualization print "visualizing..." mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(discreteCubes.GetOutput()) mapper.ScalarVisibilityOn() mapper.SetScalarRange(0,4) mapper.SetLookupTable(lut) actor = vtk.vtkActor() actor.SetMapper(mapper) renderer = vtk.vtkRenderer() renderer.AddActor(actor) window = vtk.vtkRenderWindow() window.AddRenderer(renderer) interactor = vtk.vtkRenderWindowInteractor() window.SetInteractor(interactor) window.Render() interactor.Start()
def labels2meshes_vtk(surfdir, compdict, labelimage, labels=[], spacing=[1, 1, 1], offset=[0, 0, 0], nvoxthr=0): """Generate meshes from a labelimage with vtk marching cubes.""" try: import vtk except ImportError: return if not labels: labels = np.unique(labelimage) labels = np.delete(labels, 0) # labels = np.unique(labelimage[labelimage > 0]) print('number of labels to process: ', len(labels)) labelimage = np.lib.pad(labelimage.tolist(), ((1, 1), (1, 1), (1, 1)), 'constant') dims = labelimage.shape vol = vtk.vtkImageData() vol.SetDimensions(dims[0], dims[1], dims[2]) vol.SetOrigin(offset[0] * spacing[0] + spacing[0], offset[1] * spacing[1] + spacing[1], offset[2] * spacing[2] + spacing[2]) # vol.SetOrigin(0, 0, 0) vol.SetSpacing(spacing[0], spacing[1], spacing[2]) sc = vtk.vtkFloatArray() sc.SetNumberOfValues(labelimage.size) sc.SetNumberOfComponents(1) sc.SetName('tnf') for ii, val in enumerate(np.ravel(labelimage.swapaxes(0, 2))): # FIXME: why swapaxes??? sc.SetValue(ii, val) vol.GetPointData().SetScalars(sc) dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInput(vol) dmc.ComputeNormalsOn() for label in labels: try: labelname = compdict[label]['name'] except KeyError: labelname = 'label.{:05d}'.format(label) fpath = os.path.join(surfdir, '{:s}.stl'.format(labelname)) print("Processing label {} (value: {:05d})".format(labelname, label)) dmc.SetValue(0, label) dmc.Update() writer = vtk.vtkSTLWriter() writer.SetInputConnection(dmc.GetOutputPort()) writer.SetFileName(fpath) writer.Write()
def vis_bw(ax, a, facecolor='r'): # verts, faces, normals, values = measure.marching_cubes_lewiner(a, 0) # print(verts) # mesh = Poly3DCollection(verts[faces], alpha=0.5) # mesh.set_facecolor(facecolor) # ax.add_collection3d(mesh) # v_a = numpy_support.numpy_to_vtk(num_array=a.ravel(), deep=True, array_type=vtk.VTK_STRUCTURED_POINTS) # v_a = vtk.vtkDataObject() # v_a.SetInformation(v_bit_a) # n2vtk = vtk.vtkImageImport() # Converter # n2vtk.SetArr # # contour = vtk.vtkDiscreteMarchingCubes() # contour.SetInputData(v_a) # contour.SetValue(0, .5) # contour.Update() # writer = vtk.vtkPolyDataWriter() # writer.SetInputData(contour) # writer.SetFileName('contour.vtk') # writer.Update() # mc = vtk.vtkMarchingCubes(v_a) # print(v_a) n_a = np.ravel(sitk.GetArrayFromImage(a), order='C') v_a = vtk.vtkImageData() v_a.SetSpacing(a.GetSpacing()) v_a.SetOrigin(a.GetOrigin()) v_a.SetDimensions(a.GetSize()) print(a.GetPixelID()) v_a.SetScalarType(convertTypeITKtoVTK(sitk.sitkInt8), vtk.vtkInformation()) v_a.SetNumberOfScalarComponents(a.GetNumberOfComponentsPerPixel(), vtk.vtkInformation()) print('a') v_a_to_VTK = numpy_to_vtk(n_a, deep=True, array_type=convertTypeITKtoVTK(a.GetPixelID())) print('b') v_a.GetPointData().SetScalars(v_a_to_VTK) fow = vtk.vtkFileOutputWindow() fow.SetFileName('ow.txt') ow = vtk.vtkOutputWindow() ow.SetInstance(fow) contour = vtk.vtkDiscreteMarchingCubes() contour.SetInputData(v_a) contour.SetValue(0, .5) contour.Update() writer = vtk.vtkPolyDataWriter() writer.SetInputData(contour.GetOutput()) writer.SetFileName('contour.vtk') writer.Update()
def labels2meshes_vtk(datadir, compdict, labelimage, labels=[], spacing=[1, 1, 1], offset=[0, 0, 0], nvoxthr=0): """""" if not labels: labels = np.unique(labelimage) labels = np.delete(labels, 0) # labels = np.unique(labelimage[labelimage>0]) print('number of labels to process: ', len(labels)) labelimage = np.lib.pad(labelimage.tolist(), ((1, 1), (1, 1), (1, 1)), 'constant') dims = labelimage.shape vol = vtk.vtkImageData() vol.SetDimensions(dims[0], dims[1], dims[2]) vol.SetOrigin(offset[0] * spacing[0] + spacing[0], offset[1] * spacing[1] + spacing[1], offset[2] * spacing[2] + spacing[2]) # vol.SetOrigin(0, 0, 0) vol.SetSpacing(spacing[0], spacing[1], spacing[2]) sc = vtk.vtkFloatArray() sc.SetNumberOfValues(labelimage.size) sc.SetNumberOfComponents(1) sc.SetName('tnf') for ii, val in enumerate(np.ravel(labelimage.swapaxes( 0, 2))): # why swapaxes??? sc.SetValue(ii, val) vol.GetPointData().SetScalars(sc) dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInput(vol) dmc.ComputeNormalsOn() surfdir = 'dmcsurf' mkdir_p(os.path.join(datadir, surfdir)) for ii, label in enumerate(labels): for labelclass, labels in compdict.items(): if label in labels: break else: labelclass = 'NN' ndepth = 1 fpath = os.path.join( datadir, surfdir, labelclass + '.{:05d}.{:02d}.stl'.format(label, ndepth)) print("Processing labelnr " + str(ii) + " of class " + labelclass + " with value: " + str(label)) # print("Saving to " + fpath) dmc.SetValue(0, label) # dmc.GenerateValues(nb_labels, 0, nb_labels) dmc.Update() writer = vtk.vtkSTLWriter() writer.SetInputConnection(dmc.GetOutputPort()) writer.SetFileName(fpath) writer.Write()
def main(): # vtkDiscreteFlyingEdges3D was introduced in VTK >= 8.2 use_flying_edges = vtk_version_ok(8, 2, 0) n = 20 radius = 8 blob = make_blob(n, radius) if use_flying_edges: try: discrete = vtk.vtkDiscreteFlyingEdges3D() except AttributeError: discrete = vtk.vtkDiscreteMarchingCubes() else: discrete = vtk.vtkDiscreteMarchingCubes() discrete.SetInputData(blob) discrete.GenerateValues(n, 1, n) lut = make_colors(n) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(discrete.GetOutputPort()) mapper.SetLookupTable(lut) mapper.SetScalarRange(0, lut.GetNumberOfColors()) # Create the RenderWindow, Renderer and both Actors # ren = vtk.vtkRenderer() ren_win = vtk.vtkRenderWindow() ren_win.AddRenderer(ren) ren_win.SetWindowName('DiscreteMarchingCubes') iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(ren_win) actor = vtk.vtkActor() actor.SetMapper(mapper) ren.AddActor(actor) colors = vtk.vtkNamedColors() ren.SetBackground(colors.GetColor3d('Burlywood')) ren_win.Render() iren.Start()
def create_marching_cube(data, color, opacity=0.5, min_threshold=0, smoothing_iterations=None, spacing=[1., 1., 1.]): im = vtk.vtkImageData() I, J, K = data.shape[:3] im.SetDimensions(I, J, K) im.SetSpacing(spacing[0], spacing[1], spacing[2]) im.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) vol = np.swapaxes(data, 0, 2) vol = np.ascontiguousarray(vol) vol = vol.ravel() uchar_array = numpy_support.numpy_to_vtk(vol, deep=0) im.GetPointData().SetScalars(uchar_array) mapper = vtk.vtkDataSetMapper() mapper.SetInputData(im) mapper.Update() threshold = vtk.vtkImageThreshold() threshold.SetInputData(im) threshold.ThresholdByLower(min_threshold) threshold.ReplaceInOn() threshold.SetInValue(0) threshold.ReplaceOutOn() threshold.SetOutValue(1) threshold.Update() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(threshold.GetOutputPort()) dmc.GenerateValues(1, 1, 1) dmc.Update() mapper = vtk.vtkPolyDataMapper() if smoothing_iterations is not None: smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(dmc.GetOutputPort()) smoother.SetNumberOfIterations(smoothing_iterations) smoother.Update() mapper.SetInputConnection(smoother.GetOutputPort()) else: mapper.SetInputConnection(dmc.GetOutputPort()) mapper.Update() actor = vtk.vtkActor() actor.SetMapper(mapper) mapper.ScalarVisibilityOff() actor.GetProperty().SetColor(color) actor.GetProperty().SetOpacity(opacity) return actor
def applyDiscreteMarchingCubes(self, imgData): # Apply marching cubes to render surface # Distcrete MarchingCubes speeds up computation dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputData(imgData.GetOutput()) dmc.GenerateValues(1, 1, 1) dmc.Update() return dmc # vtkPolyData
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__(self, module_manager, vtk.vtkDiscreteMarchingCubes(), 'Processing.', ('vtkImageData', ), ('vtkPolyData', ), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def arrayToPoly(array, origin, spacing, direction): # array to vtkImageData flatten_array = array.ravel() vtk_data_array = numpy_to_vtk( num_array= flatten_array, # ndarray contains the fitting result from the points. It is a 3D array deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) # Convert the VTK array to vtkImageData shape = np.array(array.shape[::-1]) origin = np.array(origin) spacing = np.array(spacing) img_vtk = vtk.vtkImageData() img_vtk.SetDimensions(shape) img_vtk.SetSpacing(spacing) img_vtk.SetOrigin(origin) img_vtk.SetDirectionMatrix(*direction) img_vtk.GetPointData().SetScalars(vtk_data_array) surf = vtk.vtkDiscreteMarchingCubes() surf.SetInputData(img_vtk) surf.SetValue( 0, 1 ) # use surf.GenerateValues function if more than one contour is available in the file # surf.GenerateValues(2, 0, 1) # use surf.GenerateValues function if more than one contour is available in the file surf.Update() # smoothing the mesh smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(surf.GetOutputPort()) smoother.SetNumberOfIterations(50) smoother.SetRelaxationFactor(0.1) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() smoother.Update() # Update normals on newly smoothed polydata normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputConnection(smoother.GetOutputPort()) normalGenerator.ComputePointNormalsOn() normalGenerator.ComputeCellNormalsOn() normalGenerator.Update() # transform transform = vtk.vtkTransform() transform.Scale(-1, -1, 1) transform_filter = vtk.vtkTransformFilter() transform_filter.SetTransform(transform) transform_filter.SetInputData(normalGenerator.GetOutput()) transform_filter.TransformAllInputVectorsOn() transform_filter.Update() poly = transform_filter.GetOutput() return poly
def marchingcubes(image, startlabel, endlabel): """Generates object boundaries from labelled volumes using Marching Cubes algorithm.""" discretecubes = vtk.vtkDiscreteMarchingCubes() discretecubes.SetInput(image) discretecubes.GenerateValues(endlabel - startlabel + 1, startlabel, endlabel) discretecubes.Update() return discretecubes.GetOutput()
def __init__(self, source): # Get list with string-representations of the organs to be used organs = Settings.organs source.Update() # Filter cast_filter = vtk.vtkImageCast() cast_filter.SetOutputScalarTypeToUnsignedInt() cast_filter.SetInputConnection(source.GetOutputPort()) cast_filter.Update() # Create mesh using marching cube march = vtk.vtkDiscreteMarchingCubes() march.ComputeNormalsOn() march.ComputeGradientsOn() for i, organ in enumerate(organs): march.SetValue(i, Settings.labels[organ]['value']) march.SetInputData(cast_filter.GetOutput()) march.Update() # Filtrate the masks smooth = vtk.vtkWindowedSincPolyDataFilter() smooth.SetInputConnection(march.GetOutputPort()) smooth.SetNumberOfIterations(15) smooth.BoundarySmoothingOff() smooth.FeatureEdgeSmoothingOff() smooth.SetFeatureAngle(120.0) smooth.SetPassBand(.001) smooth.NonManifoldSmoothingOn() smooth.NormalizeCoordinatesOn() smooth.Update() # Set lookup table self.color_transfer = vtk.vtkDiscretizableColorTransferFunction() self.alpha_transfer = vtk.vtkPiecewiseFunction() self.color_transfer.AddRGBPoint(0, 0., 0., 0.) # Background self.alpha_transfer.AddPoint(0, 0) # Background for i, organ in enumerate(Settings.organs): self.color_transfer.AddRGBPoint(Settings.labels[organ]['value'], *Settings.labels[organ]['rgb']) self.alpha_transfer.AddPoint(Settings.labels[organ]['value'], 1.) self.color_transfer.SetScalarOpacityFunction(self.alpha_transfer) # Surface mapper self.surface_mapper = vtk.vtkPolyDataMapper() self.surface_mapper.SetLookupTable(self.color_transfer) self.surface_mapper.SetInputConnection(smooth.GetOutputPort()) # Create the actor self.actor = vtk.vtkActor() self.actor.GetProperty().SetOpacity(1.) self.actor.SetMapper(self.surface_mapper) self.actor.GetProperty().ShadingOn()
def createThresholdMesh2(mask, threshold1, threshold2): mesh = vtk.vtkDiscreteMarchingCubes() mesh.SetInputData(mask) # mesh.SetValue(threshold1,threshold2) mesh.GenerateValues(threshold2 - threshold1 + 1, threshold1, threshold2) mesh.Update() return mesh.GetOutput()
def main(args): img_fn_array = [] if args.image: img_obj = {} img_obj["img"] = args.image img_obj["out"] = args.out img_fn_array.append(img_obj) elif args.dir: normpath = os.path.normpath("/".join([args.dir, '**', '*'])) for img_fn in glob.iglob(normpath, recursive=True): if os.path.isfile(img_fn) and True in [ ext in img_fn for ext in [".nrrd"] ]: img_obj = {} img_obj["img"] = img_fn img_obj["out"] = os.path.normpath("/".join([args.out])) img_fn_array.append(img_obj) for img_obj in img_fn_array: image = img_obj["img"] out = img_obj["out"] print("Reading:", image) surf = vtk.vtkNrrdReader() surf.SetFileName(image) surf.Update() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(surf.GetOutputPort()) dmc.GenerateValues(100, 1, 100) # LAPLACIAN smooth SmoothPolyDataFilter = vtk.vtkSmoothPolyDataFilter() SmoothPolyDataFilter.SetInputConnection(dmc.GetOutputPort()) SmoothPolyDataFilter.SetNumberOfIterations(10) SmoothPolyDataFilter.SetFeatureAngle(120.0) SmoothPolyDataFilter.SetRelaxationFactor(0.6) SmoothPolyDataFilter.Update() # SINC smooth # smoother = vtk.vtkWindowedSincPolyDataFilter() # smoother.SetInputConnection(dmc.GetOutputPort()) # smoother.SetNumberOfIterations(30) # smoother.BoundarySmoothingOff() # smoother.FeatureEdgeSmoothingOff() # smoother.SetFeatureAngle(120.0) # smoother.SetPassBand(0.001) # smoother.NonManifoldSmoothingOn() # smoother.NormalizeCoordinatesOn() # smoother.Update() outputFilename = out + "/" + os.path.splitext( os.path.basename(image))[0] + ".vtk" Write(SmoothPolyDataFilter.GetOutput(), outputFilename)
def discreteMarchingCubes(volume) -> pv.PolyData: # use discrete marching cube algorithm dm = vtk.vtkDiscreteMarchingCubes() dm.SetInputData(volume) dm.ComputeNormalsOn() dm.GenerateValues(1, 0, 255) dm.Update() mesh = dm.GetOutput() mesh = pv.wrap(mesh) return mesh
def create_mask_extractor(mask): """ Given the output from mask (vtkNIFTIImageReader) extract it into 3D using vtkDiscreteMarchingCubes algorithm (https://www.vtk.org/doc/release/5.0/html/a01331.html). This algorithm is specialized for reading segmented volume labels. :param mask: a vtkNIFTIImageReader volume containing the mask :return: the extracted volume from vtkDiscreteMarchingCubes """ mask_extractor = vtk.vtkDiscreteMarchingCubes() mask_extractor.SetInputConnection(mask.reader.GetOutputPort()) return mask_extractor
def niftiMask2Surface(img_path, surf_name, smooth_iter=10, filetype="vtk"): # import the binary nifti image reader = vtk.vtkNIFTIImageReader() reader.SetFileName(img_path) reader.Update() # do marching cubes to create a surface surface = vtk.vtkDiscreteMarchingCubes() surface.SetInputConnection(reader.GetOutputPort()) # GenerateValues(number of surfaces, label range start, label range end) surface.GenerateValues(1, 1, 1) surface.Update() smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(surface.GetOutputPort()) smoother.SetNumberOfIterations(smooth_iter) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() connectivityFilter = vtk.vtkPolyDataConnectivityFilter() connectivityFilter.SetInputConnection(smoother.GetOutputPort()) connectivityFilter.SetExtractionModeToLargestRegion() connectivityFilter.Update() cleaned = vtk.vtkCleanPolyData() cleaned.SetInputConnection(connectivityFilter.GetOutputPort()) cleaned.Update() # doesn't work, but may need in future # close_holes = vtk.vtkFillHolesFilter() # close_holes.SetInputConnection(smoother.GetOutputPort()) # close_holes.SetHoleSize(10) # close_holes.Update() if filetype == "stl": writer = vtk.vtkSTLWriter() writer.SetInputConnection(cleaned.GetOutputPort()) writer.SetFileTypeToASCII() writer.SetFileName(surf_name) writer.Write() if filetype == "ply": writer = vtk.vtkPLYWriter() writer.SetInputConnection(cleaned.GetOutputPort()) writer.SetFileTypeToASCII() writer.SetFileName(surf_name) writer.Write() if filetype == "vtk": writer = vtk.vtkPolyDataWriter() #writer = vtk.vtkDataSetWriter() writer.SetInputConnection(cleaned.GetOutputPort()) writer.SetFileName(surf_name) writer.Write()
def __init__(self, img, threshold, xysmoothing, zsmoothing, color, alpha): dataImporter = vtk.vtkImageImport() simg = np.ascontiguousarray(img, np.uint8) dataImporter.CopyImportVoidPointer(simg.data, len(simg.data)) dataImporter.SetDataScalarTypeToUnsignedChar() dataImporter.SetNumberOfScalarComponents(1) dataImporter.SetDataExtent(0, simg.shape[2]-1, 0, simg.shape[1]-1, 0, simg.shape[0]-1) dataImporter.SetWholeExtent(0, simg.shape[2]-1, 0, simg.shape[1]-1, 0, simg.shape[0]-1) self.__smoother = vtk.vtkImageGaussianSmooth() self.__smoother.SetStandardDeviation(xysmoothing, xysmoothing, zsmoothing) self.__smoother.SetInputConnection(dataImporter.GetOutputPort()) self.__threshold = vtk.vtkImageThreshold() self.__threshold.SetInputConnection(self.__smoother.GetOutputPort()) self.__threshold.ThresholdByUpper(threshold) self.__threshold.ReplaceInOn() self.__threshold.SetInValue(1) self.__threshold.ReplaceOutOn() self.__threshold.SetOutValue(0) self.__threshold.Update() contour = vtk.vtkDiscreteMarchingCubes() contour.SetInputConnection(self.__threshold.GetOutputPort()) contour.ComputeNormalsOn() contour.SetValue(0, 1) contour.Update() smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(contour.GetOutputPort()) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() triangleCellNormals=vtk.vtkPolyDataNormals() triangleCellNormals.SetInputConnection(smoother.GetOutputPort()) triangleCellNormals.ComputeCellNormalsOn() triangleCellNormals.ComputePointNormalsOff() triangleCellNormals.ConsistencyOn() triangleCellNormals.AutoOrientNormalsOn() triangleCellNormals.Update() triangleCellAn = vtk.vtkMeshQuality() triangleCellAn.SetInputConnection(triangleCellNormals.GetOutputPort()) triangleCellAn.SetTriangleQualityMeasureToArea() triangleCellAn.SaveCellQualityOn() triangleCellAn.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(triangleCellAn.GetOutputPort()) mapper.ScalarVisibilityOn() mapper.SetScalarRange(.3, 1) mapper.SetScalarModeToUsePointData() colorLookupTable = vtk.vtkLookupTable() colorLookupTable.SetHueRange(.6, 1) colorLookupTable.Build() mapper.SetLookupTable(colorLookupTable) self.SetMapper(mapper) self.GetProperty().SetColor(*color) self.GetProperty().SetOpacity(alpha)
def treesOfNodes(*nodes): trees = [] for node in nodes: mesh = vtk.vtkDiscreteMarchingCubes() mesh.SetInputData(node.GetImageData()) mesh.Update() polyData = mesh.GetOutput() tree = vtk.vtkCellLocator() tree.SetDataSet(polyData) tree.BuildLocator() trees.append(tree) return trees
def _labelmapToPolydata(labelmap, value=1): discreteCubes = vtk.vtkDiscreteMarchingCubes() discreteCubes.SetInputData(labelmap) discreteCubes.SetValue(0, value) reverse = vtk.vtkReverseSense() reverse.SetInputConnection(discreteCubes.GetOutputPort()) reverse.ReverseCellsOn() reverse.ReverseNormalsOn() reverse.Update() return reverse.GetOutput()
def main(): n = 20 radius = 8 blob = make_blob(n, radius) discrete = vtk.vtkDiscreteMarchingCubes() discrete.SetInputData(blob) discrete.GenerateValues(n, 1, n) smoothing_iterations = 15 pass_band = 0.001 feature_angle = 120.0 smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(discrete.GetOutputPort()) smoother.SetNumberOfIterations(smoothing_iterations) smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(feature_angle) smoother.SetPassBand(pass_band) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() lut = make_colors(n) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(smoother.GetOutputPort()) mapper.SetLookupTable(lut) mapper.SetScalarRange(0, lut.GetNumberOfColors()) # Create the RenderWindow, Renderer and both Actors # ren = vtk.vtkRenderer() ren_win = vtk.vtkRenderWindow() ren_win.AddRenderer(ren) ren_win.SetWindowName('SmoothDiscreteMarchingCubes') iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(ren_win) actor = vtk.vtkActor() actor.SetMapper(mapper) ren.AddActor(actor) colors = vtk.vtkNamedColors() ren.SetBackground(colors.GetColor3d('Burlywood')) ren_win.Render() iren.Start()
def convert_label_map_to_surface(label_name, output_file): print('Converting', label_name) reader = vtk.vtkNIFTIImageReader() reader.SetFileName(label_name) reader.Update() mc = vtk.vtkDiscreteMarchingCubes() mc.SetInputConnection(reader.GetOutputPort()) mc.SetNumberOfContours(1) mc.SetValue(0, 1) mc.Update() # Hacky way to get real size of image (for some reason the vtk image is incorrect) image_itk = sitk.Cast(sitk.ReadImage(label_name), sitk.sitkFloat32) origin = image_itk.GetOrigin() size = image_itk.GetSize() spacing = image_itk.GetSpacing() # Transform surface to fit in coordinate system # 6/4-2020 these transformations are found by trial and error... rotate = vtk.vtkTransform() # rotate.RotateY(180) rotate.RotateZ(180) rotate.RotateX(180) translate = vtk.vtkTransform() rotate_filter = vtk.vtkTransformFilter() rotate_filter.SetInputConnection(mc.GetOutputPort()) rotate_filter.SetTransform(rotate) rotate_filter.Update() # 6/4-2020 these transformations are found by trial and error... t_x, t_y, t_z = -origin[0], -origin[1], origin[2] + spacing[2] * size[2] translate.Translate(t_x, t_y, t_z) translate_filter = vtk.vtkTransformFilter() translate_filter.SetInputData(rotate_filter.GetOutput()) translate_filter.SetTransform(translate) translate_filter.Update() norms = vtk.vtkPolyDataNormals() norms.SetInputConnection(translate_filter.GetOutputPort()) norms.SetFlipNormals(True) norms.SetSplitting(False) writer = vtk.vtkPolyDataWriter() writer.SetInputConnection(norms.GetOutputPort()) writer.SetFileTypeToBinary() writer.SetFileName(output_file) writer.Write()
def stl_writer(filename, stack, spacing, dcm_folder): ###### filename: the file name of the output ".stl" ####### ###### stack: the volume of 3D ndarray #################### ###### spacing: resolution of raw data #################### DEBUG = False RElAXATIONFACTOR = 0.03 ITERATIONS = 100 stack = stack.transpose(0, 1, 2) stack[stack >= 0.5] = 1.0 stack[stack <= 0.5] = 0.0 stack = stack * 255 stack = np.require(stack, dtype=np.uint8) data_string = stack.tostring() #### 转换成vtk-image的形式,调用vtkImageImport类 ############ dataImporter = vtk.vtkImageImport() dataImporter.CopyImportVoidPointer(data_string, len(data_string)) dataImporter.SetDataScalarTypeToUnsignedChar() dataImporter.SetNumberOfScalarComponents(1) #### importer数据只有灰度信息,不是rgb之类的 #### vtk uses an array in the order : height, depth, width which is different of numpy (w,h,d) w, d, h = stack.shape dataImporter.SetWholeExtent(0, h - 1, 0, d - 1, 0, w - 1) dataImporter.SetDataExtent(0, h - 1, 0, d - 1, 0, w - 1) dataImporter.SetDataSpacing(spacing[2], spacing[1], spacing[0]) # dataImporter.SetWholeExtent(0, h-1, 0, d-1, 0, w-1) reader = vtk.vtkDICOMImageReader() reader.SetDirectoryName(dcm_folder) reader.Update() dcmImagePosition = reader.GetImagePositionPatient() dataImporter.SetDataOrigin(dcmImagePosition) threshold = vtk.vtkImageThreshold() threshold.SetInputConnection(dataImporter.GetOutputPort()) threshold.ThresholdByLower(128) threshold.ReplaceInOn() threshold.SetInValue(0) threshold.ReplaceOutOn() threshold.SetOutValue(1) threshold.Update() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(threshold.GetOutputPort()) dmc.GenerateValues(1, 1, 1) dmc.Update() smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(dmc.GetOutputPort()) smooth.SetRelaxationFactor(RElAXATIONFACTOR) smooth.SetNumberOfIterations(ITERATIONS) writer = vtk.vtkSTLWriter() writer.SetInputConnection(smooth.GetOutputPort()) writer.SetFileTypeToBinary() writer.SetFileName(filename) writer.Write()
def labels2meshes_vtk(surfdir, compdict, labelimage, labels=[], spacing=[1, 1, 1], offset=[0, 0, 0]): """Generate meshes from a labelimage with vtk marching cubes.""" labelimage = np.lib.pad(labelimage.tolist(), ((1, 1), (1, 1), (1, 1)), 'constant') dims = labelimage.shape vol = vtk.vtkImageData() vol.SetDimensions(dims[0], dims[1], dims[2]) vol.SetOrigin(offset[0] * spacing[0] + spacing[0], offset[1] * spacing[1] + spacing[1], offset[2] * spacing[2] + spacing[2]) # vol.SetOrigin(0, 0, 0) vol.SetSpacing(spacing[0], spacing[1], spacing[2]) sc = vtk.vtkFloatArray() sc.SetNumberOfValues(labelimage.size) sc.SetNumberOfComponents(1) sc.SetName('tnf') for ii, val in enumerate(np.ravel(labelimage.swapaxes(0, 2))): # FIXME: why swapaxes??? zyx => xyz? sc.SetValue(ii, val) vol.GetPointData().SetScalars(sc) dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputData( vol ) # dmc.SetInput(vol) # FIXME: dmc.SetInputData(vol) for newer vtk versions (>5.1?) dmc.ComputeNormalsOn() for label in labels: try: labelname = compdict[label]['name'] except (IndexError, KeyError): print("Skipping label {:05d}".format(label)) else: fpath = os.path.join(surfdir, '{}.stl'.format(labelname)) print("Processing label {:05d} ({})".format(label, labelname)) dmc.SetValue(0, label) dmc.Update() writer = vtk.vtkSTLWriter() writer.SetInputConnection(dmc.GetOutputPort()) writer.SetFileName(fpath) writer.Write()
def generate_mesh(imgbinitk): sitk.WriteImage( imgbinitk,'label_cleaned_tmp.mha') reader=vtk.vtkMetaImageReader() reader.SetFileName('label_cleaned_tmp.mha') reader.Update() imgbin=reader.GetOutput() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputData(imgbin) dmc.ComputeNormalsOn() dmc.GenerateValues(1, 1, 1) dmc.Update() meshout=dmc.GetOutput() #DisplayVTKMesh(meshout,"mesh from marchin cubes") return meshout
def __init__(self, parent, visualizer, **kws): """ Initialization """ self.init = False VisualizationModule.__init__(self, parent, visualizer, numberOfInputs=(2, 2), **kws) # self.name = "Surface Rendering" self.normals = vtk.vtkPolyDataNormals() self.smooth = None self.volumeModule = None self.scalarRange = (0, 255) for i in range(1, 3): self.setInputChannel(i, i) self.eventDesc = "Rendering iso-surface" self.decimate = vtk.vtkDecimatePro() self.mapper = vtk.vtkPolyDataMapper() self.mapper2 = vtk.vtkPolyDataMapper() self.contour = vtk.vtkMarchingCubes() self.contour2 = vtk.vtkDiscreteMarchingCubes() self.descs = { "Normals": "Smooth surface with normals", "FeatureAngle": "Feature angle of normals\n", "Simplify": "Simplify surface", "PreserveTopology": "Preserve topology", "Transparency": "Surface transparency", "Distance": "Distance to consider inside", "MarkColor": "Mark in/outside objects with colors", } self.actor = self.lodActor = vtk.vtkLODActor() self.lodActor.SetMapper(self.mapper) self.lodActor.SetNumberOfCloudPoints(10000) self.actor2 = vtk.vtkLODActor() self.actor2.SetMapper(self.mapper2) self.actor2.SetNumberOfCloudPoints(10000) self.renderer = self.parent.getRenderer() self.renderer.AddActor(self.lodActor) self.renderer.AddActor(self.actor2) lib.messenger.connect(None, "highlight_object", self.onHighlightObject)
def process_image(self, image): dims = image.shape width = dims[1] height = dims[2] depth = dims[0] vtk_data = numpy_support.numpy_to_vtk(num_array=image.ravel(), deep=True, array_type=vtk.VTK_FLOAT) imgdat = vtk.vtkImageData() imgdat.GetPointData().SetScalars(vtk_data) imgdat.SetDimensions(height, width, depth) imgdat.SetOrigin(0, 0, 0) spacing = self.image_processing.spacing imgdat.SetSpacing(spacing[0], spacing[1], spacing[2]) dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputData(imgdat) dmc.GenerateValues(1, 1, 1) dmc.Update() smoothing_iterations = 15 pass_band = 0.001 feature_angle = 120.0 smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(dmc.GetOutputPort()) smoother.SetNumberOfIterations(smoothing_iterations) smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(feature_angle) smoother.SetPassBand(pass_band) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(smoother.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) return actor
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())
thres.SetInValue(expr.expr(globals(), locals(),["i","+","1"])) thres.SetOutValue(0) thres.Update() if (i == 0): blobImage.DeepCopy(thres.GetOutput()) pass catch.catch(globals(),"""maxValue = vtk.vtkImageMathematics()""") maxValue.SetInputData(0,blobImage) maxValue.SetInputData(1,thres.GetOutput()) maxValue.SetOperationToMax() maxValue.Modified() maxValue.Update() blobImage.DeepCopy(maxValue.GetOutput()) i = i + 1 discrete = vtk.vtkDiscreteMarchingCubes() discrete.SetInputData(blobImage) discrete.GenerateValues(n,1,n) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(discrete.GetOutputPort()) mapper.SetLookupTable(lut) mapper.SetScalarRange(0,lut.GetNumberOfColors()) actor = vtk.vtkActor() actor.SetMapper(mapper) ren1.AddActor(actor) renWin.Render() # render the image # # prevent the tk window from showing up then start the event loop # --- end of script --
def image_to_vtk_cell_polydata(img,considered_cells=None,mesh_center=None,coef=1.0,mesh_fineness=1.0,smooth_factor=1.0): start_time = time() print "--> Generating vtk mesh from image" vtk_mesh = vtk.vtkPolyData() vtk_points = vtk.vtkPoints() vtk_triangles = vtk.vtkCellArray() vtk_cells = vtk.vtkLongArray() nx, ny, nz = img.shape data_string = img.tostring('F') reader = vtk.vtkImageImport() reader.CopyImportVoidPointer(data_string, len(data_string)) if img.dtype == np.uint8: reader.SetDataScalarTypeToUnsignedChar() else: reader.SetDataScalarTypeToUnsignedShort() reader.SetNumberOfScalarComponents(1) reader.SetDataExtent(0, nx - 1, 0, ny - 1, 0, nz - 1) reader.SetWholeExtent(0, nx - 1, 0, ny - 1, 0, nz - 1) reader.SetDataSpacing(*img.resolution) reader.Update() if considered_cells is None: considered_cells = np.unique(img)[1:] if mesh_center is None: #mesh_center = np.array(img.resolution)*np.array(img.shape)/2. mesh_center = np.array([0,0,0]) for label in considered_cells: cell_start_time = time() cell_volume = (img==label).sum()*np.array(img.resolution).prod() # mask_data = vtk.vtkImageThreshold() # mask_data.SetInputConnection(reader.GetOutputPort()) # mask_data.ThresholdBetween(label, label) # mask_data.ReplaceInOn() # mask_data.SetInValue(label) # mask_data.SetOutValue(0) contour = vtk.vtkDiscreteMarchingCubes() # contour.SetInput(mask_data.GetOutput()) SetInput(contour,reader.GetOutput()) contour.ComputeNormalsOn() contour.ComputeGradientsOn() contour.SetValue(0,label) contour.Update() # print " --> Marching Cubes : ",contour.GetOutput().GetPoints().GetNumberOfPoints()," Points,",contour.GetOutput().GetNumberOfCells()," Triangles, 1 Cell" # decimate = vtk.vtkDecimatePro() # decimate.SetInputConnection(contour.GetOutputPort()) # # decimate.SetTargetReduction(0.75) # decimate.SetTargetReduction(0.66) # # decimate.SetTargetReduction(0.5) # # decimate.SetMaximumError(2*np.sqrt(3)) # decimate.Update() smooth_iterations = int(np.ceil(smooth_factor*8.)) smoother = vtk.vtkWindowedSincPolyDataFilter() SetInput(smoother,contour.GetOutput()) smoother.BoundarySmoothingOn() # smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOn() # smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(120.0) # smoother.SetPassBand(1) smoother.SetPassBand(0.01) smoother.SetNumberOfIterations(smooth_iterations) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() divisions = int(np.ceil(np.power(cell_volume,1/3.)*mesh_fineness)) decimate = vtk.vtkQuadricClustering() # decimate = vtk.vtkQuadricDecimation() # decimate = vtk.vtkDecimatePro() # decimate.SetInput(contour.GetOutput()) SetInput(decimate,smoother.GetOutput()) # decimate.SetTargetReduction(0.95) # decimate.AutoAdjustNumberOfDivisionsOff() decimate.SetNumberOfDivisions(divisions,divisions,divisions) decimate.SetFeaturePointsAngle(120.0) # decimate.AttributeErrorMetricOn() # decimate.ScalarsAttributeOn() # decimate.PreserveTopologyOn() # decimate.CopyCellDataOn() # decimate.SetMaximumCost(1.0) # decimate.SetMaximumCollapsedEdges(10000.0) decimate.Update() # print " --> Decimation : ",decimate.GetOutput().GetPoints().GetNumberOfPoints()," Points,",decimate.GetOutput().GetNumberOfCells()," Triangles, 1 Cell" cell_polydata = decimate.GetOutput() # cell_polydata = smoother.GetOutput() polydata_points = np.array([cell_polydata.GetPoints().GetPoint(p) for p in xrange(cell_polydata.GetPoints().GetNumberOfPoints())]) polydata_center = polydata_points.mean(axis=0) polydata_points = polydata_center + coef*(polydata_points-polydata_center) - mesh_center cell_points = [] for p in xrange(cell_polydata.GetPoints().GetNumberOfPoints()): pid = vtk_points.InsertNextPoint(polydata_points[p]) cell_points.append(pid) cell_points = array_dict(cell_points,np.arange(cell_polydata.GetPoints().GetNumberOfPoints())) for t in xrange(cell_polydata.GetNumberOfCells()): poly = vtk_triangles.InsertNextCell(3) for i in xrange(3): pid = cell_polydata.GetCell(t).GetPointIds().GetId(i) vtk_triangles.InsertCellPoint(cell_points[pid]) vtk_cells.InsertValue(poly,label) cell_end_time = time() print " --> Cell",label,":",decimate.GetOutput().GetNumberOfCells(),"triangles (",cell_volume," microm3 ) [",cell_end_time-cell_start_time,"s]" vtk_mesh.SetPoints(vtk_points) vtk_mesh.SetPolys(vtk_triangles) vtk_mesh.GetCellData().SetScalars(vtk_cells) print " <-- Cell Mesh : ",vtk_mesh.GetPoints().GetNumberOfPoints()," Points,",vtk_mesh.GetNumberOfCells()," Triangles, ",len(considered_cells)," Cells" end_time = time() print "<-- Generating vtk mesh from image [",end_time-start_time,"s]" return vtk_mesh
def image_to_vtk_polydata(img,considered_cells=None,mesh_center=None,coef=1.0,mesh_fineness=1.0): start_time = time() print "--> Generating vtk mesh from image" vtk_mesh = vtk.vtkPolyData() vtk_points = vtk.vtkPoints() vtk_triangles = vtk.vtkCellArray() vtk_cells = vtk.vtkLongArray() nx, ny, nz = img.shape data_string = img.tostring('F') reader = vtk.vtkImageImport() reader.CopyImportVoidPointer(data_string, len(data_string)) if img.dtype == np.uint8: reader.SetDataScalarTypeToUnsignedChar() else: reader.SetDataScalarTypeToUnsignedShort() reader.SetNumberOfScalarComponents(1) reader.SetDataExtent(0, nx - 1, 0, ny - 1, 0, nz - 1) reader.SetWholeExtent(0, nx - 1, 0, ny - 1, 0, nz - 1) reader.SetDataSpacing(*img.resolution) if considered_cells is None: considered_cells = np.unique(img)[1:] if mesh_center is None: mesh_center = np.array(img.resolution)*np.array(img.shape)/2. marching_cube_start_time = time() print " --> Marching Cubes" contour = vtk.vtkDiscreteMarchingCubes() SetInput(contour,reader.GetOutput()) contour.ComputeNormalsOn() contour.ComputeGradientsOn() contour.ComputeScalarsOn() for i,label in enumerate(considered_cells): contour.SetValue(i,label) contour.Update() marching_cube_end_time = time() print " <-- Marching Cubes : ",contour.GetOutput().GetPoints().GetNumberOfPoints()," Points,",contour.GetOutput().GetNumberOfCells()," Triangles, ",len(np.unique(img)[1:])," Cells [",marching_cube_end_time - marching_cube_start_time,"s]" marching_cubes = contour.GetOutput() marching_cubes_cell_data = marching_cubes.GetCellData().GetArray(0) triangle_cell_start_time = time() print " --> Listing triangles" print " - ",marching_cubes.GetNumberOfCells()," triangles" marching_cubes_triangles = np.sort([[marching_cubes.GetCell(t).GetPointIds().GetId(i) for i in xrange(3)] for t in xrange(marching_cubes.GetNumberOfCells())]) triangle_cell_end_time = time() print " <-- Listing triangles [",triangle_cell_end_time - triangle_cell_start_time,"s]" triangle_cell_start_time = time() print " --> Listing triangle cells" triangle_cell = np.array([marching_cubes_cell_data.GetTuple(t)[0] for t in xrange(marching_cubes.GetNumberOfCells())],np.uint16) triangle_cell_end_time = time() print " <-- Listing triangle cells [",triangle_cell_end_time - triangle_cell_start_time,"s]" triangle_cell_start_time = time() print " --> Updating marching cubes mesh" vtk_mesh = vtk.vtkPolyData() vtk_points = vtk.vtkPoints() vtk_triangles = vtk.vtkCellArray() vtk_cells = vtk.vtkLongArray() for label in considered_cells: # cell_start_time = time() cell_marching_cubes_triangles = marching_cubes_triangles[np.where(triangle_cell == label)] marching_cubes_point_ids = np.unique(cell_marching_cubes_triangles) marching_cubes_points = np.array([marching_cubes.GetPoints().GetPoint(p) for p in marching_cubes_point_ids]) marching_cubes_center = marching_cubes_points.mean(axis=0) marching_cubes_points = marching_cubes_center + coef*(marching_cubes_points-marching_cubes_center) - mesh_center cell_points = [] for p in xrange(marching_cubes_points.shape[0]): pid = vtk_points.InsertNextPoint(marching_cubes_points[p]) cell_points.append(pid) cell_points = array_dict(cell_points,marching_cubes_point_ids) for t in xrange(cell_marching_cubes_triangles.shape[0]): poly = vtk_triangles.InsertNextCell(3) for i in xrange(3): pid = cell_marching_cubes_triangles[t][i] vtk_triangles.InsertCellPoint(cell_points[pid]) vtk_cells.InsertValue(poly,label) # cell_end_time = time() # print " --> Cell",label,":",cell_marching_cubes_triangles.shape[0],"triangles [",cell_end_time-cell_start_time,"s]" vtk_mesh.SetPoints(vtk_points) vtk_mesh.SetPolys(vtk_triangles) vtk_mesh.GetCellData().SetScalars(vtk_cells) triangle_cell_end_time = time() print " <-- Updating marching cubes mesh [",triangle_cell_end_time - triangle_cell_start_time,"s]" decimation_start_time = time() print " --> Decimation" smoother = vtk.vtkWindowedSincPolyDataFilter() SetInput(smoother,vtk_mesh) smoother.SetFeatureAngle(30.0) smoother.SetPassBand(0.05) smoother.SetNumberOfIterations(25) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() decimate = vtk.vtkQuadricClustering() SetInput(decimate,smoother.GetOutput()) decimate.SetNumberOfDivisions(*tuple(mesh_fineness*np.array(np.array(img.shape)*np.array(img.resolution)/2.,np.uint16))) decimate.SetFeaturePointsAngle(30.0) decimate.CopyCellDataOn() decimate.Update() decimation_end_time = time() print " <-- Decimation : ",decimate.GetOutput().GetPoints().GetNumberOfPoints()," Points,",decimate.GetOutput().GetNumberOfCells()," Triangles, ",len(considered_cells)," Cells [",decimation_end_time - decimation_start_time,"s]" end_time = time() print "<-- Generating vtk mesh from image [",end_time-start_time,"s]" return decimate.GetOutput()
def init_cell_field_actors_borderless(self, actor_specs, drawing_params=None): hex_flag = False lattice_type_str = self.get_lattice_type_str() if lattice_type_str.lower() == 'hexagonal': hex_flag = True # todo 5 - check if this should be called earlier # self.extractCellFieldData() # initializes self.usedCellTypesList field_dim = self.currentDrawingParameters.bsd.fieldDim cell_type_image_data = vtk.vtkImageData() cell_type_image_data.SetDimensions(field_dim.x + 2, field_dim.y + 2, field_dim.z + 2) # adding 1 pixel border around the lattice to make rendering smooth at lattice borders cell_type_image_data.GetPointData().SetScalars(self.cell_type_array) voi = vtk.vtkExtractVOI() if VTK_MAJOR_VERSION >= 6: voi.SetInputData(cell_type_image_data) else: voi.SetInput(cell_type_image_data) # voi.SetVOI(1,self.dim[0]-1, 1,self.dim[1]-1, 1,self.dim[2]-1 ) # crop out the artificial boundary layer that we created voi.SetVOI(0, 249, 0, 189, 0, 170) # # todo 5- check if it is possible to call it once # self.usedCellTypesList = self.extractCellFieldData() number_of_actors = len(self.used_cell_types_list) # creating and initializing filters, smoothers and mappers - one for each cell type filterList = [vtk.vtkDiscreteMarchingCubes() for i in xrange(number_of_actors)] smootherList = [vtk.vtkSmoothPolyDataFilter() for i in xrange(number_of_actors)] normalsList = [vtk.vtkPolyDataNormals() for i in xrange(number_of_actors)] mapperList = [vtk.vtkPolyDataMapper() for i in xrange(number_of_actors)] # actorCounter=0 # for i in usedCellTypesList: for actorCounter, actor_number in enumerate(self.used_cell_types_list): # for actorCounter in xrange(len(self.usedCellTypesList)): if VTK_MAJOR_VERSION >= 6: filterList[actorCounter].SetInputData(cell_type_image_data) else: filterList[actorCounter].SetInput(cell_type_image_data) # filterList[actorCounter].SetInputConnection(voi.GetOutputPort()) # filterList[actorCounter].SetValue(0, usedCellTypesList[actorCounter]) filterList[actorCounter].SetValue(0, self.used_cell_types_list[actorCounter]) smootherList[actorCounter].SetInputConnection(filterList[actorCounter].GetOutputPort()) # smootherList[actorCounter].SetNumberOfIterations(200) normalsList[actorCounter].SetInputConnection(smootherList[actorCounter].GetOutputPort()) normalsList[actorCounter].SetFeatureAngle(45.0) mapperList[actorCounter].SetInputConnection(normalsList[actorCounter].GetOutputPort()) mapperList[actorCounter].ScalarVisibilityOff() actors_dict = actor_specs.actors_dict cell_type_lut = self.get_type_lookup_table() cell_type_lut_max = cell_type_lut.GetNumberOfTableValues() - 1 if actor_number in actors_dict.keys(): actor = actors_dict[actor_number] actor.SetMapper(mapperList[actorCounter]) actor.GetProperty().SetDiffuseColor( cell_type_lut.GetTableValue(self.used_cell_types_list[actorCounter])[0:3]) # actor.GetProperty().SetDiffuseColor( # # self.celltypeLUT.GetTableValue(self.usedCellTypesList[actorCounter])[0:3]) # self.celltypeLUT.GetTableValue(actor_number)[0:3]) if hex_flag: actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex)
voi.SetInput(reader_volume.GetOutput()) else: voi.SetInputConnection(reader_volume.GetOutputPort()) #voi.SetVOI(0,517, 0,228, 0,392) voi.SetSampleRate(1, 1, 1) #voi.SetSampleRate(3, 3, 3) voi.Update() # necessary for GetScalarRange() srange = voi.GetOutput().GetScalarRange() # needs Update() before! print("Range", srange) ##Prepare surface generation #contour = vtk.vtkContourFilter() #contour = vtk.vtkMarchingCubes() contour = vtk.vtkDiscreteMarchingCubes() #for label images if vtk.VTK_MAJOR_VERSION <= 5: contour.SetInput(voi.GetOutput()) else: contour.SetInputConnection(voi.GetOutputPort()) contour.ComputeNormalsOn() ##run through all labels for index in range(1, int(srange[1]) + 1): print("Doing label", index) contour.SetValue(0, index) contour.Update() #needed for GetNumberOfPolys() !!! smoother = vtk.vtkWindowedSincPolyDataFilter()
#only handle some surfaces #if label_id < 1000 or label_id > 2036: # continue if not label_id in unique: continue surf_name=label['label']+'.'+label['name']+'.vtk' label["filename"] = surf_name print(surf_name) #label["label"] = label_id index.append(label) # do marching cubes to create a surface surface = vtk.vtkDiscreteMarchingCubes() surface.SetInputConnection(reader.GetOutputPort()) # GenerateValues(number of surfaces, label range start, label range end) surface.GenerateValues(1, label_id, label_id) surface.Update() #print(surface) smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(surface.GetOutputPort()) smoother.SetNumberOfIterations(10) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() smoother.Update() connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
def __init__(self, electrode_data): def __pca(A): """ Principal Component Analaysis """ # Get Dimensions num_data, dim = A.shape # Center data mean_A = A.mean(axis=0) for i in range(num_data): A[i] -= mean_A u,s,v = np.linalg.svd(A) normPos = s.argmin() return v[:, normPos] """ Setup Surface Rendering """ # Apply a discrete marching cubes algorithm to extract segmented # surface contours with incremental values self.electrodeExtractor = vtk.vtkDiscreteMarchingCubes() self.electrodeExtractor.SetInput(electrode_data.GetOutput()) self.electrodeExtractor.GenerateValues(1,\ np.min(electrode_data.GetArray()),\ np.max(electrode_data.GetArray())) self.electrodeMapper = vtk.vtkPolyDataMapper() self.electrodeMapper.SetInputConnection(\ self.electrodeExtractor.GetOutputPort()) self.electrodeMapper.ScalarVisibilityOff() self.electrodeProperty = vtk.vtkProperty() self.electrodeProperty.SetColor(1.0, 0.5, 0.0) self.SetMapper(self.electrodeMapper) self.SetProperty(self.electrodeProperty) self.electrodeExtractor.Update() self.grid = vtk.vtkAssembly() self.electrodePolyData = vtk.vtkPolyData() electrodePoints = vtk.vtkPoints() ePointMat = np.mat(np.zeros(shape = (36, 3))) chanIdx = 0 for segLabel in np.unique(electrode_data.GetArray()): # This is hacked for MAYO34 in order to show just the 6x6 grid sphere = vtk.vtkSphereSource() sphere.SetRadius(2) sphereMap = vtk.vtkPolyDataMapper() sphereMap.SetInput(sphere.GetOutput()) if (segLabel > 0 and segLabel < 37): x,y,z = np.nonzero(electrode_data.GetArray() == segLabel) nx = 0.9375*np.mean(z) ny = 0.9375*np.mean(y) nz = 1.5*np.mean(x) ePointMat[chanIdx] = [nx, ny, nz] chanIdx = chanIdx + 1 normalVector = __pca(ePointMat.copy()) for chan in range(chanIdx): xx = ePointMat[chan, 0] yy = ePointMat[chan, 1] zz = ePointMat[chan, 2] sphereActor = vtk.vtkOpenGLActor() sphereActor.SetMapper(sphereMap) sphereActor.GetProperty().SetColor(1.0, 0.0, 1.0) sphereActor.SetPosition(xx - 0 * normalVector[0],\ yy - 0 * normalVector[1],\ zz - 0 * normalVector[2]) electrodePoints.InsertNextPoint(xx - 0 * normalVector[0],\ yy - 0 * normalVector[1],\ zz - 0 * normalVector[2]) self.grid.AddPart(sphereActor) self.electrodePolyData.SetPoints(electrodePoints) self.GridSurface()
def init_cell_field_borders_actors(self, actor_specs, drawing_params=None): """ initializes cell field actors where each cell is rendered individually as a separate spatial domain :param actor_specs: {ActorSpecs} :param drawing_params: {DrawingParameters} :return: None """ field_dim = self.currentDrawingParameters.bsd.fieldDim hex_flag = False lattice_type_str = self.get_lattice_type_str() # if lattice_type_str.lower() == 'hexagonal': # hex_flag = True hex_flag = self.is_lattice_hex(drawing_params=drawing_params) cell_type_image_data = vtk.vtkImageData() # adding 1 pixel border around the lattice to make rendering smooth at lattice borders cell_type_image_data.SetDimensions(field_dim.x + 2, field_dim.y + 2, field_dim.z + 2) cell_type_image_data.GetPointData().SetScalars(self.cell_id_array) # create a different actor for each cell type number_of_actors = len(self.used_cell_types_list) # creating and initializing filters, smoothers and mappers - one for each cell type filter_list = [vtk.vtkDiscreteMarchingCubes() for i in xrange(number_of_actors)] smoother_list = [vtk.vtkSmoothPolyDataFilter() for i in xrange(number_of_actors)] normals_list = [vtk.vtkPolyDataNormals() for i in xrange(number_of_actors)] mapper_list = [vtk.vtkPolyDataMapper() for i in xrange(number_of_actors)] for actor_counter, actor_number in enumerate(self.used_cell_types_list): if VTK_MAJOR_VERSION >= 6: filter_list[actor_counter].SetInputData(cell_type_image_data) else: filter_list[actor_counter].SetInput(cell_type_image_data) if self.used_cell_types_list[actor_counter] >= 1: ct_all = vtk_to_numpy(self.cell_type_array) cid_all = vtk_to_numpy(self.cell_id_array) cid_unique = [] for idx in range(len(ct_all)): if ct_all[idx] == self.used_cell_types_list[actor_counter]: cid = cid_all[idx] if cid not in cid_unique: cid_unique.append(cid_all[idx]) for idx in range(len(cid_unique)): filter_list[actor_counter].SetValue(idx, cid_unique[idx]) else: filter_list[actor_counter].SetValue(0, 13) # rwh: what the?? smoother_list[actor_counter].SetInputConnection(filter_list[actor_counter].GetOutputPort()) normals_list[actor_counter].SetInputConnection(smoother_list[actor_counter].GetOutputPort()) normals_list[actor_counter].SetFeatureAngle(45.0) mapper_list[actor_counter].SetInputConnection(normals_list[actor_counter].GetOutputPort()) mapper_list[actor_counter].ScalarVisibilityOff() actors_dict = actor_specs.actors_dict if actor_number in actors_dict.keys(): actor = actors_dict[actor_number] actor.SetMapper(mapper_list[actor_counter]) cell_type_lut = self.get_type_lookup_table() actor.GetProperty().SetDiffuseColor( cell_type_lut.GetTableValue(actor_number)[0:3]) if hex_flag: actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex)