def loadSurface(fname): reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(fileName) reader.Update() # Take the largest connected component connectFilter = vtk.vtkPolyDataConnectivityFilter() connectFilter.SetInputConnection(reader.GetOutputPort()) connectFilter.SetExtractionModeToLargestRegion() connectFilter.Update() normals = vtk.vtkPolyDataNormals() normals.SetInputConnection(connectFilter.GetOutputPort()) normals.Update() pd = normals.GetOutput() com = vtk.vtkCenterOfMass() com.SetInputData(pd) com.SetUseScalarsAsWeights(False) com.Update() center = com.GetCenter() # Mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(normals.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) prop = actor.GetProperty() prop.SetColor(vtk.vtkColor3d(hexCol("#873927"))) # Assign actor to the renderer prop.SetOpacity(0.35) return actor, center
def centroid(self): '''average of all vertices''' center = vtk.vtkCenterOfMass() center.SetInputData(self.polydata) center.SetUseScalarsAsWeights(False) center.Update() return center.GetCenter()
def calculate_center_of_gravity_vtk(self, ): '''Function to calculate the center of gravity .. Note:: The VTK Pytnon bindings must be installed to use this function Examples: This example assumes that a mesh has been read by bemio and mesh data is contained in a `PanelMesh` object called `mesh` >>> mesh.calculate_center_of_gravity_vtk() ''' if self.VTK_installed is False: raise VTK_Exception( 'VTK must be installed to access the calculate_center_of_gravity_vtk function' ) com = vtk.vtkCenterOfMass() if vtk.VTK_MAJOR_VERSION >= 6: com.SetInputData(self.vtp_mesh) else: com.SetInput(self.vtp_mesh) com.Update() self.center_of_gravity = com.GetCenter() print 'Calculated center of gravity assuming uniform material density'
def __init__(self, vtk_mesh, center_scale=False, name=None): center = vtk.vtkCenterOfMass() center.SetInputData(vtk_mesh) center.SetUseScalarsAsWeights(False) center.Update() self.old_centerpoint = center.GetCenter() self.centerpoint = center.GetCenter() self.old_polydata = vtk_mesh #I think that I'm being passed a PolyData now, instead of a vtk_mesh self.old_scale = np.linalg.norm( vtk_to_numpy(vtk_mesh.GetPoints().GetData()), 'fro') if center_scale: transform = vtk.vtkTransform() #bp() transform.Translate(-self.centerpoint[0], -self.centerpoint[1], -self.centerpoint[2]) transformt = vtk.vtkTransformPolyDataFilter() transformt.SetInputData(vtk_mesh) transformt.SetTransform(transform) transformt.Update() self.polydata = transformt.GetOutput() else: self.polydata = vtk_mesh self.name = name
def toOriginalPos(actor, center, rotationTransform): rotMat = vtk.vtkMatrix4x4() rotationTransform.GetTranspose(rotMat) rotTrans = vtk.vtkTransform() rotTrans.SetMatrix(rotMat) transformFilter = vtk.vtkTransformFilter() transformFilter.SetInputData(actor.GetMapper().GetInput()) transformFilter.SetTransform(rotTrans) transformFilter.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(transformFilter.GetOutputPort()) mapper.Update() actor.SetMapper(mapper) centerTransform = vtk.vtkTransform() centerTransform.Translate(center[0], center[1], center[2]) transformFilter = vtk.vtkTransformFilter() transformFilter.SetInputData(actor.GetMapper().GetInput()) transformFilter.SetTransform(centerTransform) transformFilter.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(transformFilter.GetOutputPort()) mapper.Update() actor.SetMapper(mapper) centerCalculer = vtk.vtkCenterOfMass() centerCalculer.SetInputData(actor.GetMapper().GetInput()) centerCalculer.SetUseScalarsAsWeights(False) centerCalculer.Update() center = centerCalculer.GetCenter() print(center)
def get_tangent_vec(contour_id, tangent_vec): # Export the provided contour to a usable VTK PolyData object. contour_set = sv.dmg.get_segmentation(contour_group_name) contour_pd = contour_set.get_segmentation(contour_id).get_polydata() # Apply a VTK filter to locate the center of mass (average) of the # points in the first contour. com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(contour_pd) com_filter.Update() center = com_filter.GetCenter() # Save the points in the first contour to a vtkPoints object and then # extract the first two points. contour_pts = contour_pd.GetPoints() point1 = contour_pts.GetPoint(0) point2 = contour_pts.GetPoint(5) # Calculate the vector (deltas in x, y, and z) between the center point # of the contour and two points on the contour. vec1 = [ point1[0] - center[0], point1[1] - center[1], point1[2] - center[2] ] vec2 = [ point2[0] - center[0], point2[1] - center[1], point2[2] - center[2] ] # Calculate the vector cross product of the two vectors, which is also # the tangent vector to the plane of the two points. vtk.vtkMath.Cross(vec1, vec2, tangent_vec)
def compute_pre_transformation(self, file_name): translation = [0, 0, 0] if self.config['pre-align']['align_center_of_mass']: # hack to avoid how the objimporter deals with multiple polydata pd = Utils3D.multi_read_surface(file_name) if pd.GetNumberOfPoints() < 1: print('Could not read', file_name) return None vtk_cm = vtk.vtkCenterOfMass() vtk_cm.SetInputData(pd) vtk_cm.SetUseScalarsAsWeights(False) vtk_cm.Update() cm = vtk_cm.GetCenter() translation = [-cm[0], -cm[1], -cm[2]] t = vtk.vtkTransform() t.Identity() rx = self.config['pre-align']['rot_x'] ry = self.config['pre-align']['rot_y'] rz = self.config['pre-align']['rot_z'] # Scale is handling by doing magic with the view frustrum elsewhere # s = self.config['pre-align']['scale'] # t.Scale(s, s, s) t.RotateY(ry) t.RotateX(rx) t.RotateZ(rz) t.Translate(translation) t.Update() return t
def read_mesh(file_name, scale): '''Read a VTK vtu file. ''' reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(file_name) reader.Update() mesh = reader.GetOutput() print("Mesh extent: {0:s}".format(str(mesh.GetBounds()))) com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(mesh) com_filter.Update() center = com_filter.GetCenter() print("Mesh center: {0:s}".format(str(center))) transform = vtk.vtkTransform() transform.Identity() transform.Scale(scale, scale, scale) transform.Translate(-center[0], -center[1], -center[2]) transform.Update() transform_filter = vtk.vtkTransformFilter() transform_filter.SetInputData(mesh) transform_filter.SetTransform(transform) transform_filter.Update() mesh = transform_filter.GetOutput() mesh.Modified() com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(mesh) com_filter.Update() center = com_filter.GetCenter() print("New mesh center: {0:s}".format(str(center))) print("New mesh extent: {0:s}".format(str(mesh.GetBounds()))) # check_nodes(mesh) #print_connectivity(mesh) num_points = mesh.GetNumberOfPoints() points = mesh.GetPoints() print("Number of points: {0:d}".format(num_points)) num_cells = mesh.GetNumberOfCells() print("Number of cells: {0:d}".format(num_cells)) cells = mesh.GetCells() return mesh
def find_centeroid(poly): ''' Return a 3x tuple ''' centerMass = vtk.vtkCenterOfMass() centerMass.SetInputData(poly) centerMass.SetUseScalarsAsWeights(False) centerMass.Update() return centerMass.GetCenter()
def findRadius(name, index): contour_group_name = name contour_group_name_in_repo = contour_group_name contour_ids = [index] repo_contour_ids = [ contour_group_name_in_repo + "_contour_" + str(id) for id in contour_ids ] try: # Does this item already exist in the Repository? if int(Repository.Exists(repo_contour_ids[0])): a = 5 else: GUI.ExportContourToRepos(contour_group_name, repo_contour_ids) # Calculate the centers of each contour in the segmentation group with a VTK # center of mass filter, then calculate the radius of the contour. contour_radii = [] for id in repo_contour_ids: # Export the id'th contour to a VTK polyData object. contour = Repository.ExportToVtk(id) # Apply a VTK filter to locate the center of mass (average) of the points in the contour. com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(contour) com_filter.Update() center = com_filter.GetCenter() # Save the points in the contour to a vtkPoints object. contour_pts = contour.GetPoints() # Iterate through the list of points, but not the last two. (last two are # control points that bung up the solution) radii = [] for point_index in range(contour_pts.GetNumberOfPoints() - 2): # Save the point to a cordinate list. coord = [0.0, 0.0, 0.0] contour_pts.GetPoint(point_index, coord) # Compute the "radius" between the current point and the center of the contour. # Distance formula: sqrt(dx^2 + dy^2 + dz^2) radii.append( math.sqrt( math.pow(coord[0] - center[0], 2) + math.pow(coord[1] - center[1], 2) + math.pow(coord[2] - center[2], 2))) # Append the average of the "radii" to the list of contour radii as the nominal radius of the current contour. contour_radii.append(numpy.mean(radii)) return (contour_radii[0]) except Exception as e: print("Error!" + str(e)) return
def centerOfMass(actor): '''Get the Center of Mass of the actor''' if vtkMV: #faster cmf = vtk.vtkCenterOfMass() setInput(cmf, polydata(actor, True)) cmf.Update() c = cmf.GetCenter() return np.array(c) else: pts = coordinates(actor, True) if not len(pts): return np.array([0, 0, 0]) return np.mean(pts, axis=0)
def calc_centers(self): """ Calculate the contour centers. Create a VTK center of mass filter to calculate contour centers. """ centers = [] for id in self.repo_contour_ids: print(id) contour = Repository.ExportToVtk(id) com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(contour) com_filter.Update() center = com_filter.GetCenter() centers.append(center) #_for id in self.repo_contor_ids self.centers = centers
def check_if_filt_tri_inside_PD(tripts, mesh): points1 =vtk.vtkPoints() points1.InsertNextPoint (triangle_points[0]) points1.InsertNextPoint (triangle_points[1]) points1.InsertNextPoint (triangle_points[2]) triangle =vtk.vtkTriangle() triangle.GetPointIds().SetId ( 0, 0 ) triangle.GetPointIds().SetId ( 1, 1 ) triangle.GetPointIds().SetId ( 2, 2 ) triangles = vtk.vtkCellArray() triangles.InsertNextCell(triangle) trianglePolyData =vtk.vtkPolyData() trianglePolyData.SetPoints( points1 ) trianglePolyData.SetPolys( triangles ) A=triangle_points[0] B=triangle_points[1] C=triangle_points[2] a_minus_b=A-B a_minus_C=A-C normtoplane=np.cross(a_minus_b,a_minus_C) centerOfMassFilter =vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(trianglePolyData) centerOfMassFilter.Update() center=centerOfMassFilter.GetCenter() plane = vtk.vtkPlane() plane.SetOrigin(center) plane.SetNormal(normtoplane) planeCut = vtk.vtkCutter() planeCut.SetInputData(mesh) planeCut.SetCutFunction(plane) planeCut.Update() num_inter= planeCut.GetOutput().GetNumberOfPoints() return num_inter
def GetGeomCenterOfMass(mesh): cellcenter=vtk.vtkCellCenters() cellcenter.SetInputData(mesh) cellcenter.Update() cell_centeroutput=cellcenter.GetOutput() cell_centeroutput_num=cell_centeroutput.GetNumberOfPoints() center=[0.0,0.0,0.0] centerOfMassFilter =vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(mesh) centerOfMassFilter.SetUseScalarsAsWeights(0) centerOfMassFilter.Update() xx=centerOfMassFilter.GetCenter() return xx,cell_centeroutput
def center_poly_data(poly_data): centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(poly_data) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() center = np.array(centerOfMassFilter.GetCenter()) transform = vtk.vtkTransform() transform.Translate(-center) transform_filter = vtk.vtkTransformPolyDataFilter() transform_filter.SetTransform(transform) transform_filter.SetInputData(poly_data) transform_filter.Update() poly_data = transform_filter.GetOutput() return poly_data
def doubleClickFunction(self, node): centerList = [0] * 3 # get center position of model/drawing if isinstance(node, slicer.vtkMRMLModelNode): pd = node.GetPolyData() center = vtk.vtkCenterOfMass() center.SetInputData(pd) center.Update() centerList = center.GetCenter() elif isinstance(node, slicer.vtkMRMLMarkupsCurveNode): node.GetNthControlPointPosition( round(node.GetNumberOfControlPoints() / 2), centerList) elif isinstance(node, slicer.vtkMRMLMarkupsFiducialNode): node.GetNthFiducialPosition(0, centerList) else: return self.centerPosition(centerList)
def centerCOM(polydata): # Get Center of Mass centerFilter = vtk.vtkCenterOfMass() centerFilter.SetInputData(polydata) centerFilter.SetUseScalarsAsWeights(False) centerFilter.Update() center = centerFilter.GetCenter() print(center) # Change Center to (0, 0, 0) transform = vtk.vtkTransform() transform.Translate(-center[0], -center[1], -center[2]) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputData(polydata) transformFilter.SetTransform(transform) transformFilter.Update() centeredPolydata = transformFilter.GetOutput() return centeredPolydata
def get_face_center(solid, face_id, color=[1, 0, 0]): ''' Get the center of a solid model face. ''' model_face = model_name + "_face_" + str(face_id) solid.get_face_polydata(model_face, face_id) face_pd = sv.repository.export_to_vtk(model_face) com_filter = vtk.vtkCenterOfMass() com_filter.SetInputData(face_pd) com_filter.Update() face_center = com_filter.GetCenter() # Show the face. face_actor = sv_vis.pRepos(renderer, model_face)[1] #sv_vis.polyDisplayWireframe(renderer, model_face_2) face_actor.GetProperty().SetColor(color[0], color[1], color[2]) return face_center
def center_of_mass(self, scalars_weight=False): """Return the coordinates for the center of mass of the mesh. Parameters ---------- scalars_weight : bool, optional Flag for using the mesh scalars as weights. Defaults to False. Return ------ center : np.ndarray, float Coordinates for the center of mass. """ alg = vtk.vtkCenterOfMass() alg.SetInputDataObject(self) alg.SetUseScalarsAsWeights(scalars_weight) alg.Update() return np.array(alg.GetCenter())
def information(poly): # get the maximum of z coordinate by the bounds bc = poly.GetBounds() num_points = poly.GetNumberOfPoints() p = [0, 0, 0] small_z = 1000 xof_small_z = 1000 yof_small_z = 1000 small_y = 1000 xof_small_y = 1000 zof_small_y = 1000 for point_index in range(num_points): poly.GetPoint(point_index, p) tmp = p[2] if tmp < small_z: small_z = tmp xof_small_z = p[0] yof_small_z = p[1] for point_index in range(num_points): poly.GetPoint(point_index, p) tmp = p[1] if tmp < small_y: small_y = tmp xof_small_y = p[0] zof_small_y = p[2] # in order to put center of mass as # origin we want to deduct the first one from the rest of the points com = vtk.vtkCenterOfMass() com.SetInputData(poly) com.SetUseScalarsAsWeights(False) com.Update() center = com.GetCenter() return [bc, center, xof_small_z, yof_small_z, small_z, xof_small_y, zof_small_y, small_y]
def calculate_center_of_gravity_vtk(self, ): '''Function to calculate the center of gravity .. Note:: The VTK Pytnon bindings must be installed to use this function Examples: This example assumes that a mesh has been read by bemio and mesh data is contained in a `PanelMesh` object called `mesh` >>> mesh.calculate_center_of_gravity_vtk() ''' if self.VTK_installed is False: raise VTK_Exception('VTK must be installed to access the calculate_center_of_gravity_vtk function') com = vtk.vtkCenterOfMass() com.SetInputData(self.vtp_mesh) com.Update() self.center_of_gravity = com.GetCenter() print 'Calculated center of gravity assuming uniform material density'
def onDoubleClick(self): nodeID = self.view.currentItem() if not nodeID: return shNode = slicer.mrmlScene.GetSubjectHierarchyNode() node = shNode.GetItemDataNode(nodeID) if not isinstance(node, slicer.vtkMRMLModelNode): return pd = node.GetPolyData() center = vtk.vtkCenterOfMass() center.SetInputData(pd) center.Update() centerList = center.GetCenter() # create markups node, add center as fiducial and jump and center slices markupsNode = slicer.mrmlScene.AddNewNodeByClass( 'vtkMRMLMarkupsFiducialNode') markupsNode.GetDisplayNode().SetVisibility(False) markupsNode.AddFiducialFromArray(np.array(centerList), '') markupsLogic = slicer.modules.markups.logic() markupsLogic.JumpSlicesToNthPointInMarkup(markupsNode.GetID(), 0, True) slicer.mrmlScene.RemoveNode(markupsNode)
def apply_pre_transformation(self, pd): translation = [0, 0, 0] if self.config['pre-align']['align_center_of_mass']: vtk_cm = vtk.vtkCenterOfMass() vtk_cm.SetInputData(pd) vtk_cm.SetUseScalarsAsWeights(False) vtk_cm.Update() cm = vtk_cm.GetCenter() translation = [-cm[0], -cm[1], -cm[2]] t = vtk.vtkTransform() t.Identity() rx = self.config['pre-align']['rot_x'] ry = self.config['pre-align']['rot_y'] rz = self.config['pre-align']['rot_z'] s = self.config['pre-align']['scale'] t.Scale(s, s, s) t.RotateY(ry) t.RotateX(rx) t.RotateZ(rz) t.Translate(translation) t.Update() # Transform (assuming only one mesh) trans = vtk.vtkTransformPolyDataFilter() trans.SetInputData(pd) trans.SetTransform(t) trans.Update() if self.config['pre-align']['write_pre_aligned']: name_out = str(self.config.temp_dir / ('pre_transform_mesh.vtk')) writer = vtk.vtkPolyDataWriter() writer.SetInputData(trans.GetOutput()) writer.SetFileName(name_out) writer.Write() return trans.GetOutput(), t
def RequestData(self, request, inInfo, outInfo): inp = vtk.vtkDataSet.GetData(inInfo[0]) vec = vtk.vtkDataSet.GetData(inInfo[1]) opt = vtk.vtkPolyData.GetData(outInfo) origin = np.array(self._normalLine.GetPoints().GetPoint(0)) normal = np.array(self._normalLine.GetPoints().GetPoint(1)) - origin if np.allclose(normal, [0, 0, 0]): centerFilter = vtk.vtkCenterOfMass() centerFilter.SetInputData(inp) centerFilter.SetUseScalarsAsWeights(False) centerFilter.Update() center = centerFilter.GetCenter() bounds = inp.GetBounds() origin = [ np.random.triangular(bounds[0], center[0], bounds[1]), np.random.triangular(bounds[2], center[1], bounds[3]), np.random.triangular(bounds[4], center[2], bounds[5]) ] normal = sample_spherical(1) self.SetOrigin(origin) self.SetNormal(normal) plane = vtk.vtkPlane() plane.SetNormal(normal[0], normal[1], normal[2]) plane.SetOrigin(origin[0], origin[1], origin[2]) #create cutter cutter = vtk.vtkCutter() cutter.SetCutFunction(plane) cutter.SetInputData(inp) cutter.Update() opt.ShallowCopy(cutter.GetOutput()) return 1
def CenterOfMass(self, scalars_weight=False): """ Returns the coordinates for the center of mass of the mesh. Parameters ---------- scalars_weight : bool, optional Flag for using the mesh scalars as weights. Defaults to False. Return ------ center : np.ndarray, float Coordinates for the center of mass. """ comfilter = vtk.vtkCenterOfMass() comfilter.SetInputData(self) comfilter.SetUseScalarsAsWeights(scalars_weight) comfilter.Update() center = np.array(comfilter.GetCenter()) return center
def Get_Centroids(self,surface_files,filenames): print ("-"*50) print ("------ Computing Centroids of Surface Outlets") Centroids={} count=0 for surface_file in surface_files: print ("----Processing %s"%filenames[count]) #Read the Surface File reader=vtk.vtkXMLPolyDataReader() reader.SetFileName(surface_file) reader.Update() #Get the Centroid centerOfMassFilter=vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData(reader.GetOutput()) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() center_=centerOfMassFilter.GetCenter() Centroids[filenames[count]]=[center_[0],center_[1],center_[2]] del reader,centerOfMassFilter count+=1 return Centroids
def run(self, inputVolume, Index): logging.info('Processing started') DosiFilmImage = inputVolume logging.info(DosiFilmImage) date = datetime.datetime.now() savepath = u"//s-grp/grp/RADIOPHY/Personnel/Aurélien Corroyer-Dulmont/3dSlicer/Field_Center_vs_Jaw_setting_TOMOTHERAPY_QC_Results/Results_" + str( date.day) + str(date.month) + str(date.year) + ".txt" logging.info(savepath) logging.info(Index) #### To get background intensity for the thershold value of the bloc # Create segmentation segmentationNode = slicer.vtkMRMLSegmentationNode() slicer.mrmlScene.AddNode(segmentationNode) segmentationNode.CreateDefaultDisplayNodes() # only needed for display segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode( DosiFilmImage) # Create segment backgroundSeed = vtk.vtkSphereSource() backgroundSeed.SetCenter(-40, -30, 0) backgroundSeed.SetRadius(5) backgroundSeed.Update() segmentationNode.AddSegmentFromClosedSurfaceRepresentation( backgroundSeed.GetOutput(), "Segment A", [1.0, 0.0, 0.0]) mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode() slicer.mrmlScene.AddNode(mergedLabelmapNode) sa = vtk.vtkStringArray() sa.InsertNextValue("Segment A") slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode( segmentationNode, sa, mergedLabelmapNode, DosiFilmImage) label = su.PullVolumeFromSlicer("LabelMapVolume") image = su.PullVolumeFromSlicer(DosiFilmImage) stat_filter_backgroundSeed = sitk.LabelIntensityStatisticsImageFilter() stat_filter_backgroundSeed.Execute(label, image) #attention à l'ordre meanBackground = stat_filter_backgroundSeed.GetMean(1) print(meanBackground) # Stockage du nom de la machine en utilisant le choix de l'utilisateur dans la class Widget if Index == 0: machineName = 'Tomotherapy 1' else: machineName = 'Tomotherapy 2' # Création de la segmentation segmentationNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentationNode") segmentationNode.CreateDefaultDisplayNodes() segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode( DosiFilmImage) logging.info(segmentationNode) # Création des segments editors temporaires segmentEditorWidget = slicer.qMRMLSegmentEditorWidget() segmentEditorWidget.setMRMLScene(slicer.mrmlScene) segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentEditorNode") segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode) segmentEditorWidget.setSegmentationNode(segmentationNode) segmentEditorWidget.setMasterVolumeNode(DosiFilmImage) # Création d'un segment après seuillage addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment( "IrradiatedBlocks") segmentEditorNode.SetSelectedSegmentID(addedSegmentID) segmentEditorWidget.setActiveEffectByName("Threshold") effect = segmentEditorWidget.activeEffect() #effect.setParameter("MinimumThreshold",str(22000)) #effect.setParameter("MaximumThreshold",str(55000)) effect.setParameter("MinimumThreshold", str(meanBackground / 5)) effect.setParameter("MaximumThreshold", str(meanBackground / 1.2)) effect.self().onApply() # Passage en mode closed surface pour calcul des centres n = slicer.util.getNode('Segmentation_1') s = n.GetSegmentation() ss = s.GetSegment('IrradiatedBlocks') ss.AddRepresentation('Closed surface', vtk.vtkPolyData()) # Division du segment en plusieurs segments (un par bloc d'irradiation) segmentEditorWidget.setActiveEffectByName("Islands") effect = segmentEditorWidget.activeEffect() effect.setParameter("Operation", str("SPLIT_ISLANDS_TO_SEGMENTS")) effect.setParameter("MinimumSize", 1000) effect.self().onApply() ######### Initialisation des variables fixes d'intérêt########### Segmentation_Name = 'Segmentation_1' Segment_Name = [ "IrradiatedBlocks", "IrradiatedBlocks -_1", "IrradiatedBlocks -_2", "IrradiatedBlocks -_3", "IrradiatedBlocks -_4", "IrradiatedBlocks -_5", "IrradiatedBlocks -_6" ] ListYaxisCenterOfBlock = [ 0, 0, 0, 0, 0, 0, 0 ] # initialisation de la liste contenant les valeurs Y centrales des blocs # Boucle de calcul des centres pour les 7 blocs (segment) i = 0 while i < len(Segment_Name): n = slicer.util.getNode(Segmentation_Name) s = n.GetSegmentation() ss = s.GetSegment(Segment_Name[i]) pd = ss.GetRepresentation('Closed surface') com = vtk.vtkCenterOfMass() com.SetInputData(pd) com.Update() com.GetCenter() # A voir mais je pense que cette ligne est inutile CenterOfBlock = com.GetCenter( ) # CenterOfBlock est alors un tuple avec plusieurs variables (coordonées x,y,z) YaxisCenterOfBlock = ( CenterOfBlock[1] ) # Sélection de la 2ème valeur du tuple (indice 1) qui est la valeur dans l'axe Y qui est l'unique valeure d'intérêt YaxisCenterOfBlock = abs( YaxisCenterOfBlock) # On passe en valeur absolue ListYaxisCenterOfBlock[i] = YaxisCenterOfBlock i += 1 logging.info(ListYaxisCenterOfBlock) ######### Calcul de la différence en Y entre les centres des différents blocs########### MaxYaxisCenter = max(ListYaxisCenterOfBlock) MinYaxisCenter = min(ListYaxisCenterOfBlock) DifferenceMaxInPixelYCenters = MaxYaxisCenter - MinYaxisCenter DifferenceMaxInMmYCenters = float(DifferenceMaxInPixelYCenters) DifferenceMaxInMmYCenters = DifferenceMaxInMmYCenters * 0.3528 # Pas élégant mais si je ne fais pas ça, il initialise DifferenceMaxInMmYCenters en tuple et pas en variable... ### Enonciation des résultats ### logging.info("Coordonnee Max en Y : " + str(MaxYaxisCenter)) logging.info("Coordonnee Min en Y : " + str(MinYaxisCenter)) logging.info("Difference maximale entre les blocs (en pixel) : " + str(DifferenceMaxInPixelYCenters)) logging.info("Difference maximale entre les blocs (en mm) : " + str(DifferenceMaxInMmYCenters)) ######### Création et remplissage fichier text pour stocker les résultats########### file = open(savepath, 'w') ### encodage du fichier pour écriture incluant les "é" ### file = codecs.open(savepath, encoding='utf-8') txt = file.read() file = codecs.open(savepath, "w", encoding='mbcs') date = datetime.datetime.now() file.write(u"Résultats test -Field Center vs Jaw setting-") file.write("\n\n") file.write("Machine : " + str(machineName)) file.write("\n\n") file.write("Date : " + str(date.day) + "/" + str(date.month) + "/" + str(date.year)) file.write("\n\n") file.write("\n\n") i = 0 for i in range( len(ListYaxisCenterOfBlock) ): # Boucle pour obtenir les coordonées Y des centres des 7 blocs file.write(u"Coordonnée Y du centre du bloc n°" + str(i + 1) + ": ") file.write(str(ListYaxisCenterOfBlock[i])) file.write("\n\n") file.write("\n\n") file.write(u"Coordonnée Max en Y : " + str(MaxYaxisCenter)) file.write("\n\n") file.write(u"Coordonnée Min en Y : " + str(MinYaxisCenter)) file.write("\n\n") file.write(u"Différence maximale entre les blocs (en pixel) : " + str(DifferenceMaxInPixelYCenters)) file.write("\n\n") file.write(u"Différence maximale entre les blocs (en mm) : " + str(DifferenceMaxInMmYCenters)) ######### Calcul de la conformité et mention dans le fichier résultats########### if 0 <= DifferenceMaxInMmYCenters < 0.5: Result = "Conforme" elif DifferenceMaxInMmYCenters > 0.5: Result = "Hors tolerance" else: Result = "Limite" #car si pas < ou > à 0.5 alors = à 0.5 if DifferenceMaxInMmYCenters < 0: logging.info( u"Valeur de la différence négative, problème dans l'image ou dans le programme, contactez Aurélien Corroyer-Dulmont tel : 5768" ) logging.info(Result) file.write("\n\n") file.write("\n\n") file.write(u"Résultat : " + str(Result)) file.close() logging.info('Processing completed') logging.info('\n\nResults are in the following file : ' + savepath) return True
def extractfeatures(self, DICOMImages, image_pos_pat, image_ori_pat, series_path, phases_series, VOI_mesh): """ Start pixVals for collection pixel values at VOI """ pixVals_margin = []; pixVals = [] Fmargin = {}; voxel_frameS = {} # necessary to read point coords VOIPnt = [0,0,0] ijk = [0,0,0] pco = [0,0,0] for i in range(len(DICOMImages)): # find mapping to Dicom space [transformed_image, transform_cube] = Display().dicomTransform(DICOMImages[i], image_pos_pat, image_ori_pat) if (i==0): # create mask from segmenation np_VOI_mask = self.createMaskfromMesh(VOI_mesh, transformed_image) for j in range( VOI_mesh.GetNumberOfPoints() ): VOI_mesh.GetPoint(j, VOIPnt) # extract pixID at location VOIPnt pixId = transformed_image.FindPoint(VOIPnt[0], VOIPnt[1], VOIPnt[2]) im_pt = [0,0,0] transformed_image.GetPoint(pixId,im_pt) inorout = transformed_image.ComputeStructuredCoordinates( im_pt, ijk, pco) if(inorout == 0): pass else: pixValx = transformed_image.GetScalarComponentAsFloat( ijk[0], ijk[1], ijk[2], 0) pixVals_margin.append(pixValx) # Now collect pixVals print "\n Saving %s" % 'Fmargin'+str(i) Fmargin['Fmargin'+str(i)] = pixVals_margin pixVals_margin = [] # extract pixID at inside VOIPnt VOI_scalars = transformed_image.GetPointData().GetScalars() np_VOI_imagedata = vtk_to_numpy(VOI_scalars) dims = transformed_image.GetDimensions() spacing = transformed_image.GetSpacing() np_VOI_imagedata = np_VOI_imagedata.reshape(dims[2], dims[1], dims[0]) np_VOI_imagedata = np_VOI_imagedata.transpose(2,1,0) #################### HERE GET INTERNAL PIXELS IT AND MASK IT OUT VOI_imagedata = np_VOI_imagedata[nonzero(np_VOI_mask)] for j in range( len(VOI_imagedata) ): pixValx = VOI_imagedata[j] pixVals.append(pixValx) # Now collect pixVals print "\n Saving %s" % 'F'+str(i) voxel_frameS['F'+str(i)] = pixVals pixVals = [] ############################################################## # Initialize features self.i_var = []; self.alln_F_r_i=[]; self.allmin_F_r_i=[]; self.allmax_F_r_i=[]; self.allmean_F_r_i=[]; self.allvar_F_r_i=[]; self.allskew_F_r_i=[]; self.allkurt_F_r_i=[] F_r_0 = array(voxel_frameS['F'+str(0)]).astype(float) n, min_max, meanFr, var_F_r_0, skew, kurt = stats.describe(F_r_0) self.i_var_max = 0 # Collect to Compute inhomogeneity variance of uptake and other variables for k in range(1,len(DICOMImages)): F_r_i = array(voxel_frameS['F'+str(k)]).astype(float) print "\nF_r_i parameters %s" % str(k) n_F_r_i, min_max_F_r_i, mean_F_r_i, var_F_r_i, skew_F_r_i, kurt_F_r_i = stats.describe(F_r_i) print("Number of internal voxels: {0:d}".format(n_F_r_i)) self.alln_F_r_i.append(n_F_r_i) print("Minimum: {0:8.6f} Maximum: {1:8.6f}".format(min_max_F_r_i[0], min_max_F_r_i[1])) self.allmin_F_r_i.append(min_max_F_r_i[0]) self.allmax_F_r_i.append(min_max_F_r_i[1]) print("Mean: {0:8.6f}".format(mean_F_r_i)) self.allmean_F_r_i.append(mean_F_r_i) print("Variance F_r_i: {0:8.6f}".format(var_F_r_i)) self.allvar_F_r_i.append(var_F_r_i) print("Skew : {0:8.6f}".format(skew_F_r_i)) self.allskew_F_r_i.append(skew_F_r_i) print("Kurtosis: {0:8.6f}".format(kurt_F_r_i)) self.allkurt_F_r_i.append(kurt_F_r_i) print("Variance of uptake: {0:8.6f}".format(var_F_r_i/var_F_r_0)) self.i_var.append( var_F_r_i/var_F_r_0 ) # Find max of change in variance of uptake if( self.i_var[k-1] > self.i_var_max): self.i_var_max = self.i_var[k-1] print("\nMax Variance of uptake: {0:8.6f}\n".format( self.i_var_max )) # Collect to Compute change in variance of uptake self.ii_var = [] self.ii_var_min = 1000 for k in range(len(DICOMImages)-1): F_r_i = array(voxel_frameS['F'+str(k)]).astype(float) F_r_iplus = array(voxel_frameS['F'+str(k+1)]).astype(float) n, min_max, meanFr, var_F_r_ith, skew, kurt = stats.describe(F_r_i) n, min_max, meanFr, var_F_r_iplus, skew, kurt = stats.describe(F_r_iplus) """change Variance of uptake:""" self.ii_var.append( var_F_r_ith/var_F_r_iplus ) # Find max of change in variance of uptake if( var_F_r_ith/var_F_r_iplus < self.ii_var_min): self.ii_var_min = var_F_r_ith/var_F_r_iplus print("Min change Variance of uptake: {0:8.6f}\n".format( self.ii_var_min )) # Extract features for sharpness of lesion margin, compute Margin gradient iii_var # The gradient is computed using convolution with a 3D sobel filter using scipy.ndimage.filters.sobel # The function generic_gradient_magnitude calculates a gradient magnitude using the function passed through derivative to calculate first derivatives. F_rmargin_0 = array(Fmargin['Fmargin'+str(0)]).astype(float) self.iii_var_max = -1000 iii_Sobelvar = [] # Collect to Compute variance of uptake and other variables for k in range(1,len(DICOMImages)): F_rmargin_i = array(Fmargin['Fmargin'+str(k)]).astype(float) margin_delta = F_rmargin_i-F_rmargin_0 # using first sobel and then prewitt sobel_grad_margin_delta = generic_gradient_magnitude(margin_delta, sobel) # compute feature Margin Gradient n, min_max, mean_sobel_grad_margin, var, skew, kurt = stats.describe(sobel_grad_margin_delta) n, min_max, mean_F_rmargin_i, var_F_r_ith, skew, kurt = stats.describe(F_rmargin_i) """Margin Gradient""" iii_Sobelvar.append( mean_sobel_grad_margin/mean_F_rmargin_i ) # Find max of Margin Gradient if( iii_Sobelvar[k-1] > self.iii_var_max): self.iii_var_max = iii_Sobelvar[k-1] self.iii_var_max_k = k print("Max Margin Gradient: {0:8.6f}".format( self.iii_var_max )) print("k for Max Margin Gradient: {0:8.6f}".format( self.iii_var_max_k )) # compute iv feature Variance of Margin Gradient # note: only computed from the subtraction frames of i and 0 where the margin gradient iii_var is maximum. self.ivVariance = [] F_rmargin_iv = array(Fmargin['Fmargin'+str(self.iii_var_max_k)]).astype(float) n, min_max, mean_F_rmargin_iv, var_F_r_ith, skew, kurt = stats.describe(F_rmargin_iv) margin_delta_iv = F_rmargin_iv-F_rmargin_0 # using first sobel and then prewitt sobel_grad_margin_delta_iv = generic_gradient_magnitude(margin_delta_iv, sobel) n, min_max, mean_sobel, var_sobel_grad_margin_delta_iv, skew, kurt = stats.describe(sobel_grad_margin_delta_iv) self.ivVariance = var_sobel_grad_margin_delta_iv/mean_F_rmargin_iv**2 print("Variance of spatial Margin Gradient: {0:8.6f}".format( self.ivVariance )) # Extract Shape features: pre-requisite is the Volume and the diameter of the lesion #################################### # Measure VOI ################################### VOI_massProperty = vtk.vtkMassProperties() VOI_massProperty.SetInputData(VOI_mesh) VOI_massProperty.Update() # get VOI volume # VTK is unitless. The units you get out are the units you put in. # If your input polydata has points defined in terms of millimetres, then # the volume will be in cubic millimetres. VOI_vol = VOI_massProperty.GetVolume() # mm3 VOI_surface = VOI_massProperty.GetSurfaceArea() # mm2 # just print the results print "\nVolume lesion = ", VOI_vol print "Surface lesion = ", VOI_surface # Calculate the effective diameter of the surface D=2(sqrt3(3V/(4pi))) diam_root = (3*VOI_vol)/(4*pi) self.VOI_efect_diameter = 2*pow(diam_root,1.0/3) print "VOI_efect_diameter = ", self.VOI_efect_diameter centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData( VOI_mesh ) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() # centroid of lesion self.lesion_centroid = [0,0,0] self.lesion_centroid = centerOfMassFilter.GetCenter() print "lesion_centroid = ", self.lesion_centroid # create a sphere to compute the volume of lesion within a sphere of effective diameter sphere_effectD = vtk.vtkSphereSource() sphere_effectD.SetRadius(self.VOI_efect_diameter/2) #VOI_diameter/2 sphere_effectD.SetCenter(self.lesion_centroid) sphere_effectD.Update() # compute volume of lesion within a sphere of effective diameter sphereVOI_massProperty = vtk.vtkMassProperties() sphereVOI_massProperty.SetInputData(sphere_effectD.GetOutput()) sphereVOI_massProperty.Update() sphereVOI_vol = sphereVOI_massProperty.GetVolume() # mm3 # just print the results print "Volume sphereVOI = ", sphereVOI_vol # Compute Shape of lesion in 3D # Circularity epsilon = 0.001 self.circularity = sphereVOI_vol/(VOI_vol+epsilon) print("\nCircularity: {0:8.6f}".format( self.circularity )) self.irregularity = 1 - pi*(self.VOI_efect_diameter/VOI_surface) print("Irregularity: {0:8.6f}".format( self.irregularity )) #################################### # Radial gradient analysis ref[9] white paper ################################### # Radial gradient analysis is based on examination of the angles between voxel-value gradients # and lines intersecting a single point near the center of the suspect lesion, lines in radial directions. # Radial gradient values are given by the dot product of the gradient direction and the radial direction. RGH_mean = []; self.max_RGH_mean = 0; self.max_RGH_mean_k = 0; RGH_var = []; self.max_RGH_var = 0; self.max_RGH_var_k = 0; H_norm_p = [] # do subtraction of timepost-pre #################### for i in range(1,len(DICOMImages)): subtractedImage = Display().subImage(DICOMImages, i) [transformed_image, transform_cube] = Display().dicomTransform(subtractedImage, image_pos_pat, image_ori_pat) for j in range( VOI_mesh.GetNumberOfPoints() ): VOI_mesh.GetPoint(j, VOIPnt) r = array(VOIPnt) rc = array(self.lesion_centroid) norm_rdir = (r-rc)/linalg.norm(r-rc) # Find point for gradient vectors at the margin point pixId = transformed_image.FindPoint(VOIPnt[0], VOIPnt[1], VOIPnt[2]) sub_pt = [0,0,0] transformed_image.GetPoint(pixId, sub_pt) ijk = [0,0,0] pco = [0,0,0] grad_pt = [0,0,0]; inorout = transformed_image.ComputeStructuredCoordinates( sub_pt, ijk, pco) if(inorout == 0): print "point outside data" else: transformed_image.GetPointGradient( ijk[0], ijk[1], ijk[2], transformed_image.GetPointData().GetScalars(), grad_pt) ############# # Compute vector in the direction gradient at margin point grad_marginpt = array([grad_pt]) norm_grad_marginpt = grad_marginpt/linalg.norm(grad_marginpt) # Compute dot product (unit vector for dot product) p_dot = dot(norm_grad_marginpt, norm_rdir) norm_p_dot = np.abs(p_dot)[0] #linalg.norm(p_dot) H_norm_p.append(norm_p_dot) # The histogram of radial gradient values quantifying the frequency of occurrence of the dot products in a given region of interest # radial gradient histogram. The hist() function now has a lot more options # first create a single histogram # the histogram of the data with histtype='step' # plt.figure() # nsamples, bins, patches = plt.hist(array(H_norm_p), 50, normed=1, histtype='bar',facecolor='blue', alpha=0.75) # n, min_max, mean_bins, var_bins, skew, kurt = stats.describe(nsamples) mean_bins = np.mean(H_norm_p) var_bins = np.var(H_norm_p) print("\n mean RGB: {0:8.6f}".format( mean_bins )) print("variance RGB: {0:8.6f}".format( var_bins )) # Append data RGH_mean.append( mean_bins ) RGH_var.append( var_bins ) # Find max of RGH Gradient if( RGH_mean[i-1] > self.max_RGH_mean): self.max_RGH_mean = RGH_mean[i-1] self.max_RGH_mean_k = i if( RGH_var[i-1] > self.max_RGH_var): self.max_RGH_var = RGH_var[i-1] self.max_RGH_var_k = i # add a line showing the expected distribution # create a histogram by providing the bin edges (unequally spaced) plt.xlabel('normalized dot product |R.G|') plt.ylabel('Probability') plt.title('radial gradient histogram') plt.grid(True) ################# Jacob's lesion margin sharpness #initializations VOI_outlinept_normal = [0,0,0]; VOI_outlinept = [0,0,0]; inpt = [0,0,0]; outpt = [0,0,0] im_pts = [0,0,0]; ijk_in = [0,0,0]; ijk_out = [0,0,0]; pco = [0,0,0]; SIout_pixVal=[]; lastSIout_pixVal=[] # get model_point_normals VOI_point_normals = vtk.vtkPolyDataNormals() VOI_point_normals.SetInputData( VOI_mesh ) VOI_point_normals.SetComputePointNormals(1) VOI_point_normals.SetComputeCellNormals(0) VOI_point_normals.SplittingOff() VOI_point_normals.FlipNormalsOff() VOI_point_normals.ConsistencyOn() VOI_point_normals.Update() # Retrieve model normals VOI_normalsRetrieved = VOI_point_normals.GetOutput().GetPointData().GetNormals() VOI_n = VOI_normalsRetrieved.GetNumberOfTuples() # obtain vols of interest [transf_pre_dicomReader, transform_cube] = Display().dicomTransform(DICOMImages[0], image_pos_pat, image_ori_pat) [transf_last_dicomReader, transform_cube] = Display().dicomTransform(DICOMImages[len(DICOMImages)-1], image_pos_pat, image_ori_pat) num_margin = [] den_margin = [] for i in range(1,len(DICOMImages)): #initializations SIout_pixVal=[] lastSIout_pixVal=[] subtractedImage = Display().subImage(DICOMImages, i) [transf_sub_pre_dicomReader, transform_cube] = Display().dicomTransform(subtractedImage, image_pos_pat, image_ori_pat) for k in range( VOI_n ): VOI_outlinept_normal = VOI_normalsRetrieved.GetTuple3(k) VOI_mesh.GetPoint(k, VOI_outlinept) # "d for radial lenght: %f" % d d = sqrt(spacing[0]**2 + spacing[1]**2 + spacing[2]**2) inpt[0] = VOI_outlinept[0] - VOI_outlinept_normal[0]*d inpt[1] = VOI_outlinept[1] - VOI_outlinept_normal[1]*d inpt[2] = VOI_outlinept[2] - VOI_outlinept_normal[2]*d outpt[0] = VOI_outlinept[0] + VOI_outlinept_normal[0]*d outpt[1] = VOI_outlinept[1] + VOI_outlinept_normal[1]*d outpt[2] = VOI_outlinept[2] + VOI_outlinept_normal[2]*d # get pre-contrast SIin to normalized RSIgroup [See equation 1] from paper prepixin = transf_pre_dicomReader.FindPoint(inpt[0], inpt[1], inpt[2]) transf_pre_dicomReader.GetPoint(prepixin,im_pts) transf_pre_dicomReader.ComputeStructuredCoordinates( im_pts, ijk_in, pco) #print ijk_in # get pre-contrast SIout in 6-c-neighbordhood to normalized RSIgroup [See equation 1] from paper prepixout = transf_pre_dicomReader.FindPoint(outpt[0], outpt[1], outpt[2]) transf_pre_dicomReader.GetPoint(prepixout,im_pts) transf_pre_dicomReader.ComputeStructuredCoordinates( im_pts, ijk_out, pco) #print ijk_out # get t-post SIin SIin_pixVal = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_in[0], ijk_in[1], ijk_in[2], 0 ) preSIin_pixVal = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_in[0], ijk_in[1], ijk_in[2], 0 )+epsilon RSIin = SIin_pixVal/preSIin_pixVal #### # get t-post SIout 6-c-neighbordhood #cn1 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]+1, ijk_out[1], ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]+1, ijk_out[1], ijk_out[2], 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) #cn2 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]-1, ijk_out[1], ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]-1, ijk_out[1], ijk_out[2], 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) #cn3 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]+1, ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]+1, ijk_out[2], 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) #cn4 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2], 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) #cn5 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1], ijk_out[2]+1, 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1], ijk_out[2]+1, 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) #cn6 SIout = transf_sub_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2]-1, 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2]-1, 0 )+epsilon SIout_pixVal.append(float(SIout/preSIout)) RSIout = mean( SIout_pixVal ) ### # get last-post SIout 6-c-neighbordhood #cn1 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0]+1, ijk_out[1], ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]+1, ijk_out[1], ijk_out[2], 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) #cn2 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0]-1, ijk_out[1], ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0]-1, ijk_out[1], ijk_out[2], 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) #cn3 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]+1, ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]+1, ijk_out[2], 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) #cn4 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2], 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2], 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) #cn5 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1], ijk_out[2]+1, 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1], ijk_out[2]+1, 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) #cn6 SIout = transf_last_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2]-1, 0 ) preSIout = transf_pre_dicomReader.GetScalarComponentAsFloat( ijk_out[0], ijk_out[1]-1, ijk_out[2]-1, 0 )+epsilon lastSIout_pixVal.append(float(SIout/preSIout)) # calculate RSIoutf = mean( lastSIout_pixVal ) ### compute feature num_margin.append( RSIin-RSIout ) den_margin.append( RSIin-RSIoutf ) #print num_margin #print den_margin SIout_pixVal=[] lastSIout_pixVal=[] self.edge_sharp_mean = mean(array(num_margin).astype(float)) / mean(array(den_margin).astype(float)) self.edge_sharp_std = std(array(num_margin).astype(float)) / std(array(den_margin).astype(float)) print "\n edge_sharp_mean: " print self.edge_sharp_mean print "\n edge_sharp_std: " print self.edge_sharp_std ################################################## # orgamize into dataframe self.morphologyFeatures = DataFrame( data=array([[ mean(self.allmin_F_r_i), mean(self.allmax_F_r_i),mean(self.allmean_F_r_i), mean(self.allvar_F_r_i), mean(self.allskew_F_r_i), mean(self.allkurt_F_r_i), self.i_var_max, self.ii_var_min, self.iii_var_max, self.iii_var_max_k, self.ivVariance, self.circularity, self.irregularity, self.edge_sharp_mean, self.edge_sharp_std, self.max_RGH_mean, self.max_RGH_mean_k, self.max_RGH_var, self.max_RGH_var_k ]]), columns=['min_F_r_i', 'max_F_r_i', 'mean_F_r_i', 'var_F_r_i', 'skew_F_r_i', 'kurt_F_r_i', 'iMax_Variance_uptake', 'iiMin_change_Variance_uptake', 'iiiMax_Margin_Gradient', 'k_Max_Margin_Grad', 'ivVariance', 'circularity', 'irregularity', 'edge_sharp_mean', 'edge_sharp_std', 'max_RGH_mean', 'max_RGH_mean_k', 'max_RGH_var', 'max_RGH_var_k']) return self.morphologyFeatures
def addSegment(self, lesion3D, color, interact): '''Add segmentation to current display''' # Set the planes based on seg bounds self.lesion_bounds = lesion3D.GetBounds() print "\n Mesh DICOM bounds: " print "xmin, xmax= [%d, %d]" % (self.lesion_bounds[0], self.lesion_bounds[1]) print "yin, ymax= [%d, %d]" % (self.lesion_bounds[2], self.lesion_bounds[3]) print "zmin, zmax= [%d, %d]" % (self.lesion_bounds[4], self.lesion_bounds[5]) ### GEt semgnetation information self.no_pts_segm = lesion3D.GetNumberOfPoints() print "no pts %d" % self.no_pts_segm # get VOI volume VOI_massProperty = vtk.vtkMassProperties() VOI_massProperty.SetInput(lesion3D) VOI_massProperty.Update() # VTK is unitless. The units you get out are the units you put in. # If your input polydata has points defined in terms of millimetres, then # the volume will be in cubic millimetres. self.VOI_vol = VOI_massProperty.GetVolume() # mm3 self.VOI_surface = VOI_massProperty.GetSurfaceArea() # mm2 # just print the results print "\nVolume lesion = ", self.VOI_vol print "Surface lesion = ", self.VOI_surface # Calculate the effective diameter of the surface D=2(sqrt3(3V/(4pi))) diam_root = (3*self.VOI_vol)/(4*pi) self.VOI_efect_diameter = 2*pow(diam_root,1.0/3) print "VOI_efect_diameter = ", self.VOI_efect_diameter centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInput( lesion3D ) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() # centroid of lesion self.lesion_centroid = [0,0,0] self.lesion_centroid = centerOfMassFilter.GetCenter() print "lesion_centroid = ", self.lesion_centroid self.lesioncentroidijk() # Add ICPinit_mesh.vtk to the render self.mapper_mesh = vtk.vtkPolyDataMapper() self.mapper_mesh.SetInput( lesion3D ) self.mapper_mesh.ScalarVisibilityOff() self.actor_mesh = vtk.vtkActor() self.actor_mesh.SetMapper(self.mapper_mesh) self.actor_mesh.GetProperty().SetColor(color) #R,G,B self.actor_mesh.GetProperty().SetOpacity(0.3) self.actor_mesh.GetProperty().SetPointSize(5.0) self.actor_mesh.GetProperty().SetRepresentationToWireframe() self.xImagePlaneWidget.SetSliceIndex(0) self.yImagePlaneWidget.SetSliceIndex(0) self.zImagePlaneWidget.SetSliceIndex( 0 ) self.renderer1.AddActor(self.actor_mesh) # Initizalize self.renderer1.Modified() self.renWin1.Render() self.renderer1.Render() if(interact==True): self.iren1.Start() return
def get_center(_mesh): centerofmass = vtk.vtkCenterOfMass() centerofmass.SetInputData(_mesh.GetOutput()) centerofmass.Update() return np.array(centerofmass.GetCenter())
MARCHING_CUBES_THRESHOLD = 0.01 #************* GET CENTER OF MASS OF WHOLE STRUCTURE SO WE CAN TRANSLATE PARTS #Run marching cubes on the whole input image fltMarching_whole = vtk.vtkMarchingCubes() #***** Discrete version instead? fltMarching_whole.SetInputData(imageData) fltMarching_whole.ComputeScalarsOff() fltMarching_whole.ComputeGradientsOff() fltMarching_whole.ComputeNormalsOn() fltMarching_whole.SetNumberOfContours(1) fltMarching_whole.SetValue(0, MARCHING_CUBES_THRESHOLD) fltMarching_whole.Update() centerFilter = vtk.vtkCenterOfMass() centerFilter.SetInputConnection(fltMarching_whole.GetOutputPort()) centerFilter.SetUseScalarsAsWeights(False) centerFilter.Update() center = centerFilter.GetCenter() transform = vtk.vtkTransform() transform.PostMultiply() transform.Translate(-center[0], -center[1], -center[2]) transform.RotateWXYZ(args.x_rot, 1, 0, 0) transform.RotateWXYZ(args.y_rot, 0, 1, 0) transform.RotateWXYZ(args.z_rot, 0, 0, 1) #************** GET RANGE OF LABELS imageScalars = imageData.GetPointData().GetScalars() iMin, iMax = imageScalars.GetValueRange() assert iMin == 0
def Initialize(self): self.renderer = vtk.vtkRenderer() self.vtkWidget.GetRenderWindow().AddRenderer(self.renderer) self.interactor = self.vtkWidget.GetRenderWindow().GetInteractor() self.centerOfPolyData = vtk.vtkCenterOfMass() self.markedTissues = [] self.sister1 = None # set these two as sisters self.sister2 = None self.calToMarkTissues() self.resetActors() self.fillListWidget() self.addActorsToRender() self.calCenter() self.setupCamera() self.zoomExtents() self.myInteractorStyle = interact.MyInteractorStyle() self.interactor.SetInteractorStyle(self.myInteractorStyle) if (not self.isTraining): self.createCSVfile() def kayboardPressedActor(obj, ev): self.logFile.recordPress("Keyboard", obj.GetKeySym(), self.camera.GetPosition(), self.camera.GetFocalPoint(), self.camera.GetDistance()) self.interactor.AddObserver('KeyPressEvent', kayboardPressedActor, -1.0) def wheelForward(obj, ev): self.logFile.record3DInteraction("ZoomIn", self.camera.GetPosition(), self.camera.GetFocalPoint(), self.camera.GetDistance()) def wheelBackward(obj, ev): self.logFile.record3DInteraction("ZoomOut", self.camera.GetPosition(), self.camera.GetFocalPoint(), self.camera.GetDistance()) self.interactor.AddObserver('MouseWheelForwardEvent', wheelForward, -1.0) self.interactor.AddObserver('MouseWheelBackwardEvent', wheelBackward, -1.0) self.lastSingleClicked = None self.lastDoubleClicked = None self.numberOfClicks = 0 self.prePosition = [0, 0] self.resetPixelDistance = 0 def leftClickedActorHighlight(obj, ev): self.numberOfClicks += 1 clickPos = obj.GetEventPosition() xdist = clickPos[0] - self.prePosition[0] ydist = clickPos[1] - self.prePosition[1] self.prePosition = clickPos moveDistance = int(math.sqrt(xdist * xdist + ydist * ydist)) picker = vtk.vtkPropPicker() picker.Pick(clickPos[0], clickPos[1], 0, obj.FindPokedRenderer(clickPos[0], clickPos[1])) NewPickedActor = picker.GetActor() if (moveDistance > self.resetPixelDistance): self.numberOfClicks = 1 if (NewPickedActor and NewPickedActor in self.modelActors): index = self.modelActors.index(NewPickedActor) if (index != self.lastDoubleClicked): if (self.lastSingleClicked != None and self.lastSingleClicked != index and self.lastSingleClicked not in self.markedTissues): self.modelActors[ self.lastSingleClicked].GetProperty().DeepCopy( self.originalProperty[ self.lastSingleClicked]) # if in focus view, highlight item in the neighbor list. or highlight in tissue list if (self.lastDoubleClicked != None and self.lastSingleClicked != index and self.lastDoubleClicked not in self.markedTissues): self.highlightList(self.neighborList, self.findIndexOfOri(index)) if (self.findIndexOfOri(index) in self.neighbors): self.formNeighborText( index, self.neighbors.index( self.findIndexOfOri(index))) interact.highLightNeighbor( self.modelActors[index].GetProperty()) if (not self.isTraining): self.logFile.updateSister( 2, self.findIndexOfOri(index), self.neighbors.index( self.findIndexOfOri(index)), fixedSurface.outsideOrInside( self.findIndexOfOri(index))) else: self.highlightList(self.tissueList, index) interact.highLightTissue( self.modelActors[index].GetProperty()) self.lastSingleClicked = index if (not self.isTraining): self.logFile.recordClick("Click", "MainView", self.findIndexOfOri(index), self.camera.GetPosition(), self.camera.GetFocalPoint(), self.camera.GetDistance()) if (self.numberOfClicks == 2): if (NewPickedActor and NewPickedActor in self.modelActors): index = self.modelActors.index(NewPickedActor) if (self.lastDoubleClicked != None and index != self.lastDoubleClicked): self.numberOfClicks = 0 return if (self.textOn == True and index == self.lastDoubleClicked): self.renderer.RemoveActor2D(self.neighborTextActor) self.textOn = False self.highlightList(self.tissueList, index) self.showNeighbors(self.findIndexOfOri(index)) if (self.lastSingleClicked != None and self.lastSingleClicked not in self.markedTissues): self.modelActors[ self.lastSingleClicked].GetProperty().DeepCopy( self.originalProperty[self.lastSingleClicked]) self.lastSingleClicked = None # if (self.lastDoubleClicked != None and self.lastDoubleClicked not in self.markedTissues): # self.modelActors[self.lastDoubleClicked].GetProperty().DeepCopy(self.originalProperty[self.lastDoubleClicked]) if (self.lastDoubleClicked == None): for actor in self.renderer.GetActors(): self.renderer.RemoveActor(actor) self.renderer.AddActor(self.modelActors[index]) interact.highLightTissue( self.modelActors[index].GetProperty()) neighbors = self.neighborsInOrderOfCells[ self.findIndexOfOri(index)].copy() for neighbor in neighbors: if (self.findIndexOfList(neighbor) not in self.markedTissues): self.renderer.AddActor(self.modelActors[ self.findIndexOfList(neighbor)]) if (not self.isTraining): self.logFile.updateSister( 1, self.findIndexOfOri(index), len(neighbors), fixedSurface.outsideOrInside( self.findIndexOfOri(index))) self.camera.SetFocalPoint( self.modelActors[index].GetCenter()) # interact.highLightTissue(self.modelActors[index].GetProperty()) self.lastDoubleClicked = index elif (self.lastDoubleClicked == index): if (not self.isTraining): self.logFile.updateSister(1, "-", "-", "-") self.logFile.updateSister(2, "-", "-", "-") for actor in self.modelActors: if (self.modelActors.index(actor) not in self.markedTissues and actor not in self.renderer.GetActors()): self.renderer.AddActor(actor) self.modelActors[index].GetProperty().DeepCopy( self.originalProperty[self.lastDoubleClicked]) self.lastDoubleClicked = None self.lastSingleClicked = None self.neighborList.clear() self.vtkWidget.GetRenderWindow().Render() if (not self.isTraining): self.logFile.recordClick("DoubleClick", "MainView", self.findIndexOfOri(index), self.camera.GetPosition(), self.camera.GetFocalPoint(), self.camera.GetDistance()) self.numberOfClicks = 0 self.interactor.AddObserver('LeftButtonPressEvent', leftClickedActorHighlight, -1.0) self.tissueList.itemSelectionChanged.connect(self.listPressed) self.tissueList.itemDoubleClicked.connect(self.listDoubleClicked) self.neighborList.itemSelectionChanged.connect( self.neighborListClicked) self.setAsSisterButton.clicked.connect(self.clickSetSister) self.interactor.Initialize() self.interactor.Start()
def addSegment(self, lesion3D, color, interact=False): '''Add segmentation to current display''' # Set the planes based on seg bounds self.lesion_bounds = lesion3D.GetBounds() print "\n Mesh DICOM bounds: " print "xmin, xmax= [%d, %d]" % (self.lesion_bounds[0], self.lesion_bounds[1]) print "yin, ymax= [%d, %d]" % (self.lesion_bounds[2], self.lesion_bounds[3]) print "zmin, zmax= [%d, %d]" % (self.lesion_bounds[4], self.lesion_bounds[5]) ### GEt semgnetation information self.no_pts_segm = lesion3D.GetNumberOfPoints() print "no pts %d" % self.no_pts_segm # get VOI volume VOI_massProperty = vtk.vtkMassProperties() VOI_massProperty.SetInputData(lesion3D) VOI_massProperty.Update() # VTK is unitless. The units you get out are the units you put in. # If your input polydata has points defined in terms of millimetres, then # the volume will be in cubic millimetres. self.VOI_vol = VOI_massProperty.GetVolume() # mm3 self.VOI_surface = VOI_massProperty.GetSurfaceArea() # mm2 # just print the results print "\nVolume lesion = ", self.VOI_vol print "Surface lesion = ", self.VOI_surface # Calculate the effective diameter of the surface D=2(sqrt3(3V/(4pi))) diam_root = (3*self.VOI_vol)/(4*pi) self.VOI_efect_diameter = 2*pow(diam_root,1.0/3) print "VOI_efect_diameter = ", self.VOI_efect_diameter centerOfMassFilter = vtk.vtkCenterOfMass() centerOfMassFilter.SetInputData( lesion3D ) centerOfMassFilter.SetUseScalarsAsWeights(False) centerOfMassFilter.Update() # centroid of lesion self.lesion_centroid = [0,0,0] self.lesion_centroid = centerOfMassFilter.GetCenter() print "lesion_centroid = ", self.lesion_centroid # Add ICPinit_mesh.vtk to the render self.mapper_mesh = vtk.vtkPolyDataMapper() self.mapper_mesh.SetInputData( lesion3D ) self.mapper_mesh.ScalarVisibilityOff() self.actor_mesh = vtk.vtkActor() self.actor_mesh.SetMapper(self.mapper_mesh) self.actor_mesh.GetProperty().SetColor(color) #R,G,B self.actor_mesh.GetProperty().SetOpacity(0.3) self.actor_mesh.GetProperty().SetPointSize(5.0) self.actor_mesh.GetProperty().SetRepresentationToWireframe() self.xImagePlaneWidget.SetSliceIndex(0) self.yImagePlaneWidget.SetSliceIndex(0) self.zImagePlaneWidget.SetSliceIndex( 0 ) self.renderer1.AddActor(self.actor_mesh) # Initizalize self.renderer1.Modified() self.renWin1.Render() self.renderer1.Render() if(interact==True): self.iren1.Start() return
def getCenterOfMass(self,contour): comFilter = vtk.vtkCenterOfMass() comFilter.SetInputData(contour) comFilter.SetUseScalarsAsWeights(False) comFilter.Update() return comFilter.GetCenter()