def decimation_pro(data,ratio): sim = vtk.vtkDecimatePro(); sim.SetTargetReduction(ratio); sim.SetInputData(data); sim.PreserveTopologyOn(); sim.SplittingOff(); sim.BoundaryVertexDeletionOff(); sim.Update() return sim.GetOutput();0
def get_actor(vtk_source, color=color_diffuse, opacity=1.0, has_scalar_visibility=False, has_decimator=False): """ Set `scalar_visibility` be `True` makes `color` unavailable. :return: a vtkActor """ if has_decimator: # Reduce the number of triangles decimator = vtk.vtkDecimatePro() decimator.SetInputConnection(vtk_source.GetOutputPort()) # decimator.SetInputData(vtk_source) decimator.SetFeatureAngle(60) decimator.MaximumIterations = 1 decimator.PreserveTopologyOn() decimator.SetMaximumError(0.0002) decimator.SetTargetReduction(1) decimator.SetErrorIsAbsolute(1) decimator.SetAbsoluteError(0.0002) decimator.ReleaseDataFlagOn() # Generate Normals normals = vtk.vtkPolyDataNormals() if has_decimator: normals.SetInputConnection(decimator.GetOutputPort()) else: normals.SetInputConnection(vtk_source.GetOutputPort()) normals.SetFeatureAngle(60.0) normals.ReleaseDataFlagOn() stripper = vtk.vtkStripper() stripper.SetInputConnection(normals.GetOutputPort()) stripper.ReleaseDataFlagOn() mapper = vtk.vtkPolyDataMapper() # mapper.SetInputConnection(vtk_source.GetOutputPort()) mapper.SetInputConnection(stripper.GetOutputPort()) mapper.SetScalarVisibility(has_scalar_visibility) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetDiffuseColor(color) actor.GetProperty().SetSpecular(0.3) actor.GetProperty().SetSpecularPower(20) actor.GetProperty().SetInterpolation(2) # actor.GetProperty().SetRepresentation(2) # actor.GetProperty().SetEdgeVisibility(True) # actor.GetProperty().SetOpacity(opacity) if opacity < 1.0: if is_depth_peeling_supported(render_window, renderer, True): setup_evn_for_depth_peeling(render_window, renderer, max_peels, occlusion) actor.GetProperty().SetOpacity(opacity) else: print "Depth Peeling is not supported." return actor
def applyFilters(self, state): surface = None surface = state.inputModelNode.GetPolyDataConnection() if state.decimation: triangle = vtk.vtkTriangleFilter() triangle.SetInputConnection(surface) decimation = vtk.vtkDecimatePro() decimation.SetTargetReduction(state.reduction) decimation.SetBoundaryVertexDeletion(state.boundaryDeletion) decimation.PreserveTopologyOn() decimation.SetInputConnection(triangle.GetOutputPort()) surface = decimation.GetOutputPort() if state.smoothing: if state.smoothingMethod == "Laplace": smoothing = vtk.vtkSmoothPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.laplaceIterations) smoothing.SetRelaxationFactor(state.laplaceRelaxation) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() elif state.smoothingMethod == "Taubin": smoothing = vtk.vtkWindowedSincPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.taubinIterations) smoothing.SetPassBand(state.taubinPassBand) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() if state.normals: normals = vtk.vtkPolyDataNormals() normals.AutoOrientNormalsOn() normals.SetFlipNormals(state.flipNormals) normals.SetSplitting(state.splitting) normals.SetFeatureAngle(state.featureAngle) normals.ConsistencyOn() normals.SetInputConnection(surface) surface = normals.GetOutputPort() if state.cleaner: cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(surface) surface = cleaner.GetOutputPort() if state.connectivity: connectivity = vtk.vtkPolyDataConnectivityFilter() connectivity.SetExtractionModeToLargestRegion() connectivity.SetInputConnection(surface) surface = connectivity.GetOutputPort() state.outputModelNode.SetPolyDataConnection(surface) return True
def decimatePolygon(polyObject,reduceFactor=0.5): ''' ''' deci = vtk.vtkDecimatePro() deci.SetInputData(polyObject) deci.SetTargetReduction(reduceFactor) deci.BoundaryVertexDeletionOff() deci.PreserveTopologyOn() deci.SetSplitting(0) deci.Update() return deci.GetOutput()
def __init__(self, inputs = (1,1)): """ Initialization """ self.defaultLower = 0 self.defaultUpper = 255 lib.ProcessingFilter.ProcessingFilter.__init__(self,(1,1)) self.contour = vtk.vtkMarchingCubes() self.decimate = vtk.vtkDecimatePro() self.descs = {"Simplify": "Simplify surface", "IsoValue":"Iso-surface value", "PreserveTopology":"PreserveTopology"} self.filterDesc = "Creates iso-surface as polygons\nInput: Binary image (Grayscale image)\nOutput: Surface mesh";
def vtk_smooth(iso, iter=20, relax=0.5, decimate=0.0): isoSmooth = vtk.vtkSmoothPolyDataFilter() if decimate>0: deci = vtk.vtkDecimatePro() deci.SetInput(iso.GetOutput()) deci.SetTargetReduction(decimate) deci.PreserveTopologyOn() isoSmooth.SetInputConnection(deci.GetOutputPort()) else: isoSmooth.SetInputConnection(iso.GetOutputPort()) isoSmooth.SetNumberOfIterations(100) isoSmooth.BoundarySmoothingOn() isoSmooth.FeatureEdgeSmoothingOff() isoSmooth.SetFeatureAngle(45) isoSmooth.SetEdgeAngle(15) isoSmooth.SetRelaxationFactor(relax) return isoSmooth
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 GeneratePolyData(self): if self._imagemask: contour_filter = vtk.vtkMarchingCubes() contour_filter.ReleaseDataFlagOn() contour_filter.SetNumberOfContours(1) contour_filter.SetComputeScalars(0) contour_filter.SetComputeNormals(0) if vtk.vtkVersion().GetVTKMajorVersion() > 5: contour_filter.SetInputData(self._imagemask) else: contour_filter.SetInput(self._imagemask) contour_filter.SetValue(0, 128.0) try: contour_filter.Update() except: print sys.exc_type, sys.exc_value return False decimate = vtk.vtkDecimatePro() decimate.ReleaseDataFlagOn() decimate.SetInputConnection(contour_filter.GetOutputPort()) decimate.PreserveTopologyOn() decimate.SetTargetReduction(0) try: decimate.Update() except: print sys.exc_type, sys.exc_value return False if self._polydata is None: self._polydata = GeometryObject( self._name, self._name, decimate.GetOutputPort()) else: self._polydata.SetInputConnection(decimate.GetOutputPort()) if self._wireframe: self._polydata.SetWireFrameOn() else: self._polydata.SetWireFrameOff() self._polydata.SetVisibilityOff()
def __init__(self, parent, visualizer, **kws): """ Initialization """ VisualizationModule.__init__(self, parent, visualizer, **kws) # self.name = "Surface Rendering" # for i in range(1, 3): # self.setInputChannel(i, i) self.normals = vtk.vtkPolyDataNormals() self.smooth = None self.volumeModule = None self.scalarRange = (0, 255) self.eventDesc = "Rendering iso-surface" self.decimate = vtk.vtkDecimatePro() self.setMethod(1) self.init = 0 self.mapper = vtk.vtkPolyDataMapper() self.descs = { "Method": "Surface rendering method", "Gaussian": "Smooth surface with gaussian smoothing", "Normals": "Smooth surface with normals", "FeatureAngle": "Feature angle of normals\n", "Simplify": "Simplify surface", "PreserveTopology": "Preserve topology", "IsoValue": "Iso value", "SurfaceRangeBegin": "Generate surfaces in range:\n", "SurfaceAmnt": "Number of surfaces", "Transparency": "Surface transparency", "MultipleSurfaces": "Visualize multiple surfaces", "SolidColor": "Color surface with max. intensity", } self.actor = self.lodActor = vtk.vtkLODActor() self.lodActor.SetMapper(self.mapper) self.lodActor.SetNumberOfCloudPoints(10000) self.renderer = self.parent.getRenderer() self.renderer.AddActor(self.lodActor) # self.updateRendering() self.filterDesc = "Create and visualize iso-surface"
def decimateSurface(self, polyData): ''' ''' decimationFilter = vtk.vtkDecimatePro() decimationFilter.SetInputData(polyData) decimationFilter.SetTargetReduction(0.99) decimationFilter.SetBoundaryVertexDeletion(0) decimationFilter.PreserveTopologyOn() decimationFilter.Update() cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(decimationFilter.GetOutput()) cleaner.Update() triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInputData(cleaner.GetOutput()) triangleFilter.Update() outPolyData = vtk.vtkPolyData() outPolyData.DeepCopy(triangleFilter.GetOutput()) return outPolyData
def __init__(self, module_manager): # call parent constructor ModuleBase.__init__(self, module_manager) # the decimator only works on triangle data, so we make sure # that it only gets triangle data self._triFilter = vtk.vtkTriangleFilter() self._decimate = vtk.vtkDecimatePro() self._decimate.PreserveTopologyOn() self._decimate.SetInput(self._triFilter.GetOutput()) module_utils.setup_vtk_object_progress(self, self._triFilter, "Converting to triangles") module_utils.setup_vtk_object_progress(self, self._decimate, "Decimating mesh") # now setup some defaults before our sync self._config.target_reduction = self._decimate.GetTargetReduction() * 100.0 config_list = [ ( "Target reduction (%):", "target_reduction", "base:float", "text", "Decimate algorithm will attempt to reduce by this much.", ) ] ScriptedConfigModuleMixin.__init__( self, config_list, {"Module (self)": self, "vtkDecimatePro": self._decimate, "vtkTriangleFilter": self._triFilter}, ) self.sync_module_logic_with_config()
def applyFilters(self, state): surface = None surface = state.inputModelNode.GetPolyDataConnection() if state.decimation: triangle = vtk.vtkTriangleFilter() triangle.SetInputConnection(surface) decimation = vtk.vtkDecimatePro() decimation.SetTargetReduction(state.reduction) decimation.SetBoundaryVertexDeletion(state.boundaryDeletion) decimation.PreserveTopologyOn() decimation.SetInputConnection(triangle.GetOutputPort()) surface = decimation.GetOutputPort() if state.smoothing: if state.smoothingMethod == "Laplace": smoothing = vtk.vtkSmoothPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.laplaceIterations) smoothing.SetRelaxationFactor(state.laplaceRelaxation) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() elif state.smoothingMethod == "Taubin": smoothing = vtk.vtkWindowedSincPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.taubinIterations) smoothing.SetPassBand(state.taubinPassBand) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() if state.normals: normals = vtk.vtkPolyDataNormals() normals.SetAutoOrientNormals(state.autoOrientNormals) normals.SetFlipNormals(state.flipNormals) normals.SetSplitting(state.splitting) normals.SetFeatureAngle(state.featureAngle) normals.ConsistencyOn() normals.SetInputConnection(surface) surface = normals.GetOutputPort() if state.mirror: mirrorTransformMatrix = vtk.vtkMatrix4x4() mirrorTransformMatrix.SetElement(0, 0, -1 if state.mirrorX else 1) mirrorTransformMatrix.SetElement(1, 1, -1 if state.mirrorY else 1) mirrorTransformMatrix.SetElement(2, 2, -1 if state.mirrorZ else 1) mirrorTransform = vtk.vtkTransform() mirrorTransform.SetMatrix(mirrorTransformMatrix) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputConnection(surface) transformFilter.SetTransform(mirrorTransform) surface = transformFilter.GetOutputPort() if mirrorTransformMatrix.Determinant()<0: reverse = vtk.vtkReverseSense() reverse.SetInputConnection(surface) surface = reverse.GetOutputPort() if state.cleaner: cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(surface) surface = cleaner.GetOutputPort() if state.fillHoles: fillHoles = vtk.vtkFillHolesFilter() fillHoles.SetHoleSize(state.fillHolesSize) fillHoles.SetInputConnection(surface) # Need to auto-orient normals, otherwise holes # could appear to be unfilled when only front-facing elements # are chosen to be visible. normals = vtk.vtkPolyDataNormals() normals.AutoOrientNormalsOn() normals.ConsistencyOn() normals.SetInputConnection(fillHoles.GetOutputPort()) surface = normals.GetOutputPort() if state.connectivity: connectivity = vtk.vtkPolyDataConnectivityFilter() connectivity.SetExtractionModeToLargestRegion() connectivity.SetInputConnection(surface) surface = connectivity.GetOutputPort() state.outputModelNode.SetPolyDataConnection(surface) return True
def create_polygon_reducer(extractor): reducer = vtk.vtkDecimatePro() reducer.SetInputConnection(extractor.GetOutputPort()) reducer.SetTargetReduction(0.5) reducer.PreserveTopologyOn() return reducer
def load_map(gfx,mapfile,root,status,scale,rendtype,isov,opct,cropentry,nfv,vardeci,varsmooth,color,caller): if caller != 'fit': root.configure(cursor='watch') status.set('Map loading ... please wait') if mapfile =='' or mapfile == None or mapfile ==() : MB.showwarning('Info','Select map file') status.clear() root.configure(cursor='arrow') return try: gfx.renderer.RemoveActor(gfx.map[0].acteur) gfx.renderer.RemoveActor(gfx.map[0].box) except: pass if mapfile == 0: mapfile = gfx.map[0].fn if gfx.map == []: gfx.map = [Map()] gfx.map[0].id=0 if 'map' in caller : clean_map(gfx) #supression des fichiers sort.s xudi et iudi if '.vtk' in mapfile: chdir(gfx.tmpdir) v2v_out='info_map' if caller != 'crop': gfx.map[0].sigma,gfx.map[0].avg = map_sigma_avg(v2v_out) if scale != gfx.map[0].scale: spc = None o = None f = open(mapfile,'r') for l in f: if l.startswith('SPACING'): spc = l.split()[1:4] if l.startswith('ORIGIN'): o = l.split()[1:4] if spc != None and o != None: break f.close() gfx.map[0].ratio = scale/gfx.map[0].scale if spc != None and o != None: system("sed -i -e /^SPACING/s/.*/'SPACING %f %f %f'/ %s"%(float(spc[0])*gfx.map[0].ratio,float(spc[1])*gfx.map[0].ratio,float(spc[2])*gfx.map[0].ratio,mapfile)) system("sed -i -e /^ORIGIN/s/.*/'ORIGIN %f %f %f'/ %s"%(float(o[0])*gfx.map[0].ratio,float(o[1])*gfx.map[0].ratio,float(o[2])*gfx.map[0].ratio,mapfile)) chdir(gfx.workdir) if '.ezd' in mapfile: chdir(gfx.tmpdir) mapfileout = extract_file_from_path(mapfile)[:-4]+'.vtk' e2v_out='info_map' system(gfx.vedabin+'/e2v.exe >> %s <<ENDOF\n%s \n%f \n%s \nENDOF'%(e2v_out,mapfile,scale,mapfileout)) mapfile = gfx.tmpdir + '/' + mapfileout gfx.map[0].sigma,gfx.map[0].avg = map_sigma_avg(e2v_out) chdir(gfx.workdir) gfx.map[0].fn = mapfile gfx.map[0].id = set_map_id(gfx) gfx.map[0].color = color gfx.map[0].oldscale = gfx.map[0].scale gfx.map[0].scale = scale if nfv !=None: nfv.set(extract_file_from_path(gfx.map[0].fn)) reader = vtk.vtkStructuredPointsReader() reader.SetFileName(mapfile) reader.Update() #by calling Update() we read the file gfx.map[0].reader=reader iso = vtk.vtkMarchingContourFilter() iso.UseScalarTreeOn() iso.ComputeNormalsOn() iso.SetInputConnection(reader.GetOutputPort()) iso.SetValue(0,isov*gfx.map[0].sigma+gfx.map[0].avg) gfx.map[0].iso=iso gfx.map[0].isov=isov if varsmooth == '1': #generate vectors clean = vtk.vtkCleanPolyData() clean.SetInputConnection(iso.GetOutputPort()) clean.ConvertStripsToPolysOn() smooth = vtk.vtkWindowedSincPolyDataFilter() smooth.SetInputConnection(clean.GetOutputPort()) smooth.BoundarySmoothingOn() smooth.GenerateErrorVectorsOn() smooth.GenerateErrorScalarsOn() smooth.NormalizeCoordinatesOn() smooth.NonManifoldSmoothingOn() smooth.FeatureEdgeSmoothingOn() smooth.SetEdgeAngle(90) smooth.SetFeatureAngle(90) smooth.Update() if vardeci=='1': deci = vtk.vtkDecimatePro() if varsmooth == '0': deci.SetInput(iso.GetOutput()) else : deci.SetInput(smooth.GetOutput()) deci.PreserveTopologyOn() deci.BoundaryVertexDeletionOn() deci.SplittingOn() deci.PreSplitMeshOn() deci.SetTargetReduction(0.97) gfx.map[0].isdeci='1' mapper = vtk.vtkOpenGLPolyDataMapper() mapper.SetInputConnection(deci.GetOutputPort()) else : mapper = vtk.vtkOpenGLPolyDataMapper() if varsmooth == '1': mapper.SetInputConnection(smooth.GetOutputPort()) ### <- connection here else : mapper.SetInputConnection(iso.GetOutputPort()) #mapper.SetInput(newpd) ### <- newpd connect there gfx.map[0].isdeci='0' mapper.ScalarVisibilityOff() mapper.Update() gfx.map[0].mapper=mapper actor = vtk.vtkOpenGLActor() actor.SetMapper(mapper) gfx.map[0].acteur=actor #actor.SetScale(scale,scale,scale) gerer differament actor.GetProperty().SetColor(gfx.map[0].color) actor.PickableOff() #definition de la box outline = vtk.vtkOutlineFilter() outline.SetInput(reader.GetOutput()) outlineMapper = vtk.vtkPolyDataMapper() outlineMapper.SetInput(outline.GetOutput()) box=vtk.vtkActor() box.SetMapper( outlineMapper ) box.GetProperty().SetColor((invcolor(gfx.map[0].color))) box.PickableOff() #box.SetScale(scale,scale,scale) gfx.map[0].box = box #get boxwidget bounds and set axes lenth (xmin,xmax,ymin,ymax,zmin,zmax)=box.GetBounds() x=abs(xmin-xmax)/2.0 y=abs(ymin-ymax)/2.0 z=abs(zmin-zmax)/2.0 gfx.axes.SetTotalLength( x, y , z ) #defini la longeurs des axe init_cam_slab(gfx,(xmin,xmax,ymin,ymax,zmin,zmax)) #defini le slab correct gfx.map[0].rendtype=rendtype if rendtype=='Wireframe': actor.GetProperty().SetRepresentationToWireframe() elif rendtype=='Surface': actor.GetProperty().SetRepresentationToSurface() elif rendtype=='Points': actor.GetProperty().SetRepresentationToPoints() actor.GetProperty().SetPointSize(5) else : actor.GetProperty().SetRepresentationToWireframe() gfx.map[0].opct=opct actor.GetProperty().SetOpacity(opct) actor.GetProperty().SetInterpolationToGouraud() actor.GetProperty().SetSpecular(.4) actor.GetProperty().SetSpecularPower(10) if cropentry!=None: if gfx.crop==None: gfx.crop=Crop(gfx,iso,cropentry,None) #here entryval = None rendermap(gfx) #ajustement pour la symetry helicoidale if gfx.map[0].scale != gfx.map[0].oldscale:#changement de scale gfx.itf.propagate_scale(gfx,scale,caller) if gfx.ps != None: if gfx.ps.solidtype == 'Helicoidal': gfx.ps.display_tube(gfx,caller) elif gfx.ps.solidtype == 'Icosahedral' or gfx.ps.solidtype =='Octahedral' or gfx.ps.solidtype == 'Tetrahedral': gfx.ps.display_platonic(gfx,gfx.ps.ori) elif gfx.ps.solidtype =='Cn' or gfx.ps.solidtype == 'Dn': gfx.ps.display_Xn(gfx) if caller == 'crop':#crop uniquement helicoidal if gfx.ps != None: if gfx.ps.solidtype == 'Helicoidal': gfx.ps.display_tube(gfx,caller) if caller != 'fit': status.clear() root.configure(cursor='arrow')
polydata = contour.GetOutput() #export the 3D image as a polygon data file algordata = contour.GetOutputPort() #export the 3D image as an algorithm file """ """ #VOXEL CONTOURING ALGORITHM (doesnt work yet) vcsf = vtk.vtkVoxelContoursToSurfaceFilter() vcsf.SetInputConnection(imgThreshold) vcsf.Update() polydata = vcsf.GetOutput() #export the 3D image as a polygon data file algordata = vcsf.GetOutputPort() #export the 3D image as an algorithm file """ ############################# #Reduce Number of Triangles decimator = vtk.vtkDecimatePro() decimator.SetInputConnection(algordata) decimator.SetTargetReduction(0.5) decimator.SetPreserveTopology(1) decimator.Update() reducetri = decimator.GetOutputPort() # #Smooth smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(filhol) smooth.SetNumberOfIterations(15) smooth.SetFeatureAngle(10) smooth.SetRelaxationFactor(0.05) smooth.FeatureEdgeSmoothingOn()
def procData(self): # double negative so that the name doesn't collide with the same option that is off by default in dpLoadh5 #if not self.no_legacy_transpose: cube = self.data_cube.transpose((1,0,2)) # changed this to off by default and use same flag from dpLoadh5 if self.legacy_transpose: cube = self.data_cube.transpose((1,0,2)) else: cube = self.data_cube # for easy saving of scale as attribute in hdf5 output self.scale = self.data_attrs['scale'] # Pad data with zeros so that meshes are closed on the edges sizes = np.array(cube.shape); r = self.RAD; sz = sizes + 2*r; dataPad = np.zeros(sz, dtype=self.data_type); dataPad[r:sz[0]-r, r:sz[1]-r, r:sz[2]-r] = cube # old method # # get all unique seeds in the cube # self.seeds = np.unique(cube) # # remove the background label (label 0) # if self.seeds.size > 0 and self.seeds[0] == 0: self.seeds = self.seeds[1:] # get sizes first with hist (prevents sums in meshing loop) #self.nVoxels = emLabels.getSizes(cube)[1:] self.nVoxels = emLabels.getSizesMax(cube, sum(self.data_attrs['types_nlabels']))[1:] self.seeds = np.arange(1, self.nVoxels.size+1, dtype=np.int64); self.seeds = self.seeds[self.nVoxels>0] #print(np.argmax(self.nVoxels)) assert( self.seeds.size > 0 ) # error, no labels n = self.seeds.size; #self.nVoxels = np.zeros((n,), dtype=np.int64) assert( n == self.seeds[-1] or not self.mesh_outfile_stl ) # for consistency with stl file, no empty labels # intended for debug, only process a subset of the seeds if self.seed_range[0] < 1 or self.seed_range[0] > n: self.seed_range[0] = 0 if self.seed_range[1] < 1 or self.seed_range[1] < 0: self.seed_range[1] = n # threw me off in debug twice, if the supervoxels are contiguous then have the seed_range mean actual seed if n == self.seeds[-1] and self.seed_range[0] > 0: self.seed_range[0] -= 1 # other inits if self.do_smooth: W = np.ones(self.smooth, dtype=self.PDTYPE) / self.smooth.prod() # allocate outputs self.faces = n * [None]; self.vertices = n * [None]; self.mins = n * [None]; self.rngs = n * [None] self.bounds_beg = n * [None]; self.bounds_end = n * [None] self.nFaces = np.zeros((n,), dtype=np.uint64); self.nVertices = np.zeros((n,), dtype=np.uint64); if self.doplots or self.mesh_outfile_stl: self.allPolyData = vtk.vtkAppendPolyData() # get bounding boxes for each supervoxel svox_bnd = nd.measurements.find_objects(dataPad, n) if self.dpLabelMesher_verbose: tloop = time.time(); t = time.time() for i in range(self.seed_range[0], self.seed_range[1]): if self.dpLabelMesher_verbose and i % self.print_every == 0: print('seed : %d is %d / %d' % (self.seeds[i],i+1,self.seed_range[1])) # old method # # select the labels # #bwdpls = (dataPad == self.seeds[i]); # #self.nVoxels[i] = bwdpls.sum(); # if self.dpLabelMesher_verbose: print('\tnVoxels = %d' % self.nVoxels[i]) # # # get the voxel coordinates relative to padded and non-padded cube # idpls = np.argwhere(bwdpls) # # bounding box within zero padded cube # imin = idpls.min(axis=0); imax = idpls.max(axis=0) cur_bnd = svox_bnd[self.seeds[i]-1] imin = np.array([x.start for x in cur_bnd]); imax = np.array([x.stop-1 for x in cur_bnd]) # min and max coordinates of this seed within zero padded cube pmin = imin - r; pmax = imax + r; # min coordinates of this seed relative to original (non-padded cube) self.mins[i] = pmin - r; self.rngs[i] = pmax - pmin + 1 # old method # crop out the bounding box plus the padding, then optionally smooth #crpdpls = bwdpls[pmin[0]:pmax[0]+1,pmin[1]:pmax[1]+1,pmin[2]:pmax[2]+1].astype(self.PDTYPE) # crop out the bounding box then binarize this seed within bounding box crpdpls = (dataPad[pmin[0]:pmax[0]+1,pmin[1]:pmax[1]+1, pmin[2]:pmax[2]+1] == self.seeds[i]).astype(self.PDTYPE) if self.do_smooth: crpdplsSm = filters.convolve(crpdpls, W, mode='reflect', cval=0.0, origin=0) # if smoothing results in nothing above contour level, use original without smoothing if (crpdplsSm > self.contour_lvl).any(): del crpdpls; crpdpls = crpdplsSm; del crpdplsSm if self.doplots: showImgData(np.squeeze(crpdpls[:,:,crpdpls.shape[2]/2]),'slice') # vtkImageImport is used to create image data from memory in vtk # http://wiki.scipy.org/Cookbook/vtkVolumeRendering dataImporter = vtk.vtkImageImport() # The preaviusly created array is converted to a byte string (not string, see np docs) and imported. data_string = crpdpls.transpose((2,1,0)).tostring(); dataImporter.CopyImportVoidPointer(data_string, len(data_string)) # Set the type of the newly imported data #dataImporter.SetDataScalarTypeToUnsignedChar() #dataImporter.SetDataScalarTypeToUnsignedShort() dataImporter.SetDataScalarTypeToDouble() # Because the data that is imported only contains an intensity value (i.e. not RGB), the importer # must be told this is the case. dataImporter.SetNumberOfScalarComponents(1) if self.set_voxel_scale: # Have to set the voxel anisotropy here, as there does not seem an easy way once the poly is created. dataImporter.SetDataSpacing(self.data_attrs['scale']) # Data extent is the extent of the actual buffer, whole extent is ??? # Use extents that are relative to non-padded cube beg = self.mins[i]; end = self.mins[i] + self.rngs[i] - 1 dataImporter.SetDataExtent(beg[0], end[0], beg[1], end[1], beg[2], end[2]) dataImporter.SetWholeExtent(beg[0], end[0], beg[1], end[1], beg[2], end[2]) # save bounds relative to entire dataset self.bounds_beg[i] = beg + self.dataset_index; self.bounds_end[i] = end + self.dataset_index; # use vtk for isosurface contours and surface mesh reduction iso = vtk.vtkContourFilter() iso.SetInputConnection(dataImporter.GetOutputPort()) iso.SetComputeNormals(0) iso.SetValue(0, self.contour_lvl) if self.decimatePro: deci = vtk.vtkDecimatePro() rf = 1-self.reduce_frac; deci.SetTargetReduction(rf); df = 0.01 deci.SplittingOn(); deci.PreserveTopologyOff(); deci.BoundaryVertexDeletionOn() if self.min_faces > 0: updates = range(100) else: updates = ['deci.BoundaryVertexDeletionOff()','deci.PreserveTopologyOn()','0'] else: deci = vtk.vtkQuadricClustering() #deci.SetDivisionOrigin(0.0,0.0,0.0); deci.SetDivisionSpacing(self.reduce_spacing) nb = self.reduce_nbins; deci.SetNumberOfDivisions(nb,nb,nb); deci.AutoAdjustNumberOfDivisionsOff() updates = ['deci.AutoAdjustNumberOfDivisionsOn()','0'] # thought of adding checking for closed surfaces, http://comments.gmane.org/gmane.comp.lib.vtk.user/47957 # this did not work, for low reduce_frac, many open edges remain even for large objects # not clear that triangle filter does anything, contour filter already makes triangulated meshes? # send polygonal mesh from isosurface to triangle filter to convert to triangular mesh #tri = vtk.vtkTriangleFilter(); tri.SetInputConnection(iso.GetOutputPort()); #deci.SetInputConnection(tri.GetOutputPort()) deci.SetInputConnection(iso.GetOutputPort()) # xxx - this is kindof a cheap trick, if we reduce down "too much", then rerun to preserve more for update in updates: deci.Update() # http://forrestbao.blogspot.com/2012/06/vtk-polygons-and-other-cells-as.html # http://stackoverflow.com/questions/6684306/how-can-i-read-a-vtk-file-into-a-python-datastructure dOut = deci.GetOutput() # xxx - points seem to be single instead of inputted type, probably depends on vtk version: # http://public.kitware.com/pipermail/vtkusers/2010-April/059413.html self.vertices[i] = nps.vtk_to_numpy(dOut.GetPoints().GetData()) if self.center_origin: self.vertices[i][:,0] -= sizes[0]/2; self.vertices[i][:,1] -= sizes[1]/2 self.vertices[i][:,2] = sizes[2]/2 - self.vertices[i][:,2] self.faces[i] = nps.vtk_to_numpy(dOut.GetPolys().GetData()).reshape((-1,4))[:,1:] if self.flip_faces: self.faces[i] = self.faces[i][:,::-1] self.nVertices[i] = self.vertices[i].shape[0] self.nFaces[i] = self.faces[i].shape[0] if self.dpLabelMesher_verbose and i % self.print_every == 0: print('\t%d vertices, %d faces' % (self.nVertices[i], self.nFaces[i])) if self.min_faces > 0: if self.nFaces[i] >= self.min_faces: break rf -= df; deci.SetTargetReduction(rf) else: if self.nVertices[i] > 2 and self.nFaces[i] > 0: break eval(update) assert( self.nVertices[i] > 2 and self.nFaces[i] > 0 ) # there has to be at least one face if self.doplots: mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(deci.GetOutputPort()) dpLabelMesher.vtkShow(mapper) # append the current surface to vtk object with all the surfaces if self.doplots or self.mesh_outfile_stl: self.allPolyData.AddInputConnection(deci.GetOutputPort()) if self.doplots: connectivityFilter = vtk.vtkPolyDataConnectivityFilter() connectivityFilter.SetInputConnection(self.allPolyData.GetOutputPort()) connectivityFilter.SetExtractionModeToAllRegions() connectivityFilter.ColorRegionsOn() connectivityFilter.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(connectivityFilter.GetOutputPort()) mapper.SetScalarRange(connectivityFilter.GetOutput().GetPointData().GetArray("RegionId").GetRange()) dpLabelMesher.vtkShow(mapper) if self.dpLabelMesher_verbose and i % self.print_every == 0: print('\tdone in %.3f s' % (time.time() - t,)); t = time.time() if self.dpLabelMesher_verbose: print('Total ellapsed time meshing %.3f s' % (time.time() - tloop,))
def __init__ (self, interactor, renderer, mesh_filename, reg_filename): self.interactor = interactor self.renderer = renderer reader = vtk.vtkStructuredPointsReader() reader.SetFileName(mesh_filename) cf = vtk.vtkContourFilter() cf.SetInput(reader.GetOutput()) cf.SetValue(0, 1) deci = vtk.vtkDecimatePro() deci.SetInput(cf.GetOutput()) deci.SetTargetReduction(.1) deci.PreserveTopologyOn() smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(deci.GetOutput()) smoother.SetNumberOfIterations(100) normals = vtk.vtkPolyDataNormals() normals.SetInput(smoother.GetOutput()) normals.FlipNormalsOn() normals.SetFeatureAngle(60.0) stripper = vtk.vtkStripper() stripper.SetInputConnection(normals.GetOutputPort()) lut = vtk.vtkLookupTable() lut.SetHueRange(0, 0) lut.SetSaturationRange(0, 0) lut.SetValueRange(0.2, 0.55) contourMapper = vtk.vtkPolyDataMapper() #contourMapper.SetInput(normals.GetOutput()) contourMapper.SetInput(stripper.GetOutput()) contourMapper.SetLookupTable(lut) self.contours = vtk.vtkActor() self.contours.SetMapper(contourMapper) #self.contours.GetProperty().SetRepresentationToWireframe() self.contours.GetProperty().SetRepresentationToSurface() #self.contours.GetProperty().SetInterpolationToGouraud() #self.contours.GetProperty().SetOpacity(1.0) #self.contours.GetProperty().SetAmbient(0.1) self.contours.GetProperty().SetDiffuse(0.1) #self.contours.GetProperty().SetSpecular(0.1) #self.contours.GetProperty().SetSpecularPower(0.1) # now setmatrix() on the actor from the reg file ! def array_to_vtkmatrix4x4(scipy_array): vtkmat = vtk.vtkMatrix4x4() for i in range(0,4): for j in range(0,4): vtkmat.SetElement(i,j, scipy_array[i,j]) return vtkmat mat = pickle.load(file(reg_filename, 'r')) vtkmat = array_to_vtkmatrix4x4(mat) self.contours.SetUserMatrix(vtkmat) #self.contours.GetProperty().SetOpacity(.38) #adjustable in the grid manager now # XXX YAH somehow get a callback when actor is moved... self.renderer.AddActor(self.contours)
def _BuildPipeline(self): """_BuildPipeline - Builds the visualization pipeline""" image = component.getUtility(ICurrentImage) # update image (VTK-6 compatible) image.Update() # image reslice object reslice = vtk.vtkImageReslice() reslice.SetInterpolationModeToCubic() reslice.ReleaseDataFlagOn() reslice.SetInputConnection(image.GetOutputPort()) if self._transform: reslice.SetTransform(self._transform) # get extents, spacings, etc in_extent = image.GetExtent() in_spacing = image.GetSpacing() in_origin = image.GetOrigin() # get stencil data stencil_data = image.GetStencilData() # Set image resample factor f = self.gui.m_sliderSurfaceQuality.GetValue() / 100.0 if f == 0.0: f = 0.001 # Set surface decimation factor decf = self.gui.m_sliderDecimationFactor.GetValue() / 100.0 # Enable/Disable stencil usage if self.gui.m_checkBoxClipping.GetValue() is True and stencil_data: if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(stencil_data) else: reslice.SetStencil(stencil_data) reslice.SetBackgroundLevel(image.GetScalarRange()[0]) ext = stencil_data.GetExtent() else: ext = in_extent if vtk.vtkVersion().GetVTKMajorVersion() > 5: reslice.SetStencilData(None) else: reslice.SetStencil(None) # expand extent slightly - account for downsampling later too fudge = int(math.ceil(1.0 / f)) ext = [ext[0] - fudge, ext[1] + fudge, ext[2] - fudge, ext[3] + fudge, ext[4] - fudge, ext[5] + fudge] reslice.SetOutputExtent(ext) # set default origin/spacing -- these two lines work... reslice.SetOutputSpacing(in_spacing) reslice.SetOutputOrigin(in_origin) # do we need to downsample the image? if f < 1.0: resample = vtk.vtkImageResample() resample.SetInputConnection(reslice.GetOutputPort()) resample.ReleaseDataFlagOn() for i in range(3): resample.SetAxisMagnificationFactor(i, f) obj = resample else: obj = reslice # do we need to smooth the image? if self.gui.m_checkBoxImageSmoothing.GetValue() == True: smooth = vtk.vtkImageGaussianSmooth() smooth.SetStandardDeviation(1.0) smooth.ReleaseDataFlagOn() smooth.SetInputConnection(obj.GetOutputPort()) obj = smooth clip = vtk.vtkImageClip() clip.SetInputConnection(obj.GetOutputPort()) # setup contour filter cf = vtk.vtkMarchingCubes() cf.SetNumberOfContours(1) val = float(self.gui.m_textCtrlImageThreshold.GetValue()) cf.SetValue(0, val) cf.SetComputeScalars(0) cf.SetComputeNormals(0) cf.SetInputConnection(clip.GetOutputPort()) # decimate surface decimate = vtk.vtkDecimatePro() decimate.SetInputConnection(cf.GetOutputPort()) decimate.PreserveTopologyOn() decimate.SetTargetReduction(decf) # To cut down on memory consumption, we use the clip object # to process the image a chunk at a time. By default we # use 20 chunks -- but if the chunks are too small, we'll adjust this # number clip.UpdateInformation() ext = clip.GetInput().GetExtent() # main processing loop with wx.BusyCursor(): event.notify(ProgressEvent("Generating surface...", 0.0)) clip.SetOutputWholeExtent(ext[0], ext[1], ext[2], ext[3], ext[4], ext[5]) decimate.Update() event.notify(ProgressEvent("Generating surface...", 1.0)) # Create the rendered Geometry if not self._app_states[self._current_image_index].GetFactory(): self._app_states[self._current_image_index].SetFactory( vtkAtamai.SurfaceObjectFactory.SurfaceObjectFactory() ) self._app_states[self._current_image_index].GetFactory().SetInputConnection(decimate.GetOutputPort()) self._app_states[self._current_image_index].GetFactory().SetBackfaceProperty( self._app_states[self._current_image_index].GetFactory().GetProperty() ) self._app_states[self._current_image_index].GetFactory().NormalGenerationOn() self.SetSurfaceColor() self.GetMicroView().pane3D.ConnectActorFactory(self._app_states[self._current_image_index].GetFactory()) self._app_states[self._current_image_index]._disconnected = False # Update math values self.UpdateMathValues()
def contours(img,spacing=[1.0,1.0,1.0],contours=[]): importer = numpy2VTK(img,spacing) if len(contours) == 0: contours = [[img.max(),1.0,1.0,1.0,1.0]] actors = [] for c in contours: contourExtractor = vtk.vtkContourFilter() contourExtractor.SetInputConnection(importer.GetOutputPort()) contourExtractor.SetValue(0, c[0]) # contourNormals = vtk.vtkPolyDataNormals() # contourNormals.SetInputConnection(contourExtractor.GetOutputPort()) # contourNormals.SetFeatureAngle(60.0) # contourStripper = vtk.vtkStripper() # contourStripper.SetInputConnection(contourNormals.GetOutputPort()) deci = vtk.vtkDecimatePro() deci.SetInputConnection(contourExtractor.GetOutputPort()) deci.SetTargetReduction(0.99) deci.PreserveTopologyOn () # smoother = vtk.vtkSmoothPolyDataFilter() # smoother.SetInputConnection(deci.GetOutputPort()) # smoother.SetNumberOfIterations(50) normals = vtk.vtkPolyDataNormals() normals.SetInputConnection(deci.GetOutputPort()) normals.FlipNormalsOn() # smoothFilter = vtk.vtkSmoothPolyDataFilter() # smoothFilter.SetInputConnection(contourStripper.GetOutputPort()) # smoothFilter.SetNumberOfIterations(50) # smoothFilter.Update() contourMapper = vtk.vtkPolyDataMapper() # contourMapper.SetInputConnection(contourStripper.GetOutputPort()) contourMapper.SetInputConnection(normals.GetOutputPort()) contourMapper.ScalarVisibilityOff() actor = vtk.vtkActor() actor.SetMapper( contourMapper) actor.GetProperty().SetColor(c[1],c[2],c[3]) actor.GetProperty().SetOpacity(c[4]) actor.GetProperty().SetRepresentationToSurface() # # An outline provides context around the data. # outlineData = vtk.vtkOutlineFilter() # outlineData.SetInputConnection(v16.GetOutputPort()) # mapOutline = vtk.vtkPolyDataMapper() # mapOutline.SetInputConnection(outlineData.GetOutputPort()) # outline = vtk.vtkActor() # outline.SetMapper(mapOutline) # outline.GetProperty().SetColor(0, 0, 0) actors.append(actor) return actors
def decimate(points, faces, reduction=0.5, smooth_steps=100, scalars=[], save_vtk=False, output_vtk=''): """ Decimate vtk triangular mesh with vtk.vtkDecimatePro. Parameters ---------- points : list of lists of floats each element is a list of 3-D coordinates of a vertex on a surface mesh faces : list of lists of integers each element is list of 3 indices of vertices that form a face on a surface mesh reduction : float fraction of mesh faces to remove smooth_steps : integer number of smoothing steps scalars : list of integers or floats optional scalars for output VTK file save_vtk : Boolean output decimated vtk file? output_vtk : string output decimated vtk file name Returns ------- points : list of lists of floats decimated points faces : list of lists of integers decimated faces scalars : list of integers or floats scalars for output VTK file output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.io_vtk import read_vtk, write_vtk >>> from mindboggle.utils.mesh import decimate >>> from mindboggle.utils.plots import plot_vtk >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> reduction = 0.5 >>> smooth_steps = 100 >>> save_vtk = False >>> output_vtk = '' >>> faces, lines, indices, points, npoints, scalars, scalar_names, ... o2 = read_vtk(input_vtk) >>> points, faces, scalars, output_vtk = decimate(points, faces, reduction, >>> smooth_steps, scalars, >>> save_vtk, output_vtk) >>> len(points) == 2679 True >>> len(points) 2679 >>> # View: >>> output_vtk = 'decimated.vtk' >>> write_vtk(output_vtk, points, indices, lines, faces, scalars, >>> scalar_names) # doctest: +SKIP >>> plot_vtk(output_vtk) # doctest: +SKIP """ import os import vtk #------------------------------------------------------------------------- # vtk points: #------------------------------------------------------------------------- vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] #------------------------------------------------------------------------- # vtk faces: #------------------------------------------------------------------------- vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) #------------------------------------------------------------------------- # vtk scalars: #------------------------------------------------------------------------- if scalars: vtk_scalars = vtk.vtkFloatArray() vtk_scalars.SetName("scalars") for scalar in scalars: vtk_scalars.InsertNextValue(scalar) #------------------------------------------------------------------------- # vtkPolyData: #------------------------------------------------------------------------- polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) if scalars: polydata.GetPointData().SetScalars(vtk_scalars) #------------------------------------------------------------------------- # Decimate: #------------------------------------------------------------------------- # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() #------------------------------------------------------------------------- # Smooth: #------------------------------------------------------------------------- if save_vtk: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated.vtk') exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(decimate.GetOutput()) smoother.SetNumberOfIterations(smooth_steps) smoother.Update() out = smoother.GetOutput() if save_vtk: exporter.SetInput(smoother.GetOutput()) else: decimate.Update() out = decimate.GetOutput() if save_vtk: exporter.SetInput(decimate.GetOutput()) #------------------------------------------------------------------------- # Export output: #------------------------------------------------------------------------- if save_vtk: exporter.SetFileName(output_vtk) exporter.Write() if not os.path.exists(output_vtk): raise(IOError(output_vtk + " not found")) #------------------------------------------------------------------------- # Extract decimated points, faces, and scalars: #------------------------------------------------------------------------- points = [list(out.GetPoint(point_id)) for point_id in range(out.GetNumberOfPoints())] if out.GetNumberOfPolys() > 0: polys = out.GetPolys() pt_data = out.GetPointData() faces = [[int(polys.GetData().GetValue(j)) for j in range(i*4 + 1, i*4 + 4)] for i in range(polys.GetNumberOfCells())] if scalars: scalars = [pt_data.GetScalars().GetValue(i) for i in range(len(points))] else: faces = [] scalars = [] return points, faces, scalars, output_vtk
def applyFilters(self, state): surface = None if vtk.VTK_MAJOR_VERSION <= 5: surface = state.inputModelNode.GetPolyData() else: surface = state.inputModelNode.GetPolyDataConnection() if state.decimation: triangle = vtk.vtkTriangleFilter() if vtk.VTK_MAJOR_VERSION <= 5: triangle.SetInput(surface) else: triangle.SetInputConnection(surface) decimation = vtk.vtkDecimatePro() decimation.SetTargetReduction(state.reduction) decimation.SetBoundaryVertexDeletion(state.boundaryDeletion) decimation.PreserveTopologyOn() if vtk.VTK_MAJOR_VERSION <= 5: decimation.SetInput(triangle.GetOutput()) decimation.Update() surface = decimation.GetOutput() else: decimation.SetInputConnection(triangle.GetOutputPort()) surface = decimation.GetOutputPort() if state.smoothing: if state.smoothingMethod == "Laplace": smoothing = vtk.vtkSmoothPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.laplaceIterations) smoothing.SetRelaxationFactor(state.laplaceRelaxation) if vtk.VTK_MAJOR_VERSION <= 5: smoothing.SetInput(surface) smoothing.Update() else: smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() elif state.smoothingMethod == "Taubin": smoothing = vtk.vtkWindowedSincPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.taubinIterations) smoothing.SetPassBand(state.taubinPassBand) if vtk.VTK_MAJOR_VERSION <= 5: smoothing.SetInput(surface) smoothing.Update() surface = smoothing.GetOutput() else: smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() if state.normals: normals = vtk.vtkPolyDataNormals() normals.AutoOrientNormalsOn() normals.SetFlipNormals(state.flipNormals) normals.SetSplitting(state.splitting) normals.SetFeatureAngle(state.featureAngle) normals.ConsistencyOn() if vtk.VTK_MAJOR_VERSION <= 5: normals.SetInput(surface) normals.Update() surface = normals.GetOutput() else: normals.SetInputConnection(surface) surface = normals.GetOutputPort() if state.cleaner: cleaner = vtk.vtkCleanPolyData() if vtk.VTK_MAJOR_VERSION <= 5: cleaner.SetInput(surface) cleaner.Update() surface = cleaner.GetOutput() else: cleaner.SetInputConnection(surface) surface = cleaner.GetOutputPort() if state.connectivity: connectivity = vtk.vtkPolyDataConnectivityFilter() connectivity.SetExtractionModeToLargestRegion() if vtk.VTK_MAJOR_VERSION <= 5: connectivity.SetInput(surface) connectivity.Update() surface = connectivity.GetOutput() else: connectivity.SetInputConnection(surface) surface = connectivity.GetOutputPort() if vtk.VTK_MAJOR_VERSION <= 5: state.outputModelNode.SetAndObservePolyData(surface) else: state.outputModelNode.SetPolyDataConnection(surface) return True
def testDeciFranFace(self): # Create the RenderWindow, Renderer and both Actors # ren1 = vtk.vtkRenderer() ren2 = vtk.vtkRenderer() ren3 = vtk.vtkRenderer() ren4 = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren1) renWin.AddRenderer(ren2) renWin.AddRenderer(ren3) renWin.AddRenderer(ren4) pnm1 = vtk.vtkPNGReader() pnm1.SetFileName(VTK_DATA_ROOT + "/Data/fran_cut.png") atext = vtk.vtkTexture() atext.SetInputConnection(pnm1.GetOutputPort()) atext.InterpolateOn() # create a cyberware source # fran = vtk.vtkPolyDataReader() fran.SetFileName(VTK_DATA_ROOT + "/Data/fran_cut.vtk") # Create a table of decimation conditions # boundaryVertexDeletion = ["On", "Off"] accumulates = ["On", "Off"] deci = dict() mapper = dict() actor = dict() for topology in boundaryVertexDeletion: for accumulate in accumulates: idx = topology + accumulate deci.update({idx: vtk.vtkDecimatePro()}) deci[idx].SetInputConnection(fran.GetOutputPort()) deci[idx].SetTargetReduction(.95) if topology == "On": deci[idx].PreserveTopologyOn() elif topology == "Off": deci[idx].PreserveTopologyOff() if accumulate == "On": deci[idx].AccumulateErrorOn() elif accumulate == "Off": deci[idx].AccumulateErrorOff() mapper.update({idx: vtk.vtkPolyDataMapper()}) mapper[idx].SetInputConnection(deci[idx].GetOutputPort()) actor.update({idx: vtk.vtkActor()}) actor[idx].SetMapper(mapper[idx]) actor[idx].SetTexture(atext) # Add the actors to the renderer, set the background and size # ren1.SetViewport(0, .5, .5, 1) ren2.SetViewport(.5, .5, 1, 1) ren3.SetViewport(0, 0, .5, .5) ren4.SetViewport(.5, 0, 1, .5) ren1.AddActor(actor["OnOn"]) ren2.AddActor(actor["OnOff"]) ren3.AddActor(actor["OffOn"]) ren4.AddActor(actor["OffOff"]) camera = vtk.vtkCamera() ren1.SetActiveCamera(camera) ren2.SetActiveCamera(camera) ren3.SetActiveCamera(camera) ren4.SetActiveCamera(camera) ren1.GetActiveCamera().SetPosition(0.314753, -0.0699988, -0.264225) ren1.GetActiveCamera().SetFocalPoint(0.00188636, -0.136847, -5.84226e-09) ren1.GetActiveCamera().SetViewAngle(30) ren1.GetActiveCamera().SetViewUp(0, 1, 0) ren1.ResetCameraClippingRange() ren2.ResetCameraClippingRange() ren3.ResetCameraClippingRange() ren4.ResetCameraClippingRange() ren1.SetBackground(1, 1, 1) ren2.SetBackground(1, 1, 1) ren3.SetBackground(1, 1, 1) ren4.SetBackground(1, 1, 1) renWin.SetSize(500, 500) # render and interact with data iRen = vtk.vtkRenderWindowInteractor() iRen.SetRenderWindow(renWin); renWin.Render() img_file = "deciFranFace.png" vtk.test.Testing.compareImage(iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=25) vtk.test.Testing.interact()
def loadafmasmesh(path, flatten=True, gaussianblursize=5): # load the image img = misc.imread(path) if flatten: #if we want to remove the parabolic/spherical background from AFM image #make a kernal to scan with; This should be tested with more images to choose the best shape and size; #Current kernel is a 20x20 square kernel = np.ones((20, 20), np.uint8) #Remove background artifact img = img - np.minimum(img, cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)) #Add optional gaussian blur to denoise if gaussianblursize>0: img = cv2.GaussianBlur(img, (0, 0), gaussianblursize) #img = cv2.bilateralFilter(img,9,80,80) if img.shape.__len__()>2: if img.shape[2] == 3: #if the image is a 3 channel rgb average the channels img = np.sum(img, axis=2) / 3.0 #make a grid array for x and y xx, yy = np.mgrid[0:img.shape[0], 0:img.shape[1]] #make the array of points, then reshape it to an Nx3 array points = np.array([xx, yy, img]) points = points.reshape((3, img.shape[0] * img.shape[1])).T pointsforvtk = vtk.vtkPoints() polygondata=vtk.vtkPolyData() cellarray=vtk.vtkCellArray() delaunay=vtk.vtkDelaunay2D() boundary=vtk.vtkPolyData() pointsarray = numpytovtk(points) #print type(pointsarray) pointsforvtk.SetData(pointsarray) polygondata.SetPoints(pointsforvtk) boundary.SetPoints(polygondata.GetPoints()) boundary.SetPolys(cellarray) delaunay.SetInputData(polygondata) delaunay.SetSourceData(boundary) #print(delaunay.GetOutput()) #meshpoly=delaunay.GetOutput() decimator = vtk.vtkDecimatePro() decimator.SetInputConnection(delaunay.GetOutputPort()) decimator.SetTargetReduction(0.999) decimator.PreserveTopologyOn() #decimator.BoundaryVertexDeletionOff() decimator.Update() plotvtk(decimator,boundary) print "mesh finished" points,triangles=polytopointstriangles(decimator.GetOutput()) print(triangles.__len__()) return points, triangles
def __init__(self, filename, renderer): self.renderer = renderer reader = vtk.vtkStructuredPointsReader() #reader.SetFileName('/home/mcc/src/devel/extract_mri_slices/braintest2.vtk') reader.SetFileName(filename) # we want to move this from its (.87 .92 .43) esque position to something more like 'the center' # how to do this?!? # ALTERNATIVELY: we want to use vtkInteractorStyleTrackballActor # somewhere instead of the interactor controlling the main window and 3 planes imagedata = reader.GetOutput() #reader.SetFileName(filename) cf = vtk.vtkContourFilter() cf.SetInput(imagedata) # ??? cf.SetValue(0, 1) deci = vtk.vtkDecimatePro() deci.SetInput(cf.GetOutput()) deci.SetTargetReduction(.1) deci.PreserveTopologyOn() smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(deci.GetOutput()) smoother.SetNumberOfIterations(100) # XXX try to call SetScale directly on actor.. #self.scaleTransform = vtk.vtkTransform() #self.scaleTransform.Identity() #self.scaleTransform.Scale(.1, .1, .1) #transformFilter = vtk.vtkTransformPolyDataFilter() #transformFilter.SetTransform(self.scaleTransform) #transformFilter.SetInput(smoother.GetOutput()) #cf.SetValue(1, 2) #cf.SetValue(2, 3) #cf.GenerateValues(0, -1.0, 1.0) #deci = vtk.vtkDecimatePro() #deci.SetInput(cf.GetOutput()) #deci.SetTargetReduction(0.8) # decimate_value normals = vtk.vtkPolyDataNormals() #normals.SetInput(transformFilter.GetOutput()) normals.SetInput(smoother.GetOutput()) normals.FlipNormalsOn() """ tags = vtk.vtkFloatArray() tags.InsertNextValue(1.0) tags.InsertNextValue(0.5) tags.InsertNextValue(0.7) tags.SetName("tag") """ lut = vtk.vtkLookupTable() lut.SetHueRange(0, 0) lut.SetSaturationRange(0, 0) lut.SetValueRange(0.2, 0.55) contourMapper = vtk.vtkPolyDataMapper() contourMapper.SetInput(normals.GetOutput()) contourMapper.SetLookupTable(lut) ###contourMapper.SetColorModeToMapScalars() ###contourMapper.SelectColorArray("tag") self.contours = vtk.vtkActor() self.contours.SetMapper(contourMapper) #if (do_wireframe): #self.contours.GetProperty().SetRepresentationToWireframe() #elif (do_surface): self.contours.GetProperty().SetRepresentationToSurface() self.contours.GetProperty().SetInterpolationToGouraud() self.contours.GetProperty().SetOpacity(1.0) self.contours.GetProperty().SetAmbient(0.1) self.contours.GetProperty().SetDiffuse(0.1) self.contours.GetProperty().SetSpecular(0.1) self.contours.GetProperty().SetSpecularPower(0.1) # XXX arbitrarily setting scale to this #self.contours.SetScale(.1, .1,.1) renderer.AddActor(self.contours) # XXX: mcc will this work?!? print "PlaneWidgetsXYZ.set_image_data: setting EventHandler.set_vtkactor(self.contours)!" EventHandler().set_vtkactor(self.contours)
def execute(self, inputs, update = 0, last = 0): """ Execute the filter with given inputs and return the output """ if not lib.ProcessingFilter.ProcessingFilter.execute(self, inputs): return None self.progressObj.setProgress(0.0) self.updateProgress(None, "ProgressEvent") rightDataType = True labelImage = self.getInput(1) labelImage.Update() if "vtkImageData" in str(labelImage.__class__): rightDataType = (labelImage.GetScalarType() == 9) elif not "itkImageUL" in str(labelImage.__class__): rightDataType = False if not rightDataType: Logging.error("Incompatible data type", "Please convert the input to label data of type unsigned long. Segmented data can be labeled with 'Connected component labeling' or 'Object separation' in 'Segmentation -> Object Processing'.") origImage = self.getInput(2) origImage.Update() origRange = origImage.GetScalarRange() print "Input for label shape=",self.getInputDataUnit(1) print "Orig. dataunit = ",self.getInputDataUnit(2) diritk = dir(itk) if "LabelImageToStatisticsLabelMapFilter" in diritk and "LabelMap" in diritk and "StatisticsLabelObject" and "LabelGeometryImageFilter" in diritk: newITKStatistics = 1 else: newITKStatistics = 0 # Do necessary conversions of datatype origVTK = origImage if self.parameters["AvgInt"] or self.parameters["NonZero"] or newITKStatistics: origITK = self.convertVTKtoITK(origVTK) # Cannot have two convertVTKtoITK in same filter if self.parameters["AvgInt"] or self.parameters["Area"]: labelVTK = self.convertITKtoVTK(labelImage) if "itkImage" not in str(labelImage.__class__): extent = labelImage.GetWholeExtent() if extent[5] - extent[4] == 0: dim = 2 else: dim = 3 scalarType = labelImage.GetScalarType() if scalarType != 9: # Convert to unsigned long castVTK = vtk.vtkImageCast() castVTK.SetOutputScalarTypeToUnsignedLong() castVTK.SetInput(labelImage) labelImage = castVTK.GetOutput() labelImage.Update() vtkItk = eval("itk.VTKImageToImageFilter.IUL%d.New()"%dim) vtkItk.SetInput(labelImage) labelITK = vtkItk.GetOutput() labelITK.Update() else: labelITK = labelImage dim = labelITK.GetLargestPossibleRegion().GetSize().GetSizeDimension() # Initializations spacing = self.dataUnit.getSpacing() x, y, z = self.dataUnit.getVoxelSize() x *= 1000000 y *= 1000000 z *= 1000000 if z == 0: z = 1.0 vol = x * y * z voxelSizes = [x, y, z] values = [] centersofmass = [] umcentersofmass = [] avgints = [] avgintsstderrs = [] objIntSums = [] avgDists = [] avgDistsStdErrs = [] objAreasUm = [] objRoundness = [] objMinorLength = [] objMajorLength = [] objElongation = [] objAngleMinX = [] objAngleMinY = [] objAngleMinZ = [] objAngleMajX = [] objAngleMajY = [] objAngleMajZ = [] objSmoothness = [] ignoreLargest = 1 currFilter = self while currFilter: if currFilter.ignoreObjects > ignoreLargest: ignoreLargest = currFilter.ignoreObjects currFilter = currFilter.prevFilter startIntensity = ignoreLargest print "Ignoring",startIntensity,"first objects" if newITKStatistics: # Change spacing for correct results, or not #changeInfoLabel = itk.ChangeInformationImageFilter[labelITK].New() #changeInfoLabel.SetInput(labelITK) #changeInfoLabel.ChangeSpacingOn() #changeInfoOrig = itk.ChangeInformationImageFilter[origITK].New() #changeInfoOrig.SetInput(origITK) #changeInfoOrig.ChangeSpacingOn() if dim == 3: lm = itk.LabelMap._3.New() #changeInfoLabel.SetOutputSpacing(voxelSizes) #changeInfoOrig.SetOutputSpacing(voxelSizes) else: lm = itk.LabelMap._2.New() #changeInfoLabel.SetOutputSpacing(voxelSizes[:2]) #changeInfoOrig.SetOutputSpacing(voxelSizes[:2]) labelStatistics = itk.LabelImageToStatisticsLabelMapFilter[labelITK,origITK,lm].New() #labelStatistics.SetInput1(changeInfoLabel.GetOutput()) #labelStatistics.SetInput2(changeInfoOrig.GetOutput()) labelStatistics.SetInput1(labelITK) labelStatistics.SetInput2(origITK) if self.parameters["Area"]: labelStatistics.ComputePerimeterOn() labelStatistics.Update() labelMap = labelStatistics.GetOutput() numberOfLabels = labelMap.GetNumberOfLabelObjects() else: labelShape = itk.LabelShapeImageFilter[labelITK].New() labelShape.SetInput(labelITK) data = labelShape.GetOutput() data.Update() numberOfLabels = labelShape.GetNumberOfLabels() if self.parameters["AvgInt"]: avgintCalc = itk.LabelStatisticsImageFilter[origITK,labelITK].New() avgintCalc.SetInput(origITK) avgintCalc.SetLabelInput(labelITK) avgintCalc.Update() self.progressObj.setProgress(0.2) self.updateProgress(None, "ProgressEvent") # Area calculation pipeline if self.parameters["Area"]: voxelArea = x*y*2 + x*z*2 + y*z*2 largestSize = labelITK.GetLargestPossibleRegion().GetSize() # if 2D image, calculate area using volume if largestSize.GetSizeDimension() > 2 and largestSize.GetElement(2) > 1: areaSpacing = labelVTK.GetSpacing() objectThreshold = vtk.vtkImageThreshold() objectThreshold.SetInput(labelVTK) objectThreshold.SetOutputScalarTypeToUnsignedChar() objectThreshold.SetInValue(255) objectThreshold.SetOutValue(0) marchingCubes = vtk.vtkMarchingCubes() #marchingCubes.SetInput(labelVTK) marchingCubes.SetInput(objectThreshold.GetOutput()) massProperties = vtk.vtkMassProperties() massProperties.SetInput(marchingCubes.GetOutput()) areaDiv = (areaSpacing[0] / x)**2 if self.parameters["Smoothness"]: smoothDecimate = vtk.vtkDecimatePro() smoothProperties = vtk.vtkMassProperties() smoothDecimate.SetTargetReduction(0.9) smoothDecimate.PreserveTopologyOff() smoothDecimate.SetInput(marchingCubes.GetOutput()) smoothProperties.SetInput(smoothDecimate.GetOutput()) # Filter needed for axes calculations if self.parameters["Axes"] and newITKStatistics: labelGeometry = itk.LabelGeometryImageFilter[labelITK,labelITK].New() labelGeometry.SetCalculateOrientedBoundingBox(1) labelGeometry.SetInput(labelITK) labelGeometry.Update() # Get results and do some calculations for each object tott = 0 voxelSize = voxelSizes[0] * voxelSizes[1] * voxelSizes[2] for i in range(startIntensity, numberOfLabels+1): areaInUm = 0.0 avgInt = 0 avgIntStdErr = 0.0 roundness = 0.0 objIntSum = 0.0 minorLength = 0.0 majorLength = 0.0 elongation = 0.0 angleMinX = 0.0 angleMinY = 0.0 angleMinZ = 0.0 angleMajX = 0.0 angleMajY = 0.0 angleMajZ = 0.0 smoothness = 0.0 if newITKStatistics: try: labelObj = labelMap.GetLabelObject(i) except: continue volume = labelObj.GetSize() #com = labelObj.GetCenterOfGravity() com = labelObj.GetCentroid() c = [] c2 = [] for k in range(0,com.GetPointDimension()): v = com[k] v /= spacing[k] c.append(v) c2.append(v * voxelSizes[k]) if com.GetPointDimension() == 2: c.append(0) c2.append(0.0) if self.parameters["AvgInt"]: avgInt = labelObj.GetMean() avgIntStdErr = math.sqrt(labelObj.GetVariance()) / math.sqrt(volume) objIntSum = avgInt * volume #if self.parameters["Area"]: # areaInUm = labelObj.GetPerimeter() # roundness = labelObj.GetRoundness() # Get area of object, copied old way because roundness is not # working if self.parameters["Area"]: if largestSize.GetSizeDimension() > 2 and largestSize.GetElement(2) > 1: objectThreshold.ThresholdBetween(i,i) marchingCubes.SetValue(0,255) polydata = marchingCubes.GetOutput() polydata.Update() if polydata.GetNumberOfPolys() > 0: massProperties.Update() areaInUm = massProperties.GetSurfaceArea() / areaDiv else: areaInUm = voxelArea # Calculate roundness hypersphereR = ((3*volume*vol)/(4*math.pi))**(1/3.0) hypersphereArea = 3 * volume * vol / hypersphereR roundness = hypersphereArea / areaInUm # Calculate surface smoothness if self.parameters["Smoothness"]: # Smooth surface with vtkDecimatePro. polydata = smoothDecimate.GetOutput() polydata.Update() if polydata.GetNumberOfPolys() > 0: smoothProperties.Update() smoothArea = smoothProperties.GetSurfaceArea() / areaDiv smoothness = smoothArea / areaInUm else: areaInUm = volume * x * y if self.parameters["Axes"]: vert = labelGeometry.GetOrientedBoundingBoxVertices(i) vertices = [] for vNum in range(vert.size()): vertices.append(vert.pop()) boxVect = [] if dim == 3: vertNums = [1,2,4] else: vertNums = [1,2] for vertNum in vertNums: vertex1 = vertices[0] vertex2 = vertices[vertNum] boxVect.append([abs(vertex2[dimN]-vertex1[dimN]) * voxelSizes[dimN] for dimN in range(dim)]) boxVectLen = [] minAxNum = -1 majAxNum = -1 minorLength = -1 majorLength = -1 for num,vect in enumerate(boxVect): length = 0.0 for vectComp in vect: length += vectComp**2 length = math.sqrt(length) boxVectLen.append(length) if length > majorLength: majorLength = length majAxNum = num if length < minorLength or minorLength < 0: minorLength = length minAxNum = num elongation = majorLength / minorLength # Calculate angle between major, minor axes and x,y,z axes for dimN in range(dim): boxVect[minAxNum][dimN] /= minorLength boxVect[majAxNum][dimN] /= majorLength vecX = (1.0, 0.0, 0.0) vecY = (0.0, 1.0, 0.0) vecZ = (0.0, 0.0, 1.0) angleMinX = lib.Math.angle(boxVect[minAxNum], vecX) angleMinY = lib.Math.angle(boxVect[minAxNum], vecY) angleMinZ = lib.Math.angle(boxVect[minAxNum], vecZ) angleMajX = lib.Math.angle(boxVect[majAxNum], vecX) angleMajY = lib.Math.angle(boxVect[majAxNum], vecY) angleMajZ = lib.Math.angle(boxVect[majAxNum], vecZ) else: if not labelShape.HasLabel(i): continue else: volume = labelShape.GetVolume(i) centerOfMass = labelShape.GetCenterOfGravity(i) if self.parameters["AvgInt"]: avgInt = avgintCalc.GetMean(i) avgIntStdErr = math.sqrt(abs(avgintCalc.GetVariance(i))) / math.sqrt(volume) objIntSum = avgintCalc.GetSum(i) c = [] c2 = [] for k in range(0, dim): v = centerOfMass.GetElement(k) c.append(v) c2.append(v * voxelSizes[k]) if dim == 2: c.append(0) c2.append(0.0) # Get area of object if self.parameters["Area"]: if largestSize.GetSizeDimension() > 2 and largestSize.GetElement(2) > 1: objectThreshold.ThresholdBetween(i,i) marchingCubes.SetValue(0,255) polydata = marchingCubes.GetOutput() polydata.Update() if polydata.GetNumberOfPolys() > 0: massProperties.Update() areaInUm = massProperties.GetSurfaceArea() / areaDiv else: areaInUm = voxelArea # Calculate roundness hypersphereR = ((3*volume*vol)/(4*math.pi))**(1/3.0) hypersphereArea = 3 * volume * vol / hypersphereR roundness = hypersphereArea / areaInUm else: areaInUm = volume * x * y # Add object results to result arrays centersofmass.append(tuple(c)) umcentersofmass.append(tuple(c2)) values.append((volume, volume * vol)) avgints.append(avgInt) avgintsstderrs.append(avgIntStdErr) objIntSums.append(objIntSum) objAreasUm.append(areaInUm) objRoundness.append(roundness) objMinorLength.append(minorLength) objMajorLength.append(majorLength) objElongation.append(elongation) objAngleMinX.append(angleMinX) objAngleMinY.append(angleMinY) objAngleMinZ.append(angleMinZ) objAngleMajX.append(angleMajX) objAngleMajY.append(angleMajY) objAngleMajZ.append(angleMajZ) objSmoothness.append(smoothness) self.progressObj.setProgress(0.7) self.updateProgress(None, "ProgressEvent") # Do distance calculations t0 = time.time() for i, cm in enumerate(umcentersofmass): distList = [] if self.parameters["AvgDist"]: for j, cm2 in enumerate(umcentersofmass): if i == j: continue dx = cm[0] - cm2[0] dy = cm[1] - cm2[1] dz = cm[2] - cm2[2] dist = math.sqrt(dx*dx+dy*dy+dz*dz) distList.append(dist) avgDist, avgDistStd, avgDistStdErr = lib.Math.meanstdeverr(distList) avgDists.append(avgDist) avgDistsStdErrs.append(avgDistStdErr) print "Distance calculations took", time.time()-t0 self.progressObj.setProgress(0.8) self.updateProgress(None, "ProgressEvent") # Calculate average values and errors n = len(values) avgint, avgintstd, avgintstderr = lib.Math.meanstdeverr(avgints) intSum = sum(objIntSums, 0.0) ums = [x[1] for x in values] avgums, avgumsstd, avgumsstderr = lib.Math.meanstdeverr(ums) sumums = sum(ums, 0.0) pxs = [x[0] for x in values] avgpxs, avgpxsstd, avgpxsstderr = lib.Math.meanstdeverr(pxs) distMean, distStd, distStdErr = lib.Math.meanstdeverr(avgDists) avground, avgroundstd, avgroundstderr = lib.Math.meanstdeverr(objRoundness) avgAreaUm, avgAreaUmStd, avgAreaUmStdErr = lib.Math.meanstdeverr(objAreasUm) areaSumUm = sum(objAreasUm, 0.0) avgminlen, avgminlenstd, avgminlenstderr = lib.Math.meanstdeverr(objMinorLength) avgmajlen, avgmajlenstd, avgmajlenstderr = lib.Math.meanstdeverr(objMajorLength) avgelon, avgelonstd, avgelonstderr = lib.Math.meanstdeverr(objElongation) avgangminx, avgangminxstd, avgangminxstderr = lib.Math.meanstdeverr(objAngleMinX) avgangminy, avgangminystd, avgangminystderr = lib.Math.meanstdeverr(objAngleMinY) avgangminz, avgangminzstd, avgangminzstderr = lib.Math.meanstdeverr(objAngleMinZ) avgangmajx, avgangmajxstd, avgangmajxstderr = lib.Math.meanstdeverr(objAngleMajX) avgangmajy, avgangmajystd, avgangmajystderr = lib.Math.meanstdeverr(objAngleMajY) avgangmajz, avgangmajzstd, avgangmajzstderr = lib.Math.meanstdeverr(objAngleMajZ) avgsmooth, avgsmoothstd, avgsmoothstderr = lib.Math.meanstdeverr(objSmoothness) # Calculate average intensity outside objects avgIntOutsideObjs = 0.0 avgIntOutsideObjsStdErr = 0.0 avgIntOutsideObjsNonZero = 0.0 avgIntOutsideObjsNonZeroStdErr = 0.0 nonZeroVoxels = -1 if self.parameters["AvgInt"]: variances = 0.0 allVoxels = 0 for i in range(0,startIntensity): if newITKStatistics: try: labelObj = labelMap.GetLabelObject(i) voxelAmount = labelObj.GetSize() allVoxels += voxelAmount avgIntOutsideObjs += labelObj.GetMean() * voxelAmount variances += voxelAmount * abs(labelObj.GetVariance()) except: pass else: if labelShape.HasLabel(i): voxelAmount = labelShape.GetVolume(i) allVoxels += voxelAmount avgIntOutsideObjs += avgintCalc.GetMean(i) * voxelAmount if voxelAmount > 1: variances += voxelAmount * abs(avgintCalc.GetVariance(i)) if allVoxels > 0: avgIntOutsideObjs /= allVoxels avgIntOutsideObjsStdErr = math.sqrt(variances / allVoxels) / math.sqrt(allVoxels) labelAverage = vtkbxd.vtkImageLabelAverage() labelAverage.AddInput(origVTK) labelAverage.AddInput(labelVTK) labelAverage.SetBackgroundLevel(startIntensity) labelAverage.Update() avgIntOutsideObjsNonZero = labelAverage.GetAverageOutsideLabels() if labelAverage.GetVoxelsOutsideLabels() == 0: avgIntOutsideObjsNonZeroStdErr = 0.0 else: avgIntOutsideObjsNonZeroStdErr = labelAverage.GetOutsideLabelsStdDev() / math.sqrt(labelAverage.GetVoxelsOutsideLabels()) # Get also non zero voxels here that there is no need to recalculate nonZeroVoxels = labelAverage.GetNonZeroVoxels() self.progressObj.setProgress(0.9) self.updateProgress(None, "ProgressEvent") # Calculate average intensity inside objects avgIntInsideObjs = 0.0 avgIntInsideObjsStdErr = 0.0 if self.parameters["AvgInt"]: variances = 0.0 allVoxels = 0 for i in range(startIntensity, numberOfLabels+1): if newITKStatistics: try: labelObj = labelMap.GetLabelObject(i) voxelAmount = labelObj.GetSize() allVoxels += voxelAmount avgIntInsideObjs += labelObj.GetMean() * voxelAmount if voxelAmount > 1: variances += voxelAmount * abs(labelObj.GetVariance()) except: pass else: if labelShape.HasLabel(i): voxelAmount = labelShape.GetVolume(i) allVoxels += voxelAmount avgIntInsideObjs += avgintCalc.GetMean(i) * voxelAmount variances += voxelAmount * abs(avgintCalc.GetVariance(i)) if allVoxels > 0: avgIntInsideObjs /= allVoxels avgIntInsideObjsStdErr = math.sqrt(variances / allVoxels) / math.sqrt(allVoxels) # Calculate non-zero voxels if self.parameters["NonZero"] and nonZeroVoxels < 0: labelShape = itk.LabelShapeImageFilter[origITK].New() labelShape.SetInput(origITK) labelShape.Update() for i in range(1, int(origRange[1]) + 1): if labelShape.HasLabel(i): nonZeroVoxels += labelShape.GetVolume(i) # Set results self.values = values self.centersofmass = centersofmass self.umcentersofmass = umcentersofmass self.avgIntList = avgints self.avgIntStdErrList = avgintsstderrs self.intSums = objIntSums self.avgDistList = avgDists self.avgDistStdErrList = avgDistsStdErrs self.objAreasUm = objAreasUm self.objRoundness = objRoundness self.objMinorLength = objMinorLength self.objMajorLength = objMajorLength self.objElongation = objElongation self.objAngleMinX = objAngleMinX self.objAngleMinY = objAngleMinY self.objAngleMinZ = objAngleMinZ self.objAngleMajX = objAngleMajX self.objAngleMajY = objAngleMajY self.objAngleMajZ = objAngleMajZ self.intSum = intSum self.objSmoothness = objSmoothness #self.distMean = distMean #self.distStdErr = distStdErr #self.avgRoundness = avground #self.avgRoundnessStdErr = avgroundstderr #self.avgIntInsideObjs = avgIntInsideObjs #self.avgIntInsideObjsStdErr = avgIntInsideObjsStdErr #self.avgIntOutsideObjs = avgIntOutsideObjs #self.avgIntOutsideObjsStdErr = avgIntOutsideObjsStdErr #self.avgIntOutsideObjsNonZero = avgIntOutsideObjsNonZero #self.avgIntOutsideObjsNonZeroStdErr = avgIntOutsideObjsNonZeroStdErr self.setResultVariable("NumberOfObjects",len(values)) self.setResultVariable("ObjAvgVolInVoxels",avgpxs) self.setResultVariable("ObjAvgVolInUm",avgums) self.setResultVariable("ObjVolSumInUm",sumums) self.setResultVariable("ObjAvgAreaInUm",avgAreaUm) self.setResultVariable("ObjAreaSumInUm",areaSumUm) self.setResultVariable("ObjAvgIntensity",avgint) self.setResultVariable("AvgIntOutsideObjs", avgIntOutsideObjs) self.setResultVariable("AvgIntOutsideObjsNonZero", avgIntOutsideObjsNonZero) self.setResultVariable("AvgIntInsideObjs", avgIntInsideObjs) self.setResultVariable("NonZeroVoxels", nonZeroVoxels) self.setResultVariable("AverageDistance", distMean) self.setResultVariable("AvgDistanceStdErr", distStdErr) self.setResultVariable("ObjAvgVolInVoxelsStdErr",avgpxsstderr) self.setResultVariable("ObjAvgVolInUmStdErr",avgumsstderr) self.setResultVariable("ObjAvgAreaInUmStdErr",avgAreaUmStdErr) self.setResultVariable("ObjAvgIntensityStdErr",avgintstderr) self.setResultVariable("AvgIntOutsideObjsStdErr",avgIntOutsideObjsStdErr) self.setResultVariable("AvgIntOutsideObjsNonZeroStdErr",avgIntOutsideObjsNonZeroStdErr) self.setResultVariable("AvgIntInsideObjsStdErr",avgIntInsideObjsStdErr) self.setResultVariable("ObjIntensitySum", intSum) self.setResultVariable("ObjAvgRoundness",avground) self.setResultVariable("ObjAvgRoundnessStdErr",avgroundstderr) self.setResultVariable("ObjAvgMajorAxisLen",avgmajlen) self.setResultVariable("ObjAvgMajorAxisLenStdErr",avgmajlenstderr) self.setResultVariable("ObjAvgMinorAxisLen",avgminlen) self.setResultVariable("ObjAvgMinorAxisLenStdErr",avgminlenstderr) self.setResultVariable("ObjAvgElongation",avgelon) self.setResultVariable("ObjAvgElongationStdErr",avgelonstderr) self.setResultVariable("ObjAvgAngleXMajorAxis",avgangmajx) self.setResultVariable("ObjAvgAngleXMajorAxisStdErr",avgangmajxstderr) self.setResultVariable("ObjAvgAngleYMajorAxis",avgangmajy) self.setResultVariable("ObjAvgAngleYMajorAxisStdErr",avgangmajystderr) self.setResultVariable("ObjAvgAngleZMajorAxis",avgangmajz) self.setResultVariable("ObjAvgAngleZMajorAxisStdErr",avgangmajzstderr) self.setResultVariable("ObjAvgAngleXMinorAxis",avgangminx) self.setResultVariable("ObjAvgAngleXMinorAxisStdErr",avgangminxstderr) self.setResultVariable("ObjAvgAngleYMinorAxis",avgangminy) self.setResultVariable("ObjAvgAngleYMinorAxisStdErr",avgangminystderr) self.setResultVariable("ObjAvgAngleZMinorAxis",avgangminz) self.setResultVariable("ObjAvgAngleZMinorAxisStdErr",avgangminzstderr) self.setResultVariable("ObjAvgSmoothness",avgsmooth) self.setResultVariable("ObjAvgSmoothnessStdErr",avgsmoothstderr) self.stats = [n, avgums, avgumsstderr, avgpxs, avgpxsstderr, avgAreaUm, avgAreaUmStdErr, avgint, avgintstderr, avgIntOutsideObjs, avgIntOutsideObjsStdErr, distMean, distStdErr, sumums, areaSumUm, avgIntOutsideObjsNonZero, avgIntOutsideObjsNonZeroStdErr, avgIntInsideObjs, avgIntInsideObjsStdErr, nonZeroVoxels, avground, avgroundstderr, intSum, avgmajlen, avgmajlenstderr, avgminlen, avgminlenstderr, avgelon, avgelonstderr, avgangmajx, avgangmajxstderr, avgangmajy, avgangmajystderr, avgangmajz, avgangmajzstderr, avgangminx, avgangminxstderr, avgangminy, avgangminystderr, avgangminz, avgangminzstderr, avgsmooth, avgsmoothstderr] if self.reportGUI: self.reportGUI.DeleteAllItems() self.reportGUI.setVolumes(values) self.reportGUI.setCentersOfMass(centersofmass) self.reportGUI.setAverageIntensities(avgints, avgintsstderrs) self.reportGUI.setIntensitySums(objIntSums) self.reportGUI.setAverageDistances(avgDists, avgDistsStdErrs) self.reportGUI.setAreasUm(objAreasUm) self.reportGUI.setRoundness(objRoundness) self.reportGUI.setMajorAxisLengths(objMajorLength) self.reportGUI.setMinorAxisLengths(objMinorLength) self.reportGUI.setElongations(objElongation) self.reportGUI.setMajorAngles(objAngleMajX, objAngleMajY, objAngleMajZ) self.reportGUI.setMinorAngles(objAngleMinX, objAngleMinY, objAngleMinZ) self.reportGUI.setSmoothness(objSmoothness) self.totalGUI.setStats(self.stats) self.progressObj.setProgress(1.0) self.updateProgress(None, "ProgressEvent") return self.getInput(1)
def decimate(points, faces, reduction=0.5, smooth_steps=100, output_vtk=''): """ Decimate vtk triangular mesh with vtk.vtkDecimatePro. Parameters ---------- points : list of lists of floats each element is a list of 3-D coordinates of a vertex on a surface mesh faces : list of lists of integers each element is list of 3 indices of vertices that form a face on a surface mesh reduction : float fraction of mesh faces to remove smooth_steps : integer number of smoothing steps output_vtk : string output decimated vtk file Returns ------- points : list of lists of floats decimated points faces : list of lists of integers decimated faces output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.io_vtk import read_vtk, write_vtk >>> from mindboggle.utils.mesh import decimate >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> reduction = 0.5 >>> smooth_steps = 100 >>> output_vtk = '' >>> faces, lines, indices, points, npoints, scalars, scalar_names, ... o2 = read_vtk(input_vtk) >>> points, faces, output_vtk = decimate(points, faces, reduction, >>> smooth_steps, output_vtk) >>> len(points) == 4567 True >>> len(points) 4567 >>> # View: >>> write_vtk('decimated.vtk', points, indices, lines, faces, scalars, >>> scalar_names) # doctest: +SKIP >>> os.system('mayavi2 -d decimated.vtk -m Surface &') # doctest: +SKIP """ import os import vtk from mindboggle.utils.io_vtk import read_vtk # vtk points: vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] # vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() # Export output: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated_file.vtk') #exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(decimate.GetOutput()) smoother.SetNumberOfIterations(smooth_steps) smoother.Update() out = smoother.GetOutput() #exporter.SetInput(smoother.GetOutput()) else: decimate.Update() out = decimate.GetOutput() #exporter.SetInput(decimate.GetOutput()) #exporter.SetFileName(output_vtk) #exporter.Write() ## Extract points and faces: #faces, u1, u2, points, u4, u5, u6, u7 = read_vtk(output_vtk) points = [list(out.GetPoint(point_id)) for point_id in range(out.GetNumberOfPoints())] if out.GetNumberOfPolys() > 0: polys = out.GetPolys() faces = [[int(polys.GetData().GetValue(j)) for j in range(i*4 + 1, i*4 + 4)] for i in range(polys.GetNumberOfCells())] else: faces = [] return points, faces, output_vtk
def decimate_file(input_vtk, reduction=0.5, smooth_steps=100, output_vtk=''): """ Decimate vtk triangular mesh file with vtk.vtkDecimatePro. Parameters ---------- input_vtk : string input vtk file with triangular surface mesh reduction : float fraction of mesh faces to remove do_smooth : Boolean smooth after decimation? output_vtk : string output decimated vtk file Returns ------- output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.mesh import decimate_file >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> output_vtk = 'decimated_file.vtk' >>> reduction = 0.9 >>> smooth_steps = 0 >>> decimate_file(input_vtk, reduction=reduction, >>> smooth_steps=smooth_steps, output_vtk=output_vtk) >>> # View: >>> os.system('mayavi2 -d ' + output_vtk + ' -m Surface &') """ import os import vtk from mindboggle.utils.io_vtk import read_vtk # Read VTK surface mesh file: faces, u1, u2, points, u4, labels, u5, u6 = read_vtk(input_vtk) # vtk points: vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] # vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() # Export output: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated_file.vtk') exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(decimate.GetOutputPort()) smoother.SetNumberOfIterations(smooth_steps) exporter.SetInput(smoother.GetOutput()) else: exporter.SetInput(decimate.GetOutput()) exporter.SetFileName(output_vtk) exporter.Write() return output_vtk
# vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(decimate.GetOutputPort()) smoother.SetNumberOfIterations(smooth_steps) output = smoother.GetOutput() else: output = decimate.GetOutput()
def renderIBC(filePrefix, imgLow, imgHigh): global picker, redCone, greenCone # # This example reads a volume dataset, extracts an isosurface that # represents the skin and displays it. # # The following reader is used to read a series of 2D slices (images) # that compose the volume. The slice dimensions are set, and the # pixel spacing. The data Endianness must also be specified. The reader # usese the FilePrefix in combination with the slice number to construct # filenames using the format FilePrefix.%d. (In this case the FilePrefix # is the root name of the file: quarter.) #vtkVolume16Reader v13R # v13R SetDataDimensions 1388 1040 # v13R SetDataByteOrderToBigEndian # v13R SetFilePrefix "IBC146h.R_s" # v13R SetImageRange 0 44 # v13R SetDataSpacing 1 1 2 # Image reader v13G = vtk.vtkTIFFReader() v13G.SetDataExtent(1, 1380, 1, 1030, imgLow, imgHigh) v13G.SetDataByteOrderToLittleEndian() v13G.SetFilePrefix(filePrefix) v13G.SetDataSpacing(0.1, 0.1, 0.6) # Gaussian Smoothing gaus_v13G = vtk.vtkImageGaussianSmooth() gaus_v13G.SetDimensionality(3) gaus_v13G.SetStandardDeviation(1) gaus_v13G.SetRadiusFactors(1, 1, 1) gaus_v13G.SetInput(v13G.GetOutput()) # Set up the volume rendering volumeMapper = vtk.vtkVolumeTextureMapper3D() volumeMapper.SetInput(v13G.GetOutput()) volume = vtk.vtkVolume() volume.SetMapper(volumeMapper) # Surface rendering bactExtractor = vtk.vtkMarchingCubes() bactExtractor.SetInputConnection(gaus_v13G.GetOutputPort()) bactExtractor.SetValue(0,20000) # bactNormals = vtk.vtkPolyDataNormals() # bactNormals.SetInputConnection(bactExtractor.GetOutputPort()) # bactNormals.SetFeatureAngle(90.0) # # bactStripper = vtk.vtkStripper() # bactStripper.SetInputConnection(bactNormals.GetOutputPort()) # bactLocator = vtk.vtkCellLocator() bactLocator.SetDataSet(bactExtractor.GetOutput()) bactLocator.LazyEvaluationOn() # # bactMapper = vtk.vtkPolyDataMapper() # bactMapper.SetInputConnection(bactStripper.GetOutputPort()) # bactMapper.ScalarVisibilityOff() # skinE_v13G = vtk.vtkContourFilter() ## skinE_v13G = vtk.vtkMarchingCubes() # skinE_v13G.UseScalarTreeOn() # skinE_v13G.SetInput(gaus_v13G.GetOutput()) # skinE_v13G.SetValue(0, 10000) # smooth_v13G = vtk.vtkSmoothPolyDataFilter() smooth_v13G.SetInput(bactExtractor.GetOutput()) smooth_v13G.SetNumberOfIterations(50) deci_v13G = vtk.vtkDecimatePro() deci_v13G.SetInput(smooth_v13G.GetOutput()) deci_v13G.SetTargetReduction(0.5) deci_v13G.PreserveTopologyOn() smoother_v13G = vtk.vtkSmoothPolyDataFilter() smoother_v13G.SetInput(deci_v13G.GetOutput()) smoother_v13G.SetNumberOfIterations(50) skinNormals_v13G = vtk.vtkPolyDataNormals() skinNormals_v13G.SetInput(deci_v13G.GetOutput()) skinNormals_v13G.SetFeatureAngle(60.0) skinStripper_v13G = vtk.vtkStripper() skinStripper_v13G.SetInput(skinNormals_v13G.GetOutput()) skinMapper_v13G = vtk.vtkPolyDataMapper() skinMapper_v13G.SetInput(skinStripper_v13G.GetOutput()) skinMapper_v13G.ScalarVisibilityOff() skin_v13G = vtk.vtkActor() skin_v13G.SetMapper(skinMapper_v13G) skin_v13G.GetProperty().SetDiffuseColor(0.2, 1, 0.2) skin_v13G.GetProperty().SetSpecular(.1) skin_v13G.GetProperty().SetSpecularPower(5) skin_v13G.GetProperty().SetOpacity(0.9) # It is convenient to create an initial view of the data. The FocalPoint # and Position form a vector direction. Later on (ResetCamera() method) # this vector is used to position the camera to look at the data in # this direction. aCamera = vtk.vtkCamera() aCamera.SetViewUp(0, 0, -1) aCamera.SetPosition(0, 1.1, 2) aCamera.SetFocalPoint(0, -0.25, 0) aCamera.ComputeViewPlaneNormal() # Actors are added to the renderer. An initial camera view is created. # The Dolly() method moves the camera towards the FocalPoint, # thereby enlarging the image. #aRenderer AddActor skin_v13R ren.AddActor(skin_v13G) ren.SetActiveCamera(aCamera) ren.ResetCamera() aCamera.Dolly(1.0) # Note that when camera movement occurs (as it does in the Dolly() # method), the clipping planes often need adjusting. Clipping planes # consist of two planes: near and far along the view direction. The # near plane clips out objects in front of the plane the far plane # clips out objects behind the plane. This way only what is drawn # between the planes is actually rendered. ren.ResetCameraClippingRange() # render renWin.Render() # CONE PICKER RENDER #--------------------------------------------------------- # the cone points along the -x axis coneSource = vtk.vtkConeSource() coneSource.CappingOn() coneSource.SetHeight(2) coneSource.SetRadius(1) coneSource.SetResolution(11) coneSource.SetCenter(1,0,0) coneSource.SetDirection(-1,0,0) coneMapper = vtk.vtkDataSetMapper() coneMapper.SetInputConnection(coneSource.GetOutputPort()) redCone = vtk.vtkActor() redCone.PickableOff() redCone.SetMapper(coneMapper) redCone.GetProperty().SetColor(1,0,0) greenCone = vtk.vtkActor() greenCone.PickableOff() greenCone.SetMapper(coneMapper) greenCone.GetProperty().SetColor(0,1,0) # Add the two cones (or just one, if you want) ren.AddViewProp(redCone) ren.AddViewProp(greenCone) #--------------------------------------------------------- # the picker picker = vtk.vtkVolumePicker() picker.SetTolerance(1e-6) picker.SetVolumeOpacityIsovalue(0.1) # locator is optional, but improves performance for large polydata picker.AddLocator(bactLocator) #--------------------------------------------------------- # custom interaction iren.AddObserver("MouseMoveEvent", MoveCursor) # END CONE PICKER RENDER # initialize and start the interactor iren.Initialize() iren.Start()
def surface(points, triangles, labels, ctab=None, opacity=1, set_lut=True, decimation_ratio=1): """ Create a colored triangular surface. Parameters ---------- points: array (n_vertices, 3) the surface vertices. triangles: array nfaces x 3 array defining mesh triangles. labels: array (n_vertices) Annotation id at each vertex. If a vertex does not belong to any label its id must be negative. ctab: ndarray (n_labels, 5) (optional, default None) RGBA + label id color table array. If None a default blue to red 256 levels lookup table is used. opacity: float (optional, default 1) the actor global opacity. set_lut: bool (optional, default True) if True set a tuned lut. decimation_ratio: float (optional, default 1) how many triangles should reduced by specifying the percentage ([0,1]) of triangles to be removed. Returns ------- actor: vtkActor one actor handling the surface. """ # First setup points, triangles and colors vtk_points = vtk.vtkPoints() vtk_triangles = vtk.vtkCellArray() vtk_colors = vtk.vtkUnsignedCharArray() vtk_colors.SetNumberOfComponents(1) labels[numpy.where(labels < 0)] = 0 for index in range(len(points)): vtk_points.InsertNextPoint(points[index]) vtk_colors.InsertNextTuple1(labels[index]) for cnt, triangle in enumerate(triangles): vtk_triangle = vtk.vtkTriangle() vtk_triangle.GetPointIds().SetId(0, triangle[0]) vtk_triangle.GetPointIds().SetId(1, triangle[1]) vtk_triangle.GetPointIds().SetId(2, triangle[2]) vtk_triangles.InsertNextCell(vtk_triangle) # Make a lookup table using vtkColorSeries lut = vtk.vtkLookupTable() if ctab is not None: nb_of_labels = len(ctab) lut.SetNumberOfColors(nb_of_labels) lut.Build() for cnt, lut_element in enumerate(ctab): lut.SetTableValue( cnt, lut_element[0] / 255., lut_element[1] / 255., lut_element[2] / 255., lut_element[3] / 255.) lut.SetNanColor(1, 0, 0, 1) # This creates a blue to red lut. else: nb_of_labels = 255 lut.SetHueRange(0.667, 0.0) lut.SetNumberOfColors(nb_of_labels) lut.Build() # Create (geometry and topology) the associated polydata polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.GetPointData().SetScalars(vtk_colors) polydata.SetPolys(vtk_triangles) # Decimate the mesh decimate = vtk.vtkDecimatePro() decimate.SetInputConnection(polydata.GetProducerPort()) decimate.SetTargetReduction(decimation_ratio) # Create the mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInput(decimate.GetOutput()) if set_lut: mapper.SetLookupTable(lut) mapper.SetColorModeToMapScalars() mapper.SetScalarRange(0, nb_of_labels) mapper.SetScalarModeToUsePointData() else: mapper.ScalarVisibilityOff() # Create the actor actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetOpacity(opacity) actor.GetProperty().SetColor(0.9, 0.9, 0.9) return actor
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkDecimatePro(), 'Processing.', ('vtkPolyData',), ('vtkPolyData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInput(self.Surface) triangleFilter.Update() decimationFilter = vtk.vtkDecimatePro() decimationFilter.SetInput(triangleFilter.GetOutput()) decimationFilter.SetTargetReduction(self.TargetReduction) decimationFilter.SetBoundaryVertexDeletion(self.BoundaryVertexDeletion) decimationFilter.PreserveTopologyOn() decimationFilter.Update() cleaner = vtk.vtkCleanPolyData() cleaner.SetInput(decimationFilter.GetOutput()) cleaner.Update() triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInput(cleaner.GetOutput()) triangleFilter.Update() self.Surface = triangleFilter.GetOutput() if self.Surface.GetSource(): self.Surface.GetSource().UnRegisterAllOutputs()