def addAppliedToolToSegment(self, segment, toolName, toolType=None): self.updatingSegmentTags = True # append list of applied tools tools = vtk.mutable('') tools = str(tools).split(';') if segment.GetTag( 'QuantitativeReporting.AppliedTools', tools) else [] if not toolName in tools: tools.append(toolName) segment.SetTag('QuantitativeReporting.AppliedTools', ";".join(tools)) segmentWasImported = tools[0] != 'Add' # determine algorithm type (if not specified by user) if not toolType: if toolName in self.manualTools: toolType = 'MANUAL' elif toolName in self.automaticTools: toolType = 'AUTOMATIC' else: # default tool type toolType = 'SEMIAUTOMATIC' # update DICOM algorithm type oldAlgorithmType = vtk.mutable('') segment.GetTag('DICOM.SegmentAlgorithmType', oldAlgorithmType) updatedAlgorithmType = oldAlgorithmType if oldAlgorithmType == '': # no other editor effect was applied before if segmentWasImported: updatedAlgorithmType = 'SEMIAUTOMATIC' else: updatedAlgorithmType = toolType elif oldAlgorithmType == 'MANUAL' and toolType != 'MANUAL': updatedAlgorithmType = 'SEMIAUTOMATIC' elif oldAlgorithmType == 'AUTOMATIC': updatedAlgorithmType = 'SEMIAUTOMATIC' if oldAlgorithmType != updatedAlgorithmType: segment.SetTag('DICOM.SegmentAlgorithmType', updatedAlgorithmType) # update DICOM algorithm name GenericSlicerAlgorithmName = slicer.app.applicationName + ' ' + slicer.app.applicationVersion GenericSegmentEditorAlgorithmName = GenericSlicerAlgorithmName + ' Segment Editor' ToolSegmentEditorAlgorithmName = GenericSlicerAlgorithmName + ' ' + toolName + ' Effect' oldAlgorithmName = vtk.mutable('') segment.GetTag('DICOM.SegmentAlgorithmName', oldAlgorithmName) updatedAlgorithmName = oldAlgorithmName if oldAlgorithmName == '': # no other editor tool was applied before if segmentWasImported: updatedAlgorithmName = GenericSlicerAlgorithmName else: updatedAlgorithmName = ToolSegmentEditorAlgorithmName elif oldAlgorithmName != ToolSegmentEditorAlgorithmName: if oldAlgorithmName.startswith(GenericSegmentEditorAlgorithmName): updatedAlgorithmName = GenericSegmentEditorAlgorithmName else: updatedAlgorithmName = GenericSlicerAlgorithmName if oldAlgorithmName != updatedAlgorithmName: segment.SetTag('DICOM.SegmentAlgorithmName', updatedAlgorithmName) self.updatingSegmentTags = False
def main(): # Create a square in the x-y plane. points = vtk.vtkPoints() points.InsertNextPoint(0.0, 0.0, 0.0) points.InsertNextPoint(1.0, 0.0, 0.0) points.InsertNextPoint(1.0, 1.0, 0.0) points.InsertNextPoint(0.0, 1.0, 0.0) # Create the polygon polygon = vtk.vtkPolygon() polygon.GetPoints().DeepCopy(points) polygon.GetPointIds().SetNumberOfIds(4) # The 4 corners of the square for i in range(4): polygon.GetPointIds().SetId(i, i) # Inputs p1 = [0.1, 0, -1.0] p2 = [0.1, 0, 1.0] tolerance = 0.001 # Outputs t = vtk.mutable( 0 ) # Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) x = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] subId = vtk.mutable(0) iD = polygon.IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId) print('intersected? ', 'Yes' if iD == 1 else 'No') print('intersection: ', x)
def get_external_surface(_mesh, external=True): _center = np.zeros(3) _bounds = np.zeros(6) _ray_start = np.zeros(3) cell_id = vtk.mutable(-1) xyz = np.zeros(3) pcoords = np.zeros(3) t = vtk.mutable(0) sub_id = vtk.mutable(0) if external: surf = 1.1 else: surf = -1.1 _mesh.GetOutput().GetCenter(_center) _mesh.GetOutput().GetPoints().GetBounds(_bounds) for j in range(3): _ray_start[j] = _bounds[2 * j + 1] * surf cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(_mesh.GetOutput()) cell_locator.BuildLocator() cell_locator.IntersectWithLine(_ray_start, _center, 0.0001, t, xyz, pcoords, sub_id, cell_id) print('ID of the cell on the outer surface: {}'.format(cell_id)) connectivity_filter = vtk.vtkConnectivityFilter() connectivity_filter.SetInputConnection(_mesh.GetOutputPort()) connectivity_filter.SetExtractionModeToCellSeededRegions() connectivity_filter.InitializeSeedList() connectivity_filter.AddSeed(cell_id) connectivity_filter.Update() return connectivity_filter
def onAddButton(self): print " -- Adding Keyframe at t =", self.Time camera = slicer.mrmlScene.CreateNodeByClass('vtkMRMLCameraNode') slicer.mrmlScene.AddNode(camera) x = vtk.mutable(0) y = vtk.mutable(0) z = vtk.mutable(0) value = [x, y, z] self.defaultCam.GetPosition(value) camera.SetPosition(value) self.defaultCam.GetFocalPoint(value) camera.SetFocalPoint(value) self.defaultCam.GetViewUp(value) camera.SetViewUp(value) cameraName = 'Camera T = ' + str(self.Time) print cameraName camera.SetName(cameraName) self.cameraPath.AddKeyFrame(self.Time, camera) self.Time += 100 self.CameraList.append(camera) self.FlyButton.setEnabled(False)
def _createSegmentData(self, segmentID): segmentData = dict() segmentData["labelID"] = 1 segment = self.segmentationNode.GetSegmentation().GetSegment(segmentID) terminologyEntry = self.getDeserializedTerminologyEntry(segment) category = terminologyEntry.GetCategoryObject() segmentData["SegmentDescription"] = category.GetCodeMeaning() algorithmType = vtk.mutable('') if not segment.GetTag("DICOM.SegmentAlgorithmType", algorithmType): algorithmType = "MANUAL" if not algorithmType in ["MANUAL","SEMIAUTOMATIC","AUTOMATIC"]: raise ValueError("Segment {} has invalid attribute for SegmentAlgorithmType."\ +"Should be one of (MANUAL,SEMIAUTOMATIC,AUTOMATIC).".format(segment.GetName())) algorithmName = vtk.mutable('') if not segment.GetTag("DICOM.SegmentAlgorithmName", algorithmName): algorithmName = None if algorithmType!="MANUAL" and not algorithmName: raise ValueError("Segment {} has has missing SegmentAlgorithmName, which"\ +"should be specified for non-manual segmentations.".format(segment.GetName())) segmentData["SegmentAlgorithmType"] = str(algorithmType) if algorithmName: segmentData["SegmentAlgorithmName"] = str(algorithmName) rgb = segment.GetColor() segmentData["recommendedDisplayRGBValue"] = [rgb[0] * 255, rgb[1] * 255, rgb[2] * 255] segmentData.update(self.createJSONFromTerminologyContext(terminologyEntry)) segmentData.update(self.createJSONFromAnatomicContext(terminologyEntry)) return segmentData
def findZofXYOnPolydata(points,vtkPolydata): # Make the cell locator cellLocator = vtk.vtkCellLocator() cellLocator.SetDataSet(vtkPolydata) cellLocator.BuildLocator() # Find the min/max of the polydata. lbot, ltop = np.array(vtkPolydata.GetBounds())[4::] # Loop over all the locations. intersectList = [] try: for nr, loc in enumerate(points): # Make line p1 = np.hstack((loc[0:2],ltop)) p2 = np.hstack((loc[0:2],lbot)) # Pre define variables as in C++ t = vtk.mutable(0) pIntSect = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] sub_id = vtk.mutable(0) cellLocator.IntersectWithLine(p1,p2,1e-6,t,pIntSect,pcoords,sub_id) intersectList.append(pIntSect) except KeyboardInterrupt as k: print 'Stopped at iteration {:d} in the for loop.'.format(nr) raise k # Return the intersects return np.array(intersectList)
def get_tpc_intersection(point, direction, box=None): """ Abstract class to calculate the TPC crossings """ if box is None: tpc_box = [ TPC.x_min, TPC.x_max, TPC.y_min, TPC.y_max, TPC.z_min, TPC.z_max ] else: tpc_box = box t1 = vtk.mutable(0) t2 = vtk.mutable(0) plane1 = vtk.mutable(0) plane2 = vtk.mutable(0) entry = [-1., -1., -1.] exit = [-1., -1., -1.] l = 5000 ray = [l * direction[0], l * direction[1], l * direction[2]] end_point = np.add(point, ray).tolist() vtk.vtkBox().IntersectWithLine(tpc_box, point, end_point, t1, t2, entry, exit, plane1, plane2) return [entry, exit]
def get_external_surface(self): print('getting external surface') _center = np.zeros(3) _bounds = np.zeros(6) _ray_start = np.zeros(3) cell_id = vtk.mutable(-1) xyz = np.zeros(3) pcoords = np.zeros(3) t = vtk.mutable(0) sub_id = vtk.mutable(0) _surf = 1.1 self.mesh.GetOutput().GetCenter(_center) self.mesh.GetOutput().GetPoints().GetBounds(_bounds) for j in range(3): _ray_start[j] = _bounds[2 * j + 1] * _surf cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(self.mesh.GetOutput()) cell_locator.BuildLocator() cell_locator.IntersectWithLine(_ray_start, _center, 0.0001, t, xyz, pcoords, sub_id, cell_id) connectivity_filter = vtk.vtkConnectivityFilter() connectivity_filter.SetInputConnection(self.mesh.GetOutputPort()) connectivity_filter.SetExtractionModeToCellSeededRegions() connectivity_filter.InitializeSeedList() connectivity_filter.AddSeed(cell_id) connectivity_filter.Update() self.mesh = connectivity_filter # UnstructuredGrid
def addMappingFromPointsToCells(ugrid_points, ugrid_cells, verbose=True): if (verbose): print '*** addMappingFromPointsToCells ***' nb_points = ugrid_points.GetNumberOfPoints() nb_cells = ugrid_cells.GetNumberOfCells() print "nb_points = " + str(nb_points) print "nb_cells = " + str(nb_cells) cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(ugrid_cells) cell_locator.Update() closest_point = [0.] * 3 generic_cell = vtk.vtkGenericCell() num_cell = vtk.mutable(0) subId = vtk.mutable(0) dist = vtk.mutable(0.) iarray_num_cell = createIntArray("num_cell", 1, nb_points) for num_point in range(nb_points): point = ugrid_points.GetPoint(num_point) cell_locator.FindClosestPoint(point, closest_point, generic_cell, num_cell, subId, dist) #num_cell = cell_locator.FindCell(point) iarray_num_cell.InsertTuple(num_point, [num_cell]) #print "num_point = " + str(num_point) #print "num_cell = " + str(num_cell) ugrid_points.GetPointData().AddArray(iarray_num_cell)
def intersection(surfaces, ray): # Surfaces is as VTKmodifiedBSPtree object # Ray contains the coordinates of 2 points defining the line # Mainly based on "https://lorensen.github.io/VTKExamples/site/Python/GeometricObjects/PolygonIntersection/" # tutorial, adapted because ModifiedBSPTree is used instead of a set of polygons. p1 = ray[0] # The coordinates of the light source of the kinect p2 = ray[ 1] # The coordinates of the intersection between the ground and the ray tolerance = 0.001 bestT = 2 # the best t parameter for the intersection, 1 is the worst possible value, 0 is the best one bestID = -300000 bestX = [-100, -100, -100] atLeastOne = False t = vtk.mutable( 0 ) # Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) x = [ -100, -100, -100 ] # Setting an impossible value for the intersection (just to check problematic case) pcoords = [0.0, 0.0, 0.0] subId = vtk.mutable(0) iD = surfaces.IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId) # This part was initially there because "surfaces" parameter was a list of polygons (so a ray can intersect # with several polygons and we need to find the nearest intersection with the light source) # TODO refactor the code so it benefits more of the specification of modifiedBSPtree (see comment above) if iD == 1: atLeastOne = True if t < bestT: # bestID = i bestT = t bestX = x return bestID, bestT, bestX, atLeastOne
def surface2surfacedistance(ref, target, arrayname): """Compute distance between two surfaces. Output is added as point array.""" # adapted from vtkvmtkSurfaceDistance # initialise locator = vtk.vtkCellLocator() genericcell = vtk.vtkGenericCell() cellid = vtk.mutable(0) point = [0., 0., 0.] closestpoint = [0., 0., 0.] subid = vtk.mutable(0) distance2 = vtk.mutable(0) # create array distarray = vtk.vtkDoubleArray() distarray.SetName(arrayname) distarray.SetNumberOfTuples(target.GetNumberOfPoints()) target.GetPointData().AddArray(distarray) # build locator locator.SetDataSet(ref) locator.BuildLocator() # compute distance for i in range(target.GetNumberOfPoints()): point = target.GetPoint(i) locator.FindClosestPoint(point, closestpoint, genericcell, cellid, subid, distance2) distance = math.sqrt(distance2) # add value to array distarray.SetValue(i, distance) target.Update() return target
def _createSegmentData(self, segmentID): segmentData = dict() segmentData["labelID"] = 1 segment = self.segmentationNode.GetSegmentation().GetSegment(segmentID) terminologyEntry = self.getDeserializedTerminologyEntry(segment) category = terminologyEntry.GetCategoryObject() segmentData["SegmentLabel"] = segment.GetName() segmentData["SegmentDescription"] = category.GetCodeMeaning() algorithmType = vtk.mutable('') if not segment.GetTag("DICOM.SegmentAlgorithmType", algorithmType): algorithmType = "MANUAL" if not algorithmType in ["MANUAL", "SEMIAUTOMATIC", "AUTOMATIC"]: raise ValueError("Segment {} has invalid attribute for SegmentAlgorithmType."\ +"Should be one of (MANUAL,SEMIAUTOMATIC,AUTOMATIC).".format(segment.GetName())) algorithmName = vtk.mutable('') if not segment.GetTag("DICOM.SegmentAlgorithmName", algorithmName): algorithmName = None if algorithmType != "MANUAL" and not algorithmName: raise ValueError("Segment {} has has missing SegmentAlgorithmName, which"\ +"should be specified for non-manual segmentations.".format(segment.GetName())) segmentData["SegmentAlgorithmType"] = str(algorithmType) if algorithmName: segmentData["SegmentAlgorithmName"] = str(algorithmName) rgb = segment.GetColor() segmentData["recommendedDisplayRGBValue"] = [ rgb[0] * 255, rgb[1] * 255, rgb[2] * 255 ] segmentData.update( self.createJSONFromTerminologyContext(terminologyEntry)) segmentData.update( self.createJSONFromAnatomicContext(terminologyEntry)) return segmentData
def testTangent2(): # segment is tangent to cell tBeg, tEnd = vtk.mutable(-1.0), vtk.mutable(-1.0) piHalf = numpy.pi / 2. # cell lam0, the0 = 0.025 * piHalf, 0.05 * piHalf lam1, the1 = 0.050 * piHalf, 0.05 * piHalf lam2, the2 = 0.050 * piHalf, 0.1 * piHalf lam3, the3 = 0.025 * piHalf, 0.1 * piHalf lamA, theA = 0.02 * piHalf, 0.05 * piHalf lamB, theB = 0.07 * piHalf, 0.05 * piHalf cli = CellLineIntersector() cli.setCartesianCell(lam0, the0, lam1, the1, lam2, the2, lam3, the3) cli.setCartesianLine(lamA, theA, lamB, theB) xiBeg = numpy.zeros((2, ), numpy.float64) xiEnd = numpy.zeros((2, ), numpy.float64) found = cli.findIntersection(tBeg, tEnd, xiBeg, xiEnd) print('testTangent2: tBeg = {} tEnd = {} xiBeg = {} xiEnd = {}'.format( tBeg.get(), tEnd.get(), xiBeg, xiEnd)) assert abs(tBeg.get() - 0.1) < 1.e-3 assert abs(tEnd.get() - 0.6) < 1.e-3
def testFloatMutable(self): m = vtk.mutable(3.0) n = vtk.mutable(4.0) m *= 2 self.assertEqual(m, 6.0) self.assertEqual(str(m), str(m.get())) o = n + m self.assertEqual(o, 10.0)
def testGetRangeTwoDoubleStarArg(self): cmap = vtk.vtkColorTransferFunction() localMin = vtk.mutable(-1) localMax = vtk.mutable(-1) cmap.GetRange(localMin, localMax) self.assertEqual(localMin, 0.0) self.assertEqual(localMax, 0.0)
def addAppliedToolToSegment(self, segment, toolName, toolType=None): self.updatingSegmentTags = True # append list of applied tools tools = vtk.mutable('') tools = str(tools).split(';') if segment.GetTag('QuantitativeReporting.AppliedTools', tools) else [] if not toolName in tools: tools.append(toolName) segment.SetTag('QuantitativeReporting.AppliedTools',";".join(tools)) segmentWasImported = tools[0]!='Add' # determine algorithm type (if not specified by user) if not toolType: if toolName in self.manualTools: toolType = 'MANUAL' elif toolName in self.automaticTools: toolType = 'AUTOMATIC' else: # default tool type toolType = 'SEMIAUTOMATIC' # update DICOM algorithm type oldAlgorithmType = vtk.mutable('') segment.GetTag('DICOM.SegmentAlgorithmType', oldAlgorithmType) updatedAlgorithmType = oldAlgorithmType if oldAlgorithmType=='': # no other editor effect was applied before if segmentWasImported: updatedAlgorithmType = 'SEMIAUTOMATIC' else: updatedAlgorithmType = toolType elif oldAlgorithmType=='MANUAL' and toolType!='MANUAL': updatedAlgorithmType = 'SEMIAUTOMATIC' elif oldAlgorithmType=='AUTOMATIC': updatedAlgorithmType = 'SEMIAUTOMATIC' if oldAlgorithmType!=updatedAlgorithmType: segment.SetTag('DICOM.SegmentAlgorithmType' ,updatedAlgorithmType) # update DICOM algorithm name GenericSlicerAlgorithmName = slicer.app.applicationName+' '+slicer.app.applicationVersion GenericSegmentEditorAlgorithmName = GenericSlicerAlgorithmName+' Segment Editor' ToolSegmentEditorAlgorithmName = GenericSlicerAlgorithmName+' '+toolName+' Effect' oldAlgorithmName = vtk.mutable('') segment.GetTag('DICOM.SegmentAlgorithmName', oldAlgorithmName) updatedAlgorithmName = oldAlgorithmName if oldAlgorithmName=='': # no other editor tool was applied before if segmentWasImported: updatedAlgorithmName = GenericSlicerAlgorithmName else: updatedAlgorithmName = ToolSegmentEditorAlgorithmName elif oldAlgorithmName!=ToolSegmentEditorAlgorithmName: if oldAlgorithmName.startswith(GenericSegmentEditorAlgorithmName): updatedAlgorithmName = GenericSegmentEditorAlgorithmName else: updatedAlgorithmName = GenericSlicerAlgorithmName if oldAlgorithmName!=updatedAlgorithmName: segment.SetTag('DICOM.SegmentAlgorithmName', updatedAlgorithmName) self.updatingSegmentTags = False
def findClosestPoint(self, p): # TODO: compute the closest point, compute the triangle coordinates of the intersection point in that triangle, and subId = vtk.mutable(0) meshPoint = np.zeros(3) cellId = vtk.mutable(0) dist2 = vtk.mutable(0.) self.locator.FindClosestPoint(p, meshPoint, cellId, subId, dist2) meshPoint cellId np.linalg.solve(self.points[self.triangles[cellId]], meshPoint)
def __init__(self, vtk_mesh): cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(vtk_mesh) cell_locator.BuildLocator() self.cell_locator = cell_locator # prepare some private properties that will be filled in for us by VTK self._c_point = [0., 0., 0.] self._cell_id = vtk.mutable(0) self._sub_id = vtk.mutable(0) self._distance = vtk.mutable(0.0)
def convertRasToViewport(self, viewNode, positionRas): """Computes normalized view coordinates from RAS coordinates for a particular view Normalized view coordinates origin is in bottom-left corner, range is [-1,+1] """ x = vtk.mutable(positionRas[0]) y = vtk.mutable(positionRas[1]) z = vtk.mutable(positionRas[2]) view = slicer.app.layoutManager().threeDWidget( self.getThreeDWidgetIndex(viewNode)).threeDView() renderer = view.renderWindow().GetRenderers().GetItemAsObject(0) renderer.WorldToView(x, y, z) return [x.get(), y.get(), z.get()]
def __init__(self): self.source = None self.locator = vtk.vtkCellLocator() self.mapper = vtk.vtkPolyDataMapper() self.actor = vtk.vtkActor() self.density = 1.0 self.transform = vtk.vtkTransform() self.transformFilter=vtk.vtkTransformPolyDataFilter() self.transformFilter.SetTransform(self.transform) self.tolerance = 0.00001 self.tmut = vtk.mutable(0) self.subId = vtk.mutable(0)
def toUVSpace(self, p): """ This function converts a 3D world space to 2D texture coordinates. Args: p (iterable of type float): 2D texture coordinate in (x,y) format with x and y values between 0 and 1 representing a relative position on the image texure. Returns: worldPoint(iterable of type float): 3D euclidian coordinate of the point corresponding to the 2D texture coordinate 'p' in the VTK polyData object's frame. normalVector(iterable of type float): 3D vector (x,y,z) representing the normal vector on the current face. TODO: * Return color data """ # Add dimensions if necessary points3D = np.atleast_2d(p) if points3D.ndim != 2 or points3D.shape[1] != 3: raise TypeError('toWorldSpace: input point must be 3xN') subId = vtk.mutable(0) cellId = vtk.mutable(0) dist = vtk.mutable(0) closest = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] tCoords = [0.0, 0.0, 0.0] weights = [0.0, 0.0, 0.0] points2D = np.empty(points2D.shape) for idx, point3D in enumerate(points3D): self.pointLocator.FindClosestPoint(point3D, closest, self._cell, cellId, subId, dist) self._cell.EvaluatePosition(point3D, closest, subId, pcoords, dist, weights) if type(pcoords) == str: raise TypeError( 'VTK function EvaluatePosition returned a null pointer. please use either ' + 'a newer version of VTK or build the dvrk_vision package with vtkCell.h' ) self.polyData2D.GetCell(cellId).EvaluateLocation( subId, pcoords, tCoords, weights) points2D[idx, :] = tCoords # If only queried one point, only return one point, no need for 2D array if len(points2D) == 1: return points2D[0] return points2D
def get_spline_actor(surface_data, chassis_cg_path, surface_bounds): # Iterate over chassis CG points and create a spline which marks the driving path. # Return the spline as a vtkActor for being added later to the renderer. # Update the pipeline so that vtkCellLocator finds cells surface_data.Update() # Define a cellLocator to be able to compute intersections between lines # and the surface locator = vtkCellLocator() locator.SetDataSet(surface_data.GetOutput()) locator.BuildLocator() tolerance = 0.01 # Set intersection searching tolerance # Make a list of points. Each point is the intersection of a vertical line # defined by p1 and p2 and the surface. points = vtkPoints() for chassis_cg in chassis_cg_path: p1 = [chassis_cg[0], chassis_cg[1], surface_bounds[4]] p2 = [chassis_cg[0], chassis_cg[1], surface_bounds[5]] t = mutable(0) pos = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] subId = mutable(0) locator.IntersectWithLine(p1, p2, tolerance, t, pos, pcoords, subId) # Add a slight offset in z pos[2] += 0.05 # Add the x, y, z position of the intersection points.InsertNextPoint(pos) # Create a spline and add the pointsoi spline = vtkParametricSpline() spline.SetPoints(points) spline_function = vtkParametricFunctionSource() spline_function.SetUResolution(len(chassis_cg_path)) spline_function.SetParametricFunction(spline) # Map the spline spline_mapper = vtkPolyDataMapper() spline_mapper.SetInputConnection(spline_function.GetOutputPort()) # Define the line actor spline_actor = vtkActor() spline_actor.SetMapper(spline_mapper) spline_actor.GetProperty().SetColor([0, 0.7, 0]) spline_actor.GetProperty().SetLineWidth(10) return spline_actor
def toWorldSpace(self, p): """ This function converts a 2D texture coordinate to 3D object space. Args: p (iterable of type float): 2D texture coordinate in (x,y) format with x and y values between 0 and 1 representing a relative position on the image texure. Returns: worldPoint(iterable of type float): 3D euclidian coordinate of the point corresponding to the 2D texture coordinate 'p' in the VTK polyData object's frame. normalVector(iterable of type float): 3D vector (x,y,z) representing the normal vector on the current face. TODO: * Return color data """ # Add dimensions if necessary points2D = np.atleast_2d(p) if points2D.shape[-1] == 2: points2D = np.hstack((points2D, np.zeros((1, len(points2D))))) if points2D.ndim != 2 or points2D.shape[1] != 3: raise TypeError('toWorldSpace: input point must be 2xN or 3xN') subId = vtk.mutable(0) cellId = vtk.mutable(0) dist = vtk.mutable(0) closest = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] tCoords = [0.0, 0.0, 0.0] weights = [0.0, 0.0, 0.0] points3D = np.empty(points2D.shape) normals = np.zeros(points2D.shape) for idx, point2D in enumerate(points2D): self.pointLocator2D.FindClosestPoint(point2D, closest, self._cell, cellId, subId, dist) self._cell.EvaluatePosition(point2D, closest, subId, pcoords, dist, weights) self.polyData.GetCell(cellId).EvaluateLocation( subId, pcoords, tCoords, weights) points3D[idx, :] = tCoords pointIds = self.polyData.GetCell(cellId).GetPointIds() normals[idx, :] = np.array( self.polyData.GetCellData().GetNormals().GetTuple(cellId)) # If only queried one point, only return one point, no need for 2D array if len(points3D) == 1: return points3D[0], normals[0] return points3D, normals
def closestPoint(actor, pt, N=1, radius=None, returnIds=False): """ Find the closest point on a polydata given an other point. The appropriate locator is built on the fly and cached for speed. If N>1, return a list of N ordered closest points. If radius is given, get all points within. """ poly = polydata(actor, True) if N > 1 or radius: plocexists = hasattr(actor, 'point_locator') if not plocexists or (plocexists and actor.point_locator is None): point_locator = vtk.vtkPointLocator() point_locator.SetDataSet(poly) point_locator.BuildLocator() setattr(actor, 'point_locator', point_locator) vtklist = vtk.vtkIdList() if N > 1: actor.point_locator.FindClosestNPoints(N, pt, vtklist) else: actor.point_locator.FindPointsWithinRadius(radius, pt, vtklist) if returnIds: return [ int(vtklist.GetId(k)) for k in range(vtklist.GetNumberOfIds()) ] else: trgp = [] for i in range(vtklist.GetNumberOfIds()): trgp_ = [0, 0, 0] vi = vtklist.GetId(i) poly.GetPoints().GetPoint(vi, trgp_) trgp.append(trgp_) return np.array(trgp) clocexists = hasattr(actor, 'cell_locator') if not clocexists or (clocexists and actor.cell_locator is None): cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(poly) cell_locator.BuildLocator() setattr(actor, 'cell_locator', cell_locator) trgp = [0, 0, 0] cid = vtk.mutable(0) dist2 = vtk.mutable(0) subid = vtk.mutable(0) actor.cell_locator.FindClosestPoint(pt, trgp, cid, subid, dist2) if returnIds: return int(cid) else: return np.array(trgp)
def distanceField(surfaceMesh, targetGrid, targetArrayName: str, signed=False): """Create a distance field between a vtkStructuredGrid and a surface. :param surfaceMesh: Outer polygonal surface :param targetGrid: Grid array of points :type targetGrid: vtk.vtkStructuredGrid :param targetArrayName: The distance field values will be stored in the \ target grid, with this array name. :type targetArrayName: str :param signed: Signed/unsigned distance field, defaults to False (unsigned) :type signed: bool, optional """ # Initialize distance field: df = vtk.vtkDoubleArray() df.SetNumberOfTuples(targetGrid.GetNumberOfPoints()) df.SetName(targetArrayName) # Data structure to quickly find cells: cellLocator = vtk.vtkCellLocator() cellLocator.SetDataSet(surfaceMesh) cellLocator.BuildLocator() for i in range(0, targetGrid.GetNumberOfPoints()): # Take a point from the target... testPoint = [0] * 3 targetGrid.GetPoint(i, testPoint) # ... find the point in the surface closest to it cID, subID, dist2 = vtk.mutable(0), vtk.mutable(0), vtk.mutable(0.0) closestPoint = [0] * 3 cellLocator.FindClosestPoint( testPoint, closestPoint, cID, subID, dist2) dist = math.sqrt(dist2) df.SetTuple1(i, dist) if signed: pts = vtk.vtkPolyData() pts.SetPoints(targetGrid.GetPoints()) enclosedPointSelector = vtk.vtkSelectEnclosedPoints() enclosedPointSelector.CheckSurfaceOn() enclosedPointSelector.SetInputData(pts) enclosedPointSelector.SetSurfaceData(surfaceMesh) enclosedPointSelector.SetTolerance(1e-9) enclosedPointSelector.Update() enclosedPoints = enclosedPointSelector.GetOutput() for i in range(0, targetGrid.GetNumberOfPoints()): if enclosedPointSelector.IsInside(i): df.SetTuple1(i, -df.GetTuple1(i)) # invert sign targetGrid.GetPointData().AddArray(df)
def getPointOnOtherMesh( a, a_locator, b, p ): '''Given two vtkPolyData's with matching topology and a vtkCellLocator for the first, carry point p from one to the other.''' cell_id = vtk.mutable(0) sub_id = vtk.mutable(0) d2 = vtk.mutable(0.0) cell = vtk.vtkGenericCell() p2 = p found = a_locator.FindClosestPoint( p, p2, cell, cell_id, sub_id, d2 ) p3 = p2 pcoords = [0,0,0] weights = [] cell.EvaluatePosition( p2, p3, sub_id, pcoords, d2, weights ) p4 = p3 b.GetCell( cell_id ).EvaluateLocation( sub_id, pcoords, p4, weights ) return p4
def getCellLocator(mesh, verbose=0): myVTK.myPrint(verbose, "*** getCellLocator ***") cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(mesh) cell_locator.Update() closest_point = [0.] * 3 generic_cell = vtk.vtkGenericCell() k_cell = vtk.mutable(0) subId = vtk.mutable(0) dist = vtk.mutable(0.) return (cell_locator, closest_point, generic_cell, k_cell, subId, dist)
def getPointOnOtherMesh(a, a_locator, b, p): '''Given two vtkPolyData's with matching topology and a vtkCellLocator for the first, carry point p from one to the other.''' cell_id = vtk.mutable(0) sub_id = vtk.mutable(0) d2 = vtk.mutable(0.0) cell = vtk.vtkGenericCell() p2 = p found = a_locator.FindClosestPoint(p, p2, cell, cell_id, sub_id, d2) p3 = p2 pcoords = [0, 0, 0] weights = [] cell.EvaluatePosition(p2, p3, sub_id, pcoords, d2, weights) p4 = p3 b.GetCell(cell_id).EvaluateLocation(sub_id, pcoords, p4, weights) return p4
def updateSelector(self, selector, model_types, param, filtered, defaultIndex=0): wasSelectorBlocked = selector.blockSignals(True) selector.clear() currentSegment = self.currentSegment() currentSegmentName = currentSegment.GetName().lower() if currentSegment else "" for model_name, model in self.models.items(): if model['type'] in model_types: if filtered and not (currentSegmentName in model_name.lower()): continue selector.addItem(model_name) selector.setItemData(selector.count - 1, model['description'], qt.Qt.ToolTipRole) model = self.scriptedEffect.parameter(param) if self.scriptedEffect.parameterDefined(param) else "" if not model and currentSegment: model = vtk.mutable("") currentSegment.GetTag(param, model) modelIndex = selector.findText(model) modelIndex = defaultIndex if modelIndex < 0 < selector.count else modelIndex selector.setCurrentIndex(modelIndex) try: modelInfo = self.models[model] selector.setToolTip(modelInfo["description"]) except: selector.setToolTip("") selector.blockSignals(wasSelectorBlocked)
def onClickEditPoints(self): segment = self.currentSegment() segmentId = self.currentSegmentID() self.segmentMarkupNode.RemoveAllMarkups() if segmentId: v = self.scriptedEffect.parameterSetNode().GetMasterVolumeNode() IjkToRasMatrix = vtk.vtkMatrix4x4() v.GetIJKToRASMatrix(IjkToRasMatrix) fPosStr = vtk.mutable("") segment.GetTag("AIAA.DExtr3DExtremePoints", fPosStr) pointset = str(fPosStr) logging.debug('{} => {} Extreme points are: {}'.format( segmentId, segment.GetName(), pointset)) if fPosStr is not None and len(pointset) > 0: points = json.loads(pointset) for p in points: p_Ijk = [p[0], p[1], p[2], 1.0] p_Ras = IjkToRasMatrix.MultiplyDoublePoint(p_Ijk) logging.debug('Add Fiducial: {} => {}'.format( p_Ijk, p_Ras)) self.segmentMarkupNode.AddFiducialFromArray(p_Ras[0:3]) self.updateGUIFromMRML()
def getDeserializedTerminologyEntry(vtkSegment): terminologyEntry = slicer.vtkSlicerTerminologyEntry() tag = vtk.mutable("") vtkSegment.GetTag(vtkSegment.GetTerminologyEntryTagName(), tag) terminologyLogic = slicer.modules.terminologies.logic() terminologyLogic.DeserializeTerminologyEntry(tag, terminologyEntry) return terminologyEntry
def testPassByReference(self): t = vtk.mutable(0.0) p0 = (0.5, 0.0, 0.0) n = (1.0, 0.0, 0.0) p1 = (0.0, 0.0, 0.0) p2 = (1.0, 1.0, 1.0) x = [0.0, 0.0, 0.0] vtk.vtkPlane.IntersectWithLine(p1, p2, n, p0, t, x) self.assertEqual(round(t, 6), 0.5) self.assertEqual(round(x[0], 6), 0.5) self.assertEqual(round(x[1], 6), 0.5) self.assertEqual(round(x[2], 6), 0.5) vtk.vtkPlane().IntersectWithLine(p1, p2, n, p0, t, x) self.assertEqual(round(t, 6), 0.5) self.assertEqual(round(x[0], 6), 0.5) self.assertEqual(round(x[1], 6), 0.5) self.assertEqual(round(x[2], 6), 0.5) t.set(0) p = vtk.vtkPlane() p.SetOrigin(0.5, 0.0, 0.0) p.SetNormal(1.0, 0.0, 0.0) p.IntersectWithLine(p1, p2, t, x) self.assertEqual(round(t, 6), 0.5) self.assertEqual(round(x[0], 6), 0.5) self.assertEqual(round(x[1], 6), 0.5) self.assertEqual(round(x[2], 6), 0.5) vtk.vtkPlane.IntersectWithLine(p, p1, p2, t, x) self.assertEqual(round(t, 6), 0.5) self.assertEqual(round(x[0], 6), 0.5) self.assertEqual(round(x[1], 6), 0.5) self.assertEqual(round(x[2], 6), 0.5)
def testPassByReference(self): t = vtk.mutable(0.0) p0 = (0.5, 0.0, 0.0) n = (1.0, 0.0, 0.0) p1 = (0.0, 0.0, 0.0) p2 = (1.0, 1.0, 1.0) x = [0.0, 0.0, 0.0] vtk.vtkPlane.IntersectWithLine(p1, p2, n, p0, t, x) self.assertEqual(round(t,6), 0.5) self.assertEqual(round(x[0],6), 0.5) self.assertEqual(round(x[1],6), 0.5) self.assertEqual(round(x[2],6), 0.5) vtk.vtkPlane().IntersectWithLine(p1, p2, n, p0, t, x) self.assertEqual(round(t,6), 0.5) self.assertEqual(round(x[0],6), 0.5) self.assertEqual(round(x[1],6), 0.5) self.assertEqual(round(x[2],6), 0.5) t.set(0) p = vtk.vtkPlane() p.SetOrigin(0.5, 0.0, 0.0) p.SetNormal(1.0, 0.0, 0.0) p.IntersectWithLine(p1, p2, t, x) self.assertEqual(round(t,6), 0.5) self.assertEqual(round(x[0],6), 0.5) self.assertEqual(round(x[1],6), 0.5) self.assertEqual(round(x[2],6), 0.5) vtk.vtkPlane.IntersectWithLine(p, p1, p2, t, x) self.assertEqual(round(t,6), 0.5) self.assertEqual(round(x[0],6), 0.5) self.assertEqual(round(x[1],6), 0.5) self.assertEqual(round(x[2],6), 0.5)
def onClickEditPoints(self): segmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() segment = segmentationNode.GetSegmentation().GetSegment(segmentID) label = segment.GetName() self.segmentMarkupNode.RemoveAllMarkups() v = self.scriptedEffect.parameterSetNode().GetMasterVolumeNode() IjkToRasMatrix = vtk.vtkMatrix4x4() v.GetIJKToRASMatrix(IjkToRasMatrix) fPosStr = vtk.mutable("") segment.GetTag("DExtr3DExtremePoints", fPosStr) logging.info('{} => {} Extreme points are: '.format( segmentID, label, fPosStr)) if fPosStr is not None and len(fPosStr) > 0: points = json.loads(str(fPosStr)) for p in points: p_Ijk = [p[0], p[1], p[2], 1.0] p_Ras = IjkToRasMatrix.MultiplyDoublePoint(p_Ijk) logging.info('Add Fiducial: {} => {}'.format(p_Ijk, p_Ras)) self.segmentMarkupNode.AddFiducialFromArray(p_Ras[0:3]) else: qt.QMessageBox.information( slicer.util.mainWindow(), 'NVIDIA AIAA', 'There are no pre-existing extreme points available for (' + segment.GetName() + ')' + '\t') self.updateGUIFromMRML()
def onEdit(self): # Create empty model node if self.segmentModel is None: self.segmentModel = slicer.vtkMRMLModelNode() slicer.mrmlScene.AddNode(self.segmentModel) segmentID = self.scriptedEffect.parameterSetNode( ).GetSelectedSegmentID() segmentationNode = self.scriptedEffect.parameterSetNode( ).GetSegmentationNode() segment = segmentationNode.GetSegmentation().GetSegment(segmentID) fPosStr = vtk.mutable("") segment.GetTag("DrawTubeEffectMarkupPositions", fPosStr) # convert from space-separated list o fnumbers to 1D array import numpy fPos = numpy.fromstring(str(fPosStr), sep=' ') # convert from 1D array (N*3) to 2D array (N,3) fPosNum = int(len(fPos) / 3) fPos = fPos.reshape((fPosNum, 3)) for i in xrange(fPosNum): self.segmentMarkupNode.AddFiducialFromArray(fPos[i]) self.editButton.setEnabled(False) self.updateModelFromSegmentMarkupNode()
def updateScalarBarRange(sliceLogic, volumeNode, scalarBar, selectedLayer): vdn = volumeNode.GetDisplayNode() if vdn: vcn = vdn.GetColorNode() if vcn is None: return lut = vcn.GetLookupTable() lut2 = vtk.vtkLookupTable() lut2.DeepCopy(lut) width = vtk.mutable(0) level = vtk.mutable(0) rangeLow = vtk.mutable(0) rangeHigh = vtk.mutable(0) if selectedLayer == 'background': sliceLogic.GetBackgroundWindowLevelAndRange(width,level,rangeLow,rangeHigh) else: sliceLogic.GetForegroundWindowLevelAndRange(width,level,rangeLow,rangeHigh) lut2.SetRange(level-width/2,level+width/2) scalarBar.SetLookupTable(lut2)
def getCellLocator( mesh, verbose=0): myVTK.myPrint(verbose, "*** getCellLocator ***") cell_locator = vtk.vtkCellLocator() cell_locator.SetDataSet(mesh) cell_locator.Update() closest_point = [0.]*3 generic_cell = vtk.vtkGenericCell() k_cell = vtk.mutable(0) subId = vtk.mutable(0) dist = vtk.mutable(0.) return (cell_locator, closest_point, generic_cell, k_cell, subId, dist)
def AddTimestamp( self, time, matrix, point, role ): if ( self.targetNode == None or self.bspTree == None ): return # To speed things up, if the structure has already been scanned, then skip if ( self.structureScanned ): return # Assume the matrix is ImageToRAS # For each scan line # Assume the x-axis is equivalent to the marked-unmarked axis for i in range( self.imageMinX, self.imageMaxX ): # Find end points of the current scan line in the Image coordinate system startPoint_Image = [ i, self.imageMinY, 0, 1 ] endPoint_Image = [ i, self.imageMaxY, 0, 1 ] # Transform the end points into the RAS coordinate system startPoint_RAS = [ 0, 0, 0, 1 ] endPoint_RAS = [ 0, 0, 0, 1 ] matrix.MultiplyPoint( startPoint_Image, startPoint_RAS ) matrix.MultiplyPoint( endPoint_Image, endPoint_RAS ) startPoint_RAS = [ startPoint_RAS[ 0 ], startPoint_RAS[ 1 ], startPoint_RAS[ 2 ] ] endPoint_RAS = [ endPoint_RAS[ 0 ], endPoint_RAS[ 1 ], endPoint_RAS[ 2 ] ] # Check for intersection with the model # These parameters INTERSECTION_POINT = [ 0, 0, 0 ] INTERSECTION_TOLERANCE = 0.001 P_COORDS = [ 0, 0, 0 ] T = vtk.mutable( 0 ) SUB_ID = vtk.mutable( 0 ) scanlineIntersection = self.bspTree.IntersectWithLine( startPoint_RAS, endPoint_RAS, INTERSECTION_TOLERANCE, T, INTERSECTION_POINT, P_COORDS, SUB_ID ) if ( scanlineIntersection == 1 ): self.structureScanned = True return
def find_cell(self, locator, point=None): """ Use vtk rountines to find cell/element containing the point.""" if point is None: point = self.pos cell_index = vtk.mutable(0) locator.FindClosestPoint(point, ARGV, cell_index, ARGI, ARGR) # locator.FindCell(point) if cell_index==-1: cell_index = None return cell_index
def CatTransformedCautious(self, pdb_ext, trans, pointlocator, cutoff=1.2): """Transforms pdb_ext and concatenates it to self. checks if the new molecule is not within the distance of cutoff from all the points in pointlocator.dataset . pointlocator : vtkPointLocator() """ pdb_aux = pdb_ext.MakeCopy() pdb_aux.ApplyTransform(trans) pointlocator.Update() dataset = pointlocator.GetDataSet() points = dataset.GetPoints() distance = vtk.mutable(0.0) # FindClosestPointWithinRadius writes on distance and its useless here. if not points: points = vtk.vtkPoints() dataset.SetPoints(points) if not self.empty: # do not check if empty for atom_itr in pdb_aux: pointid = pointlocator.FindClosestPointWithinRadius(cutoff, atom_itr.pos, distance) if pointid != -1: # There have been an atom within "cutoff" distance. return False ## There have been no atom within the cutoff distance. self.Concatenate(pdb_aux) self.empty = False # not empty anymore. ## add the newly added atom's position and its repeats to the pointlocator. pos = [0, 0, 0] for atom_itr in pdb_aux: points.InsertNextPoint(atom_itr.pos) pointlocator.InsertNextPoint(atom_itr.pos) coords = [[], [], []] for coord in [0, 1, 2]: if atom_itr.pos[coord] > self.unit_cell_size: coords[coord].append(atom_itr.pos[coord]) coords[coord].append(atom_itr.pos[coord] - self.unit_cell_size) elif atom_itr.pos[coord] < cutoff: coords[coord].append(atom_itr.pos[coord]) coords[coord].append(atom_itr.pos[coord] + self.unit_cell_size) else: coords[coord].append(atom_itr.pos[coord]) for xcoord in coords[0]: for ycoord in coords[1]: for zcoord in coords[2]: pos[0] = xcoord pos[1] = ycoord pos[2] = zcoord points.InsertNextPoint(pos) pointlocator.InsertNextPoint(pos) return True
def closest_point(mesh, vector, radius = None): locator = vtk.vtkPointLocator() ugrid = read_ugrid(mesh) locator.SetDataSet(ugrid) vector = map(float, vector) assert len(vector) == 3 if radius is None: index = locator.FindClosestPoint(vector) else: a = vtk.mutable(0.0) index = locator.FindClosestPointWithinRadius(radius, vector, a) point = ugrid.GetPoint(index) distance = math.sqrt(sum(starmap(lambda a, b: (b-a)**2, zip(vector, point)))) return {'index': index, 'point': point, 'dist': distance}
def normalHistogram(opts,argv): poly = nv.readVTK(argv[0]) normfilt = vtk.vtkPolyDataNormals() normfilt.ConsistencyOn() normfilt.AutoOrientNormalsOn() normfilt.ComputeCellNormalsOn() normfilt.SetInput(poly) normfilt.SetFeatureAngle(90) normfilt.Update() poly = normfilt.GetOutput() nv.writeVTK("nrom.vtk", poly) normals = poly.GetCellData().GetArray("Normals", vtk.mutable(0)) normMap = vtk.vtkUnstructuredGrid() normMap.SetPoints(vtk.vtkPoints()) normPts = normMap.GetPoints() for i in range(0, normals.GetNumberOfTuples()): norm = [0,0,0] normals.GetTuple(i, norm) normPts.InsertNextPoint(norm) nv.writeVTK(argv[1], normMap)
def testMethods(self): """Test overloaded methods""" # single-argument method vtkTransform::SetMatrix() t = vtk.vtkTransform() m = vtk.vtkMatrix4x4() m.SetElement(0, 0, 2) t.SetMatrix(m) self.assertEqual(t.GetMatrix().GetElement(0, 0), 2) t.SetMatrix([0,1,0,0, 1,0,0,0, 0,0,-1,0, 0,0,0,1]) self.assertEqual(t.GetMatrix().GetElement(0, 0), 0) # mixed number of arguments fd = vtk.vtkFieldData() fa = vtk.vtkFloatArray() fa.SetName("Real") ia = vtk.vtkIntArray() ia.SetName("Integer") fd.AddArray(fa) fd.AddArray(ia) a = fd.GetArray("Real") self.assertEqual(id(a), id(fa)) i = vtk.mutable(0) a = fd.GetArray("Integer", i) self.assertEqual(id(a), id(ia)) self.assertEqual(i, 1)
def collide(self, k, delta_t, vel=None, force=None, pa=None, level=0): """Collision detection routine. Args: k (float): Displacement dt (float): Timestep v (float, optional): velocity f (float, optional): forcing pa (float, optional): starting position in subcycle level (int) count to control maximum depth """ if pa is None: pa = self.pos if level == 10: return k * delta_t, None, vel - self.vel, None pos = pa+delta_t*k s = vtk.mutable(-1.0) x = [0.0, 0.0, 0.0] cell_index = vtk.mutable(0) bndl = self.system.boundary.bndl intersect = bndl.IntersectWithLine(pa, pos, 1.0e-8, s, x, ARGV, ARGI, cell_index) if intersect: if self.system.boundary.bnd.GetCellData().HasArray('SurfaceIds'): if self.system.boundary.bnd.GetCellData().GetScalars('SurfaceIds').GetValue(cell_index) in self.system.boundary.outlet_ids: return pos - pa, None, vel + delta_t * force - self.vel, None data, _, names = self.system.temporal_cache(self.time) # assert IO.test_in_cell(IO.get_linear_block(data[0][2]).GetCell(self.find_cell(data[0][3], pa)), pa) or sum((pa-x)**2)<1.0-10 print 'collision', intersect, cell_index, s, x, pos, pa x = numpy.array(x) old_pos = pos cell = self.system.boundary.bnd.GetCell(cell_index) normal = numpy.zeros(3) vec1 = (numpy.array(cell.GetPoints().GetPoint(1)) -numpy.array(cell.GetPoints().GetPoint(0))) if cell.GetCellType() == vtk.VTK_TRIANGLE: vec2 = (numpy.array(cell.GetPoints().GetPoint(2)) -numpy.array(cell.GetPoints().GetPoint(0))) else: vec2 = numpy.array(((pos-pa)[1]*vec1[2]-(pos-pa)[2]*vec1[1], (pos-pa)[2]*vec1[0]-(pos-pa)[0]*vec1[2], (pos-pa)[0]*vec1[1]-(pos-pa)[1]*vec1[0])) normal[0] = vec1[1]*vec2[2]-vec1[2]*vec2[1] normal[1] = vec1[2]*vec2[0]-vec1[0]*vec2[2] normal[2] = vec1[0]*vec2[1]-vec1[1]*vec2[0] if sum(normal**2) > 1.0e-32: normal = normal / numpy.sqrt(sum(normal**2)) else: print normal print vec1, vec2 raise Collision.CollisionException normal = normal * numpy.sign(numpy.dot(normal, (pos-pa))) coeff = self.system.coefficient_of_restitution(self, cell) pos = x + delta_t * (k - (1.0 + coeff) * normal * (numpy.dot(normal, k))) theta = abs(numpy.arcsin(numpy.dot(normal, (x-pa)) / numpy.sqrt(numpy.dot(x - pa, x - pa)))) coldat = [] if any(vel): vels = vel + s * delta_t * force else: vels = self.vel + s * delta_t * force par_col = copy.copy(self) if self.system.boundary.dist: par_col.pos = IO.get_real_x(cell, ARGV) else: par_col.pos = x par_col.vel = vels par_col.time = self.time + s * delta_t coldat.append(Collision.CollisionInfo(par_col, cell_index, theta, normal)) vels += -(1.0 + coeff)* normal * numpy.dot(normal, vels) px, col, velo, dummy_vel = self.collide(vels, (1 - s) * delta_t, vel=vels, force=force, pa=x + 1.0e-9 * vels, level=level + 1) pos = px + x + 1.0e-9 * vels if col: coldat += col return pos - pa, coldat, velo, vels return pos - pa, None, vel + delta_t * force - self.vel, None
maxloop = 1000 dist = 20.0/maxloop tolerance = 0.001 # Make a list of points. Each point is the intersection of a vertical line # defined by p1 and p2 and the surface. points = vtk.vtkPoints() for i in range(maxloop): p1 = [2+i*dist, 16, -1] p2 = [2+i*dist, 16, 6] # Outputs (we need only pos which is the x, y, z position # of the intersection) t = vtk.mutable(0) pos = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] subId = vtk.mutable(0) locator.IntersectWithLine(p1, p2, tolerance, t, pos, pcoords, subId) # Add a slight offset in z pos[2] += 0.01 # Add the x, y, z position of the intersection points.InsertNextPoint(pos) # Create a spline and add the points spline = vtk.vtkParametricSpline() spline.SetPoints(points) functionSource = vtk.vtkParametricFunctionSource() functionSource.SetUResolution(maxloop)
# Create a square in the x-y plane. points = vtk.vtkPoints() points.InsertNextPoint(0.0, 0.0, 0.0) points.InsertNextPoint(1.0, 0.0, 0.0) points.InsertNextPoint(1.0, 1.0, 0.0) points.InsertNextPoint(0.0, 1.0, 0.0) # Create the polygon polygon = vtk.vtkPolygon() polygon.GetPoints().DeepCopy(points) polygon.GetPointIds().SetNumberOfIds(4) # The 4 corners of the square for i in range(4): polygon.GetPointIds().SetId(i, i) # Inputs p1 = [0.1, 0, -1.0] p2 = [0.1, 0, 1.0] tolerance = 0.001; # Outputs t = vtk.mutable(0) # Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) x = [0.0, 0.0, 0.0] pcoords = [0.0, 0.0, 0.0] subId = vtk.mutable(0) iD = polygon.IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId); print "intersected? ", iD print "intersection: ", x
from particle_model import IO from particle_model import DragModels from particle_model import Collision from particle_model import System from particle_model import Options from particle_model import ParticleBase from particle_model import Parallel import numpy import vtk import scipy.linalg as la import itertools import copy ARGV = [0.0, 0.0, 0.0] ARGI = vtk.mutable(0) ARGR = vtk.mutable(0.0) def invert(mat): """ Hard coded 2D matrix inverse.""" if mat.shape == (2, 2): return (numpy.array(((mat[1, 1], -mat[0, 1]), (-mat[1, 0], mat[0, 0]))) /(mat[0, 0]*mat[1, 1]-mat[0, 1]*mat[1, 0])) else: return la.inv(mat) class Particle(ParticleBase.ParticleBase): """Class representing a single Lagrangian particle with mass""" def __init__(self, data,
def smoothMultipleSegments(self): import vtkSegmentationCorePython as vtkSegmentationCore # Generate merged labelmap of all visible segments segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode() visibleSegmentIds = vtk.vtkStringArray() segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(visibleSegmentIds) if visibleSegmentIds.GetNumberOfValues() == 0: logging.info("Smoothing operation skipped: there are no visible segments") return mergedImage = vtkSegmentationCore.vtkOrientedImageData() if not segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage, vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_SEGMENTS_PADDED, None, visibleSegmentIds): logging.error('Failed to apply smoothing: cannot get list of visible segments') return segmentColorIndices = [] # list of [segmentId, colorIndex] for i in range(visibleSegmentIds.GetNumberOfValues()): segmentId = visibleSegmentIds.GetValue(i) segment = segmentationNode.GetSegmentation().GetSegment(segmentId) colorIndexStr = vtk.mutable("") if not segment.GetTag(slicer.vtkMRMLSegmentationDisplayNode.GetColorIndexTag(), colorIndexStr): logging.error("Joint smoothing: failed to get color index for segment " + segmentId) segmentColorIndices.append([segmentId, int(colorIndexStr)]) # Perform smoothing in voxel space ici = vtk.vtkImageChangeInformation() ici.SetInputData(mergedImage) ici.SetOutputSpacing(1, 1, 1) ici.SetOutputOrigin(0, 0, 0) # Convert labelmap to combined polydata convertToPolyData = vtk.vtkDiscreteMarchingCubes() convertToPolyData.SetInputConnection(ici.GetOutputPort()) convertToPolyData.SetNumberOfContours(len(segmentColorIndices)) contourIndex = 0 for segmentId, colorIndex in segmentColorIndices: convertToPolyData.SetValue(contourIndex, colorIndex) contourIndex += 1 # Low-pass filtering using Taubin's method smoothingFactor = self.scriptedEffect.doubleParameter("JointTaubinSmoothingFactor") smoothingIterations = 100 # according to VTK documentation 10-20 iterations could be enough but we use a higher value to reduce chance of shrinking passBand = pow(10.0, -4.0*smoothingFactor) # gives a nice range of 1-0.0001 from a user input of 0-1 smoother = vtk.vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(convertToPolyData.GetOutputPort()) smoother.SetNumberOfIterations(smoothingIterations) smoother.BoundarySmoothingOff() smoother.FeatureEdgeSmoothingOff() smoother.SetFeatureAngle(90.0) smoother.SetPassBand(passBand) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() # Extract a label threshold = vtk.vtkThreshold() threshold.SetInputConnection(smoother.GetOutputPort()) # Convert to polydata geometryFilter = vtk.vtkGeometryFilter() geometryFilter.SetInputConnection(threshold.GetOutputPort()) # Convert polydata to stencil polyDataToImageStencil = vtk.vtkPolyDataToImageStencil() polyDataToImageStencil.SetInputConnection(geometryFilter.GetOutputPort()) polyDataToImageStencil.SetOutputSpacing(1,1,1) polyDataToImageStencil.SetOutputOrigin(0,0,0) polyDataToImageStencil.SetOutputWholeExtent(mergedImage.GetExtent()) # Convert stencil to image stencil = vtk.vtkImageStencil() emptyBinaryLabelMap = vtk.vtkImageData() emptyBinaryLabelMap.SetExtent(mergedImage.GetExtent()) emptyBinaryLabelMap.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1) vtkSegmentationCore.vtkOrientedImageDataResample.FillImage(emptyBinaryLabelMap, 0) stencil.SetInputData(emptyBinaryLabelMap) stencil.SetStencilConnection(polyDataToImageStencil.GetOutputPort()) stencil.ReverseStencilOn() stencil.SetBackgroundValue(1) # General foreground value is 1 (background value because of reverse stencil) imageToWorldMatrix = vtk.vtkMatrix4x4() mergedImage.GetImageToWorldMatrix(imageToWorldMatrix) for segmentId, colorIndex in segmentColorIndices: threshold.ThresholdBetween(colorIndex, colorIndex) stencil.Update() smoothedBinaryLabelMap = vtkSegmentationCore.vtkOrientedImageData() smoothedBinaryLabelMap.ShallowCopy(stencil.GetOutput()) smoothedBinaryLabelMap.SetImageToWorldMatrix(imageToWorldMatrix) # Write results to segments directly, bypassing masking slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(smoothedBinaryLabelMap, segmentationNode, segmentId, slicer.vtkSlicerSegmentationsModuleLogic.MODE_REPLACE, smoothedBinaryLabelMap.GetExtent())
def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0, down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2, aug = False, distance_fix = 0.3, distance_mov = 0.1, w_wrong = 1.5, truth_mov = None): time1 = time.time() if index == -1: index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object') if index is None: return None, None, None if index == 0: fixed_points = fixedData.getPointSet('Contour').copy() moving_points = movingData.getPointSet('Contour').copy() else: fixed_points = fixedData.getPointSet('Centerline').copy() moving_points = movingData.getPointSet('Centerline').copy() if truth_mov is None: truth_mov = moving_points.copy() fixed_bif = db.getBifurcation(fixed_points) moving_bif = db.getBifurcation(moving_points) if useMask: mask_points = movingData.getPointSet('Mask') for point in mask_points: moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0) fixed_res = fixedData.getResolution().tolist() moving_res = movingData.getResolution().tolist() fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)] moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)] # Use the bifurcation as the initial position if (fixed_bif < 0) or (moving_bif < 0): fixed_min = 0 # Augmentation of pointset fixed = fixed_points.copy() moving = moving_points.copy() if index == 1 and aug: fixed = util.augmentCenterline(fixed, 1, 10) moving = util.augmentCenterline(moving, 1, 10) fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2]) moving = util.resampleCenterline(moving, mov_dis / moving_res[2]) fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0] moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0] fixed[:, :3] *= fixed_res[:3] moving[:, :3] *= moving_res[:3] new_trans_points = truth_mov result_center_points = movingData.getPointSet('Centerline').copy() new_trans_points = new_trans_points[new_trans_points[:, 3] >= 0] result_center_points = result_center_points[result_center_points[:, 3] >= 0] new_trans_points[:, :3] *= moving_res[:3] result_center_points[:, :3] *= moving_res[:3] if (fixed_bif >= 0) and (moving_bif >= 0): fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) # Prepare for ICP MaxIterNum = 50 #MaxNum = 600 MaxNum = int(MaxRate * moving.shape[0] + 0.5) targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()] targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()] target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()] Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()] for i in range(3): for x in fixed[npy.round(fixed[:, 3]) == i]: id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2]) targetVertices[i].InsertNextCell(1) targetVertices[i].InsertCellPoint(id) target[i].SetPoints(targetPoints[i]) target[i].SetVerts(targetVertices[i]) Locator[i].SetDataSet(target[i]) Locator[i].SetNumberOfCellsPerBucket(1) Locator[i].BuildLocator() step = 1 if moving.shape[0] > MaxNum: ind = moving[:, 2].argsort() moving = moving[ind, :] step = moving.shape[0] / MaxNum nb_points = moving.shape[0] / step points1 = vtk.vtkPoints() points1.SetNumberOfPoints(nb_points) label = npy.zeros([MaxNum * 2], dtype = npy.int8) j = 0 for i in range(nb_points): points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2]) label[i] = moving[j][3] j += step closestp = vtk.vtkPoints() closestp.SetNumberOfPoints(nb_points) points2 = vtk.vtkPoints() points2.SetNumberOfPoints(nb_points) id1 = id2 = vtk.mutable(0) dist = vtk.mutable(0.0) outPoint = [0.0, 0.0, 0.0] p1 = [0.0, 0.0, 0.0] p2 = [0.0, 0.0, 0.0] iternum = 0 a = points1 b = points2 if (op and index == 0) or (not op and index == 1): w_mat = [[1, w_wrong, w_wrong], [w_wrong, 1, 99999999], [w_wrong, 99999999, 1]] else: w_mat = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] accumulate = vtk.vtkTransform() accumulate.PostMultiply() LandmarkTransform = vtk.vtkLandmarkTransform() LandmarkTransform.SetModeToRigidBody() while True: for i in range(nb_points): min_dist = 99999999 min_outPoint = [0.0, 0.0, 0.0] for j in range(3): Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist) dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2)) if dis * w_mat[label[i]][j] < min_dist: min_dist = dis * w_mat[label[i]][j] min_outPoint = copy.deepcopy(outPoint) closestp.SetPoint(i, min_outPoint) LandmarkTransform.SetSourceLandmarks(a) LandmarkTransform.SetTargetLandmarks(closestp) LandmarkTransform.Update() accumulate.Concatenate(LandmarkTransform.GetMatrix()) iternum += 1 for i in range(nb_points): a.GetPoint(i, p1) LandmarkTransform.InternalTransformPoint(p1, p2) b.SetPoint(i, p2) b, a = a, b if iternum >= MaxIterNum: break matrix = accumulate.GetMatrix() T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32)) new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32)) LandmarkTransform = vtk.vtkThinPlateSplineTransform() LandmarkTransform.SetBasisToR() iternum = 0 # Non-rigid while True: for i in range(nb_points): min_dist = 99999999 min_outPoint = [0.0, 0.0, 0.0] for j in range(3): Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist) dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2)) if dis * w_mat[label[i]][j] < min_dist: min_dist = dis * w_mat[label[i]][j] min_outPoint = copy.deepcopy(outPoint) closestp.SetPoint(i, min_outPoint) LandmarkTransform.SetSourceLandmarks(a) LandmarkTransform.SetTargetLandmarks(closestp) LandmarkTransform.Update() ''' for i in range(result_center_points.shape[0]): LandmarkTransform.InternalTransformPoint([result_center_points[i, 0], result_center_points[i, 1], result_center_points[i, 2]], p2) result_center_points[i, :3] = p2 ''' for i in range(new_trans_points.shape[0]): LandmarkTransform.InternalTransformPoint([new_trans_points[i, 0], new_trans_points[i, 1], new_trans_points[i, 2]], p2) new_trans_points[i, :3] = p2 iternum += 1 if iternum >= 1: break for i in range(nb_points): a.GetPoint(i, p1) LandmarkTransform.InternalTransformPoint(p1, p2) b.SetPoint(i, p2) b, a = a, b time2 = time.time() if (fixed_bif >= 0) and (moving_bif >= 0): new_trans_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) result_center_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) new_trans_points[:, :3] /= fixed_res[:3] result_center_points[:, :3] /= fixed_res[:3] resultImage = movingData.getData().copy() sa = SurfaceErrorAnalysis(None) dataset = db.BasicData(npy.array([[[0]]]), fixedData.getInfo(), {'Contour': new_trans_points, 'Centerline': result_center_points}) mean_dis, mean_whole, max_dis, max_whole = sa.analysis(dataset, point_data_fix = fixedData.getPointSet('Contour').copy(), useResult = True) del dataset print mean_dis print mean_whole if isTime: return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole], time2 - time1 return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole]
def testStringMutable(self): m = vtk.mutable("%s %s!") m %= ("hello", "world") self.assertEqual(m, "hello world!")
def testIntMutable(self): m = vtk.mutable(3) n = vtk.mutable(4) m |= n self.assertEqual(m, 7.0) self.assertEqual(str(m), str(m.get()))
# Clip data to spit out unstructured tets clipper = vtk.vtkClipDataSet() clipper.SetInputConnection(mandel.GetOutputPort()) clipper.SetClipFunction(sphere) clipper.InsideOutOn() clipper.Update() output = clipper.GetOutput() numCells = output.GetNumberOfCells() bounds = output.GetBounds() #print bounds # Support subsequent method calls genCell = vtk.vtkGenericCell() t = vtk.mutable(0.0) x = [0,0,0] pc = [0,0,0] subId = vtk.mutable(0) cellId = vtk.mutable(0) # Build the locator locator = vtk.vtkStaticCellLocator() #locator = vtk.vtkCellLocator() locator.SetDataSet(output) locator.AutomaticOn() locator.SetNumberOfCellsPerNode(20) locator.CacheCellBoundsOn() locator.BuildLocator() # Now visualize the locator
def analysis(self, data, point_data_fix = None, point_data_mov = None, point_data_mask = None, spacing_mov = None, useResult = False): if point_data_fix is None: point_data_fix = self.gui.dataModel[data.getFixedIndex()].getPointSet('Contour').copy() point_data_mov = self.gui.dataModel[data.getMovingIndex()].getPointSet('Contour').copy() point_data_mask = self.gui.dataModel[data.getMovingIndex()].getPointSet('Mask').copy() spacing_mov = self.gui.dataModel[data.getMovingIndex()].getResolution().tolist() self.spacing = data.getResolution().tolist() point_data_fix = point_data_fix[point_data_fix[:, 0] >= 0] bif = db.getBifurcation(point_data_fix) point_data_fix = util.augmentPointset(point_data_fix, 3, -1, bif, nn = 20) point_data_fix[:, :3] *= self.spacing[:3] if point_data_mov is not None: point_data_mov = point_data_mov[point_data_mov[:, 0] >= 0] if not useResult: para = npy.array(data.info.getData('transform')).flatten() point_data_result = point_data_mov.copy() for point in point_data_mask: point_data_result = npy.delete(point_data_result, npy.where((npy.abs(point_data_result[:, 2] - point[2]) < 0.0001) & (npy.round(point_data_result[:, -1]) == point[3])), axis = 0) point_data_result[:, :3] *= spacing_mov[:3] R = ml.mat(para[:9]).reshape(3, 3) T = ml.mat(para[9:12]).T if para.shape[0] > 12: C = ml.mat(para[12:]).T else: C = ml.zeros([3, 1], dtype = npy.float32) T = R.I * T T = -T point_data_result[:, :3] = util.applyTransformForPoints(point_data_result[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, C) else: point_data_result = data.getPointSet('Contour').copy() point_data_result = point_data_result[point_data_result[:, -1] >= 0] point_data_result[:, :3] *= self.spacing[:3] targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()] targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()] target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()] Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()] label_dis = [3, 2, 1] for i in range(3): for x in point_data_fix[npy.round(point_data_fix[:, 3]) != label_dis[i]]: id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2]) targetVertices[i].InsertNextCell(1) targetVertices[i].InsertCellPoint(id) target[i].SetPoints(targetPoints[i]) target[i].SetVerts(targetVertices[i]) Locator[i].SetDataSet(target[i]) Locator[i].SetNumberOfCellsPerBucket(1) Locator[i].BuildLocator() ''' Locator = vtk.vtkCellLocator() targetPoints = vtk.vtkPoints() targetVertices = vtk.vtkCellArray() target = vtk.vtkPolyData() for x in point_data_fix: id = targetPoints.InsertNextPoint(x[0], x[1], x[2]) targetVertices.InsertNextCell(1) targetVertices.InsertCellPoint(id) target.SetPoints(targetPoints) target.SetVerts(targetVertices) Locator.SetDataSet(target) Locator.SetNumberOfCellsPerBucket(1) Locator.BuildLocator() ''' id1 = id2 = vtk.mutable(0) dist = vtk.mutable(0.0) outPoint = [0.0, 0.0, 0.0] cnt_num = npy.array([0, 0, 0]) mean_dis = npy.array([0.0, 0.0, 0.0]) max_dis = npy.array([0.0, 0.0, 0.0]) for pt in point_data_result: cnt = int(pt[-1] + 0.5) Locator[cnt].FindClosestPoint(pt[:3].tolist(), outPoint, id1, id2, dist) dis = npy.sqrt(npy.sum((npy.array(outPoint) - pt[:3]) ** 2)) mean_dis[cnt] += dis max_dis[cnt] = npy.max([max_dis[cnt], dis]) cnt_num[cnt] += 1 cnt_total = npy.sum(cnt_num) mean_whole = npy.sum(mean_dis) / cnt_total mean_dis /= cnt_num mean_dis[mean_dis != mean_dis] = 0 # Replace the NAN in the mean distance max_whole = npy.max(max_dis) if self.gui is not None: message = "Error on Vessel 0: %0.2fmm (Total %d slices)\nError on Vessel 1: %0.2fmm (Total %d slices)\nError on Vessel 2: %0.2fmm (Total %d slices)\nWhole Error: %0.2fmm (Total %d slices)\n" \ % (mean_dis[0], cnt_num[0], mean_dis[1], cnt_num[1], mean_dis[2], cnt_num[2], mean_whole, cnt_total) + \ "-----------------------------------------------------------------------------\n" + \ "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \ % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis)); self.gui.showErrorMessage("Centerline Registration Error", message) return mean_dis, mean_whole, max_dis, max_whole
def growCut(self): # Get master volume image data import vtkSegmentationCorePython as vtkSegmentationCore masterImageData = self.scriptedEffect.masterVolumeImageData() # Get segmentation segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode() # Cast master image if not short if masterImageData.GetScalarType() != vtk.VTK_SHORT: imageCast = vtk.vtkImageCast() imageCast.SetInputData(masterImageData) imageCast.SetOutputScalarTypeToShort() imageCast.ClampOverflowOn() imageCast.Update() masterImageDataShort = vtkSegmentationCore.vtkOrientedImageData() masterImageDataShort.DeepCopy(imageCast.GetOutput()) # Copy image data masterImageDataShort.CopyDirections(masterImageData) # Copy geometry masterImageData = masterImageDataShort # Generate merged labelmap as input to GrowCut mergedImage = vtkSegmentationCore.vtkOrientedImageData() segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage, vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_SEGMENTS, masterImageData) # Make a zero-valued volume for the output outputLabelmap = vtkSegmentationCore.vtkOrientedImageData() thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(0) thresh.SetOutValue(0) thresh.SetOutputScalarType( vtk.VTK_SHORT ) thresh.SetInputData( mergedImage ) thresh.SetOutput( outputLabelmap ) thresh.Update() outputLabelmap.DeepCopy( mergedImage ) #TODO: It was thresholded just above, why deep copy now? # Perform grow cut import vtkITK growCutFilter = vtkITK.vtkITKGrowCutSegmentationImageFilter() growCutFilter.SetInputData( 0, masterImageData ) growCutFilter.SetInputData( 1, mergedImage ) #TODO: This call sets an empty image for the optional "previous segmentation", and # is apparently needed for the first segmentation too. Why? growCutFilter.SetInputConnection( 2, thresh.GetOutputPort() ) #TODO: These are magic numbers inherited from EditorLib/GrowCut.py objectSize = 5. contrastNoiseRatio = 0.8 priorStrength = 0.003 segmented = 2 conversion = 1000 spacing = mergedImage.GetSpacing() voxelVolume = reduce(lambda x,y: x*y, spacing) voxelAmount = objectSize / voxelVolume voxelNumber = round(voxelAmount) * conversion cubeRoot = 1./3. oSize = int(round(pow(voxelNumber,cubeRoot))) growCutFilter.SetObjectSize( oSize ) growCutFilter.SetContrastNoiseRatio( contrastNoiseRatio ) growCutFilter.SetPriorSegmentConfidence( priorStrength ) growCutFilter.Update() outputLabelmap.DeepCopy( growCutFilter.GetOutput() ) # Write output segmentation results in segments segmentIDs = vtk.vtkStringArray() segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs) for index in xrange(segmentIDs.GetNumberOfValues()): segmentID = segmentIDs.GetValue(index) segment = segmentationNode.GetSegmentation().GetSegment(segmentID) # Get label corresponding to segment in merged labelmap (and so GrowCut output) colorIndexStr = vtk.mutable("") tagFound = segment.GetTag(slicer.vtkMRMLSegmentationDisplayNode.GetColorIndexTag(), colorIndexStr); if not tagFound: logging.error('Failed to apply GrowCut result on segment ' + segmentID) continue colorIndex = int(colorIndexStr.get()) # Get only the label of the current segment from the output image thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(1) thresh.SetOutValue(0) thresh.ThresholdBetween(colorIndex, colorIndex); thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(outputLabelmap) thresh.Update() # Write label to segment newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData() newSegmentLabelmap.ShallowCopy(thresh.GetOutput()) newSegmentLabelmap.CopyDirections(mergedImage) slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, segmentationNode, segmentID, slicer.vtkSlicerSegmentationsModuleLogic.MODE_REPLACE, newSegmentLabelmap.GetExtent())
def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0, down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2, aug = False, distance_fix = 0.3, distance_mov = 0.1): time1 = time.time() if index == -1: index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object') if index is None: return None, None, None if index == 0: fixed_points = fixedData.getPointSet('Contour').copy() moving_points = movingData.getPointSet('Contour').copy() else: fixed_points = fixedData.getPointSet('Centerline').copy() moving_points = movingData.getPointSet('Centerline').copy() fixed_bif = db.getBifurcation(fixed_points) moving_bif = db.getBifurcation(moving_points) if useMask: mask_points = movingData.getPointSet('Mask') for point in mask_points: moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0) fixed_res = fixedData.getResolution().tolist() moving_res = movingData.getResolution().tolist() fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)] moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)] # Use the bifurcation as the initial position if (fixed_bif < 0) or (moving_bif < 0): fixed_min = 0 # Augmentation of pointset fixed = fixed_points.copy() moving = moving_points.copy() if index == 1 and aug: fixed = util.augmentCenterline(fixed, 1, 10) moving = util.augmentCenterline(moving, 1, 10) fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2]) moving = util.resampleCenterline(moving, mov_dis / moving_res[2]) fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0] moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0] fixed[:, :3] *= fixed_res[:3] moving[:, :3] *= moving_res[:3] if (fixed_bif >= 0) and (moving_bif >= 0): fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) # Prepare for ICP LandmarkTransform = vtk.vtkLandmarkTransform() LandmarkTransform.SetModeToRigidBody() MaxIterNum = 50 #MaxNum = 600 MaxNum = int(MaxRate * moving.shape[0] + 0.5) targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()] targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()] target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()] Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()] if index == 0: if not op: label_dis = [3, 3, 3] else: label_dis = [3, 2, 1] else: if op: label_dis = [3, 3, 3] else: label_dis = [3, 2, 1] for i in range(3): for x in fixed[npy.round(fixed[:, 3]) != label_dis[i]]: id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2]) targetVertices[i].InsertNextCell(1) targetVertices[i].InsertCellPoint(id) target[i].SetPoints(targetPoints[i]) target[i].SetVerts(targetVertices[i]) Locator[i].SetDataSet(target[i]) Locator[i].SetNumberOfCellsPerBucket(1) Locator[i].BuildLocator() step = 1 if moving.shape[0] > MaxNum: ind = moving[:, 2].argsort() moving = moving[ind, :] step = moving.shape[0] / MaxNum nb_points = moving.shape[0] / step accumulate = vtk.vtkTransform() accumulate.PostMultiply() points1 = vtk.vtkPoints() points1.SetNumberOfPoints(nb_points) label = npy.zeros([MaxNum * 2], dtype = npy.int8) j = 0 for i in range(nb_points): points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2]) label[i] = moving[j][3] j += step closestp = vtk.vtkPoints() closestp.SetNumberOfPoints(nb_points) points2 = vtk.vtkPoints() points2.SetNumberOfPoints(nb_points) id1 = id2 = vtk.mutable(0) dist = vtk.mutable(0.0) outPoint = [0.0, 0.0, 0.0] p1 = [0.0, 0.0, 0.0] p2 = [0.0, 0.0, 0.0] iternum = 0 a = points1 b = points2 ''' path = sys.argv[0] if os.path.isfile(path): path = os.path.dirname(path) path += '/Data/Transform' wfile = open("%s/transform.txt" % path, 'w') matrix = accumulate.GetMatrix() T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T; R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I if (fixed_bif >= 0) and (moving_bif >= 0): T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) saveTransform(wfile, T, R) ''' while True: for i in range(nb_points): Locator[label[i]].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist) closestp.SetPoint(i, outPoint) LandmarkTransform.SetSourceLandmarks(a) LandmarkTransform.SetTargetLandmarks(closestp) LandmarkTransform.Update() accumulate.Concatenate(LandmarkTransform.GetMatrix()) iternum += 1 if iternum >= MaxIterNum: break dist_err = 0 for i in range(nb_points): a.GetPoint(i, p1) LandmarkTransform.InternalTransformPoint(p1, p2) b.SetPoint(i, p2) dist_err += npy.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 + (p1[2] - p2[2]) ** 2) dist_err /= nb_points print "iter = %d: %f" % (iternum, dist_err) ''' matrix = accumulate.GetMatrix() T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T; R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I; if (fixed_bif >= 0) and (moving_bif >= 0): T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2]) saveTransform(wfile, T, R) ''' b, a = a, b time2 = time.time() #wfile.close() # Get the result transformation parameters matrix = accumulate.GetMatrix() T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I #T = ml.mat([0, 0, 0]).T #R = ml.mat([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).T if (fixed_bif >= 0) and (moving_bif >= 0): T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta) # Resample the moving contour moving_points = movingData.getPointSet('Contour').copy() moving_center = movingData.getPointSet('Centerline').copy() #new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T) new_trans_points, result_center_points = moving_points, moving_center result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32)) new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32)) T = -T T = R * T transform = sitk.Transform(3, sitk.sitkAffine) para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0] transform.SetParameters(para) movingImage = movingData.getSimpleITKImage() fixedImage = fixedData.getSimpleITKImage() resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32) if isTime: return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0], time2 - time1 return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0]