def probeVolume(self, volumeNode, rulerNode, numOfPoints): #get ruler end points in RAS coordinates system p0ras = rulerNode.GetPolyData().GetPoint(0) + (1,) p1ras = rulerNode.GetPolyData().GetPoint(1) + (1,) import math, numpy lineLength = math.sqrt((p0ras[0]-p1ras[0])*(p0ras[0]-p1ras[0]) + (p0ras[1]-p1ras[1])*(p0ras[1]-p1ras[1]) + (p0ras[2]-p1ras[2])*(p0ras[2]-p1ras[2])) distanceArray = [0] if (numOfPoints > 1): distanceArray = numpy.linspace(0,lineLength,numOfPoints) #The transformation matrix from RAS to IJK coordinates systems ras2ijk = vtk.vtkMatrix4x4() volumeNode.GetRASToIJKMatrix(ras2ijk) p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]] p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]] #Create the VTK sampling line line = vtk.vtkLineSource() line.SetResolution(numOfPoints) line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2]) line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2]) #Creat the VTK probe filter probe = vtk.vtkProbeFilter() probe.SetInputConnection(line.GetOutputPort()) probe.SetSourceData(volumeNode.GetImageData()) probe.Update() # return the sampled array return probe.GetOutput().GetPointData().GetArray('ImageScalars'), distanceArray
def probeVolume(self,volumeNode,rulerNode): # get ruler endpoints coordinates in RAS p0ras = rulerNode.GetPolyData().GetPoint(0)+(1,) p1ras = rulerNode.GetPolyData().GetPoint(1)+(1,) # convert RAS to IJK coordinates of the vtkImageData ras2ijk = vtk.vtkMatrix4x4() volumeNode.GetRASToIJKMatrix(ras2ijk) p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]] p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]] # create VTK line that will be used for sampling line = vtk.vtkLineSource() line.SetResolution(100) line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2]) line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2]) # create VTK probe filter and sample the image probe = vtk.vtkProbeFilter() probe.SetInputConnection(line.GetOutputPort()) probe.SetSourceData(volumeNode.GetImageData()) probe.Update() # return VTK array return probe.GetOutput().GetPointData().GetArray('ImageScalars')
def probeVolume(self, volumeNode, rulerNode): # initialize vtkLineSource from Slicer ruler # (ruler endpoints are in RAS) p0ras4 = rulerNode.GetPolyData().GetPoint(0)+(1,) p1ras4 = rulerNode.GetPolyData().GetPoint(1)+(1,) # convert to vtkImageData IJK coordinates ras2ijk = vtk.vtkMatrix4x4() volumeNode.GetRASToIJKMatrix(ras2ijk) p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras4)[:3]] p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras4)[:3]] # initialize vtkLineSource line = vtk.vtkLineSource() line.SetResolution(100) # TODO: make this a parameter! line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2]) line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2]) # ready to probe the volume probe = vtk.vtkProbeFilter() probe.SetInputConnection(line.GetOutputPort()) probe.SetSourceData(volumeNode.GetImageData()) probe.Update() data = probe.GetOutput().GetPointData().GetArray('ImageScalars') for p in range(data.GetNumberOfTuples()): print data.GetTuple1(p), print return data
def lineModel(self, scene, point1, point2, name, color): """ Create a line to reflect the puncture path""" #Line mode source line = vtk.vtkLineSource() line.SetPoint1(point1)#(point1[0][0], point1[0][1], point1[0][2]) line.SetPoint2(point2)#(point2[0][0], point2[0][1], point2[0][2]) # Create model node lineModel = slicer.vtkMRMLModelNode() lineModel.SetScene(scene) lineModel.SetName(name) lineModel.SetAndObservePolyData(line.GetOutput()) # Create display node lineModelDisplay = slicer.vtkMRMLModelDisplayNode() lineModelDisplay.SetColor(color) lineModelDisplay.SetScene(scene) scene.AddNode(lineModelDisplay) lineModel.SetAndObserveDisplayNodeID(lineModelDisplay.GetID()) #Add to scene # lineModelDisplay.SetInputPolyData(line.GetOutput()) lineModelDisplay.SetInputPolyDataConnection(line.GetOutputPort()) scene.AddNode(lineModel) return line
def createOptionalPathModel(self, pos, holeInfoList, intNumOfOptionalPath): if intNumOfOptionalPath == 1: self.setOptionalPathVisibility(1) pathListRAS = [] for i in range(len(holeInfoList)): pathListRAS.append(self.templateRAS[holeInfoList[i][3]]) print "pathListRAS: ", pathListRAS #(not generate path -> pass, otherwise go on) self.optModelNode = slicer.mrmlScene.GetNodeByID(self.optionalPathModelNodeID) if self.optModelNode == None: self.optModelNode = slicer.vtkMRMLModelNode() self.optModelNode.SetName('AllOptionalPaths') slicer.mrmlScene.AddNode(self.optModelNode) self.optionalPathModelNodeID = self.optModelNode.GetID() self.dnodeOpt = slicer.vtkMRMLModelDisplayNode() self.dnodeOpt.SetColor(0.96,0.92,0.56) slicer.mrmlScene.AddNode(self.dnodeOpt) self.optModelNode.SetAndObserveDisplayNodeID(self.dnodeOpt.GetID()) optModelAppend = vtk.vtkAppendPolyData() #for path in pathListRAS: for index in range(len(pathListRAS)): optLineSource = vtk.vtkLineSource() optLineSource.SetPoint1(pos) optLineSource.SetPoint2(pathListRAS[index]) optTubeFilter = vtk.vtkTubeFilter() optTubeFilter.SetInputConnection(optLineSource.GetOutputPort()) optTubeFilter.SetRadius(1.0) optTubeFilter.SetNumberOfSides(10) optTubeFilter.CappingOn() optTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: optModelAppend.AddInput(optTubeFilter.GetOutput()) else: optModelAppend.AddInputData(optTubeFilter.GetOutput()) optModelAppend.Update() self.optModelNode.SetAndObservePolyData(optModelAppend.GetOutput())
def createCylinder(name, R, H=50): cylinder = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode') cylinder.SetName(slicer.mrmlScene.GetUniqueNameByString(name)) slicer.mrmlScene.AddNode(cylinder) cylinder.CreateDefaultDisplayNodes() lineSource = vtk.vtkLineSource() lineSource.SetPoint1(0, 0, H / 2) lineSource.SetPoint2(0, 0, -H / 2) tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputConnection(lineSource.GetOutputPort()) tubeFilter.SetRadius(R) tubeFilter.SetNumberOfSides(50) tubeFilter.CappingOn() #tubeFilter.Update() cylinder.SetPolyDataConnection(tubeFilter.GetOutputPort()) cylinder.SetAttribute('radius', str(R)) cylinder.SetAttribute('height', str(H)) return cylinder
def probeVolume(self, volumeNode, rulerNode): p0ras=rulerNode.GetPolyData().GetPoint(0)+(1,) p1ras=rulerNode.GetPolyData().GetPoint(1)+(1,) ras2ijk=vtk.vtkMatrix4x4() volumeNode.GetRASToIJKMatrix(ras2ijk) p0ijk= [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]] p1ijk= [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]] line=vtk.vtkLineSource() line.SetPoint1(p0ijk[0],p0ijk[1],p0ijk[2]) line.SetPoint2(p1ijk[0],p1ijk[1],p1ijk[2]) line.SetResolution(100) probe=vtk.vtkProbeFilter() probe.SetInputConnection(line.GetOutputPort()) probe.SetSourceData(volumeNode.GetImageData()) probe.Update() return probe.GetOutput().GetPointData().GetArray('ImageScalars')
def updateOutputArray(self,inputVolume,inputRuler,outputArray,numberOfLineSamples): rulerStartPoint_Ruler = [0,0,0] rulerEndPoint_Ruler = [0,0,0] inputRuler.GetPosition1(rulerStartPoint_Ruler) inputRuler.GetPosition2(rulerEndPoint_Ruler) rulerStartPoint_Ruler1 = [rulerStartPoint_Ruler[0], rulerStartPoint_Ruler[1], rulerStartPoint_Ruler[2], 1.0] rulerEndPoint_Ruler1 = [rulerEndPoint_Ruler[0], rulerEndPoint_Ruler[1], rulerEndPoint_Ruler[2], 1.0] rulerToRAS = vtk.vtkMatrix4x4() rulerTransformNode = inputRuler.GetParentTransformNode() if rulerTransformNode: if rulerTransformNode.IsTransformToWorldLinear(): rulerToRAS.DeepCopy(rulerTransformNode.GetMatrixTransformToParent()) else: print("Cannot handle non-linear transforms - ignoring transform of the input ruler") rulerStartPoint_RAS1 = [0,0,0,1] rulerEndPoint_RAS1 = [0,0,0,1] rulerToRAS.MultiplyPoint(rulerStartPoint_Ruler1,rulerStartPoint_RAS1) rulerToRAS.MultiplyPoint(rulerEndPoint_Ruler1,rulerEndPoint_RAS1) rulerLengthMm = math.sqrt(vtk.vtkMath.Distance2BetweenPoints(rulerStartPoint_RAS1[0:3],rulerEndPoint_RAS1[0:3])) # Need to get the start/end point of the line in the IJK coordinate system # as VTK filters cannot take into account direction cosines rasToIJK = vtk.vtkMatrix4x4() parentToIJK = vtk.vtkMatrix4x4() rasToParent = vtk.vtkMatrix4x4() inputVolume.GetRASToIJKMatrix(parentToIJK) transformNode = inputVolume.GetParentTransformNode() if transformNode: if transformNode.IsTransformToWorldLinear(): rasToParent.DeepCopy(transformNode.GetMatrixTransformToParent()) rasToParent.Invert() else: print ("Cannot handle non-linear transforms - ignoring transform of the input volume") vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK) rulerStartPoint_IJK1 = [0,0,0,1] rulerEndPoint_IJK1 = [0,0,0,1] rasToIJK.MultiplyPoint(rulerStartPoint_RAS1,rulerStartPoint_IJK1) rasToIJK.MultiplyPoint(rulerEndPoint_RAS1,rulerEndPoint_IJK1) lineSource = vtk.vtkLineSource() lineSource.SetPoint1(rulerStartPoint_IJK1[0],rulerStartPoint_IJK1[1],rulerStartPoint_IJK1[2]) lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1], rulerEndPoint_IJK1[2]) lineSource.SetResolution(numberOfLineSamples-1) probeFilter=vtk.vtkProbeFilter() probeFilter.SetInputConnection(lineSource.GetOutputPort()) if vtk.VTK_MAJOR_VERSION <= 5: probeFilter.SetSource(inputVolume.GetImageData()) else: probeFilter.SetSourceData(inputVolume.GetImageData()) probeFilter.Update() probedPoints=probeFilter.GetOutput() # Create arrays of data a = outputArray.GetArray() a.SetNumberOfTuples(probedPoints.GetNumberOfPoints()) x = xrange(0, probedPoints.GetNumberOfPoints()) xStep=rulerLengthMm/(probedPoints.GetNumberOfPoints()-1) probedPointScalars=probedPoints.GetPointData().GetScalars() for i in range(len(x)): a.SetComponent(i, 0, x[i]*xStep) a.SetComponent(i, 1, probedPointScalars.GetTuple(i)[0]) a.SetComponent(i, 2, 0) probedPoints.GetPointData().GetScalars().Modified()
def updateOutputTable(self, inputVolumes, inputRuler, outputTable, lineResolution): rulerLengthMm = self.computeRulerLength(inputRuler) distanceArray = self.getArrayFromTable(outputTable, DISTANCE_ARRAY_NAME) probedPointsList = [] intensityArrayList = [] for inputVolume in inputVolumes: # Need to get the start/end point of the line in the IJK coordinate system # as VTK filters cannot take into account direction cosines rasToIJK = vtk.vtkMatrix4x4() parentToIJK = vtk.vtkMatrix4x4() rasToParent = vtk.vtkMatrix4x4() inputVolume.GetRASToIJKMatrix(parentToIJK) transformNode = inputVolume.GetParentTransformNode() if transformNode: if transformNode.IsTransformToWorldLinear(): rasToParent.DeepCopy( transformNode.GetMatrixTransformToParent()) rasToParent.Invert() else: print( "Cannot handle non-linear transforms - ignoring transform of the input volume" ) vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK) rulerStartPoint_IJK1 = [0, 0, 0, 1] rulerEndPoint_IJK1 = [0, 0, 0, 1] rasToIJK.MultiplyPoint(self.rulerStartPoint_RAS1, rulerStartPoint_IJK1) rasToIJK.MultiplyPoint(self.rulerEndPoint_RAS1, rulerEndPoint_IJK1) lineSource = vtk.vtkLineSource() lineSource.SetPoint1(rulerStartPoint_IJK1[0], rulerStartPoint_IJK1[1], rulerStartPoint_IJK1[2]) lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1], rulerEndPoint_IJK1[2]) lineSource.SetResolution(lineResolution - 1) probeFilter = vtk.vtkProbeFilter() probeFilter.SetInputConnection(lineSource.GetOutputPort()) probeFilter.SetSourceData(inputVolume.GetImageData()) probeFilter.Update() probedPoints = probeFilter.GetOutput() probedPointsList.append(probedPoints) intensityArrayName = INTENSITY_ARRAY_NAME + '_' + inputVolume.GetName( ) intensityArrayList.append( self.getArrayFromTable(outputTable, intensityArrayName)) # Fill tables for probeIndex in range(len(probedPointsList)): probedPoints = probedPointsList[probeIndex] intensityArray = intensityArrayList[probeIndex] # Create arrays of data outputTable.GetTable().SetNumberOfRows( probedPoints.GetNumberOfPoints()) x = range(0, probedPoints.GetNumberOfPoints()) xStep = rulerLengthMm / (probedPoints.GetNumberOfPoints() - 1) if probeIndex == 0: for i in range(len(x)): distanceArray.SetValue(i, x[i] * xStep) probedPointScalars = probedPoints.GetPointData().GetScalars() for i in range(len(x)): intensityArray.SetValue(i, probedPointScalars.GetTuple(i)[0])
def createTemplateModel(self): self.templatePathVectors = [] self.templatePathOrigins = [] tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID) if tempModelNode == None: tempModelNode = slicer.vtkMRMLModelNode() tempModelNode.SetName('NeedleGuideTemplate') slicer.mrmlScene.AddNode(tempModelNode) self.templateModelNodeID = tempModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) self.modelNodetag = tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, self.onTemplateTransformUpdated) tempModelAppend = vtk.vtkAppendPolyData() for row in self.templateConfig: p1 = numpy.array(row[0:3]) p2 = numpy.array(row[3:6]) tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(p1) tempLineSource.SetPoint2(p2) tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() pathLineSource = vtk.vtkLineSource() v = p2-p1 nl = numpy.linalg.norm(v) n = v/nl # normal vector l = row[6] p3 = p1 + l * n pathLineSource.SetPoint1(p1) pathLineSource.SetPoint2(p3) self.templatePathOrigins.append([row[0], row[1], row[2], 1.0]) self.templatePathVectors.append([n[0], n[1], n[2], 1.0]) self.templateMaxDepth.append(row[6]) pathTubeFilter = vtk.vtkTubeFilter() pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort()) pathTubeFilter.SetRadius(0.8) pathTubeFilter.SetNumberOfSides(18) pathTubeFilter.CappingOn() pathTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: tempModelAppend.AddInput(tempTubeFilter.GetOutput()) # pathModelAppend.AddInput(pathTubeFilter.GetOutput()) else: tempModelAppend.AddInputData(tempTubeFilter.GetOutput()) # pathModelAppend.AddInputData(pathTubeFilter.GetOutput()) tempModelAppend.Update() tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput())
def visualNeedlePath(self, pos, pointOnTemplateRAS): if type(pointOnTemplateRAS) == list: pass elif type(pointOnTemplateRAS) == int: pointOnTemplateRAS = self.templateRAS[pointOnTemplateRAS] self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID) if self.pathModelNode == None: self.pathModelNode = slicer.vtkMRMLModelNode() self.pathModelNode.SetName('AngulatedNeedlePath') slicer.mrmlScene.AddNode(self.pathModelNode) self.needlePathModelNodeID = self.pathModelNode.GetID() self.dnodeSelectedPath = slicer.vtkMRMLModelDisplayNode() self.dnodeSelectedPath.SetColor(0, 1, 1) slicer.mrmlScene.AddNode(self.dnodeSelectedPath) self.pathModelNode.SetAndObserveDisplayNodeID(self.dnodeSelectedPath.GetID()) pathModelAppend = vtk.vtkAppendPolyData() tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(pos) # target in RAS tempLineSource.SetPoint2(pointOnTemplateRAS) # point on template in RAS tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() self.setModelSliceIntersectionVisibilityByID(self.needlePathModelNodeID, 1) if vtk.VTK_MAJOR_VERSION <= 5: pathModelAppend.AddInput(tempTubeFilter.GetOutput()) else: pathModelAppend.AddInputData(tempTubeFilter.GetOutput()) pathModelAppend.Update() self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput()) # # Reslice along with the selected needle # print "(target) pos: ", pos print "pointOnTemplateRAS: ", pointOnTemplateRAS R = pointOnTemplateRAS[0] A = pointOnTemplateRAS[1] S = pointOnTemplateRAS[2] deltaR = pos[0] - R deltaA = pos[1] - A deltaS = pos[2] - S pathVector = numpy.array([deltaR, deltaA, deltaS]) tR = numpy.array([1.0, 0, 0]) vectorA = numpy.cross(pathVector, tR) vectorS = numpy.cross(pathVector, vectorA) pathVectorNorm = numpy.linalg.norm(pathVector) vectorANorm = numpy.linalg.norm(vectorA) vectorSNorm = numpy.linalg.norm(vectorS) matrix = vtk.vtkMatrix4x4() matrix.Identity() ## TODO: if pathVector is parallel to R matrix.SetElement(0, 0, pathVector[0]/pathVectorNorm) matrix.SetElement(1, 0, pathVector[1]/pathVectorNorm) matrix.SetElement(2, 0, pathVector[2]/pathVectorNorm) matrix.SetElement(0, 1, vectorA[0]/vectorANorm) matrix.SetElement(1, 1, vectorA[1]/vectorANorm) matrix.SetElement(2, 1, vectorA[2]/vectorANorm) matrix.SetElement(0, 2, vectorS[0]/vectorSNorm) matrix.SetElement(1, 2, vectorS[1]/vectorSNorm) matrix.SetElement(2, 2, vectorS[2]/vectorSNorm) matrix.SetElement(0, 3, R) matrix.SetElement(1, 3, A) matrix.SetElement(2, 3, S) selectNeedleNode = slicer.mrmlScene.GetNodeByID(self.selectNeedleNodeID) if selectNeedleNode == None: selectNeedleNode = slicer.vtkMRMLLinearTransformNode() selectNeedleNode.SetName('SelectedNeedle') slicer.mrmlScene.AddNode(selectNeedleNode) self.selectNeedleNodeID = selectNeedleNode.GetID() selectNeedleNode.SetAndObserveMatrixTransformToParent(matrix) modelNodes = slicer.mrmlScene.GetNodesByClass("vtkMRMLModelNode") for index in range(modelNodes.GetNumberOfItems()): indexNode = modelNodes.GetItemAsObject(index) if indexNode.GetTransformNodeID() == selectNeedleNode.GetID(): indexNode.SetDisplayVisibility(1) self.selectNeedleModelNode = indexNode print indexNode.GetID() red = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeRed") yellow = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeYellow") green = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeGreen") ## Changed by yz, Sep/25 ## If 3D Slicer includes the extension "SlicerIGT", uncomment the below code # vrdLogic = slicer.modules.volumereslicedriver.logic() # redDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), red) # redMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE, red) # yellowDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), yellow) # yellowMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE90, yellow) # greenDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), green) # greenMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_TRANSVERSE, green) # vrdLogic.Modified() return pointOnTemplateRAS
def runSegmentation(self, elList, volume, parentPath, deetoExe, models, createVTK): ### CHECK that both the fiducials and ct volume have been selected if (len(elList) == 0): # notify error slicer.util.showStatusMessage("Error, no electrode list selected") return if (volume == None): # notify error slicer.util.showStatusMessage("Error, no volume selected") return ### COMPUTE THE THRESHOLD the 45% of points not null(0.0) im = volume.GetImageData() # linearize the 3D image in a vector vector = vtk.util.numpy_support.vtk_to_numpy( im.GetPointData().GetScalars()) # eliminate 0.0 value from the vector n_vector = vector[vector != 0] # sort the intensity values n_vector.sort() # compute the threshold as the 45% of points not null threshold = n_vector[int(n_vector.size * 0.45)] ### CREATE A NEW FIDUCIAL LIST CALLED ...... [TODO] mlogic = slicer.modules.markups.logic() ### ### [TODO] Accrocchio, non so come cambiare questi parametri solo ### per il nodo corrente, invece che di default mlogic.SetDefaultMarkupsDisplayNodeTextScale(1.3) mlogic.SetDefaultMarkupsDisplayNodeGlyphScale(1.5) mlogic.SetDefaultMarkupsDisplayNodeColor(0.39, 0.78, 0.78) # AZZURRO mlogic.SetDefaultMarkupsDisplayNodeSelectedColor(0.39, 1.0, 0.39) # VERDONE fidNode = slicer.util.getNode(mlogic.AddNewFiducialNode("recon")) # Save the volume as has been modified self.tmpVolumeFile = parentPath + "/Tmp/tmp.nii.gz" self.saveNode(volume, self.tmpVolumeFile) # Set the parameters of the progess bar and show it self.pb.setRange(0, len(elList)) self.pb.show() self.pb.setValue(0) slicer.app.processEvents() # For each electrode "e": for i in xrange(len(elList)): tFlag = "-l" if (elList[i].tailCheckBox.isChecked() == True) else "-t" hFlag = "-h" if (elList[i].headCheckBox.isChecked() == True) else "-e" # Construct the cmdLine to run the segmentation on "e" cmdLine = [str(deetoExe), '-s', str(threshold), '-ct', str(self.tmpVolumeFile), \ hFlag, str(-1 * elList[i].entry[0]), str(-1 * elList[i].entry[1]), \ str(elList[i].entry[2]), tFlag, \ str(-1 * elList[i].target[0]), str(-1 * elList[i].target[1]), \ str(elList[i].target[2]), '-m'] + \ map(str, models[elList[i].model.currentText][:-1]) print cmdLine # RUN the command line cmdLine. # [NOTE] : I have used Popen since subprocess.check_output wont work at the moment # It Looks a problem of returning code from deetoS points = subprocess.Popen( cmdLine, stdout=subprocess.PIPE).communicate()[0].splitlines() # print points ### For each of the point returned by deeto we add it to the new markup fiducial name = elList[i].name.text for p in range(0, (len(points) - 1), 3): a = fidNode.AddFiducial(float(points[p]), float(points[p + 1]), float(points[p + 2])) fidNode.SetNthFiducialLabel(a, name + str((p / 3) + 1)) ### For each electrode we create a line from the start point to the last + 3mm ### Look for two points p1 and p3 starting from p1 and p2 (first and last point segmented last = len(points) - 1 p1 = [float(points[0]), float(points[1]), float(points[2])] p2 = [ float(points[last - 2]), float(points[last - 1]), float(points[last]) ] delta = math.sqrt( math.pow((p1[0] - p2[0]), 2) + math.pow((p1[1] - p2[1]), 2) + math.pow((p1[2] - p2[2]), 2)) p3 = [0.0, 0.0, 0.0] p3[0] = p2[0] + (p2[0] - p1[0]) / delta * 3 # distance 3mm p3[1] = p2[1] + (p2[1] - p1[1]) / delta * 3 # distance 3mm p3[2] = p2[2] + (p2[2] - p1[2]) / delta * 3 # distance 3mm if createVTK.checked: ### Create a vtk line lineSource = vtk.vtkLineSource() lineSource.SetPoint1(p1) lineSource.SetPoint2(p3) lineSource.SetResolution(100) ## why? lineSource.Update() ### Create a model of the line to add to the scene model = slicer.vtkMRMLModelNode() model.SetName(name + "_direction") model.SetAndObservePolyData(lineSource.GetOutput()) modelDisplay = slicer.vtkMRMLModelDisplayNode() modelDisplay.SetSliceIntersectionVisibility( True) # Hide in slice view modelDisplay.SetVisibility(True) # Show in 3D view modelDisplay.SetColor(1, 0, 0) modelDisplay.SetLineWidth(2) slicer.mrmlScene.AddNode(modelDisplay) model.SetAndObserveDisplayNodeID(modelDisplay.GetID()) slicer.mrmlScene.AddNode(model) # Lock all markup mlogic.SetAllMarkupsLocked(fidNode, True) # update progress bar self.pb.setValue(i + 1) slicer.app.processEvents() self.pb.hide()
def updateOutputArray(self,inputVolume,inputRuler,outputArray,lineResolution): rulerStartPoint_Ruler = [0,0,0] rulerEndPoint_Ruler = [0,0,0] inputRuler.GetPosition1(rulerStartPoint_Ruler) inputRuler.GetPosition2(rulerEndPoint_Ruler) rulerStartPoint_Ruler1 = [rulerStartPoint_Ruler[0], rulerStartPoint_Ruler[1], rulerStartPoint_Ruler[2], 1.0] rulerEndPoint_Ruler1 = [rulerEndPoint_Ruler[0], rulerEndPoint_Ruler[1], rulerEndPoint_Ruler[2], 1.0] rulerToRAS = vtk.vtkMatrix4x4() rulerTransformNode = inputRuler.GetParentTransformNode() if rulerTransformNode: if rulerTransformNode.IsTransformToWorldLinear(): rulerToRAS.DeepCopy(rulerTransformNode.GetMatrixTransformToParent()) else: print ("Cannot handle non-linear transforms - ignoring transform of the input ruler") rulerStartPoint_RAS1 = [0,0,0,1] rulerEndPoint_RAS1 = [0,0,0,1] rulerToRAS.MultiplyPoint(rulerStartPoint_Ruler1,rulerStartPoint_RAS1) rulerToRAS.MultiplyPoint(rulerEndPoint_Ruler1,rulerEndPoint_RAS1) rulerLengthMm=math.sqrt(vtk.vtkMath.Distance2BetweenPoints(rulerStartPoint_RAS1[0:3],rulerEndPoint_RAS1[0:3])) # Need to get the start/end point of the line in the IJK coordinate system # as VTK filters cannot take into account direction cosines rasToIJK = vtk.vtkMatrix4x4() parentToIJK = vtk.vtkMatrix4x4() rasToParent = vtk.vtkMatrix4x4() inputVolume.GetRASToIJKMatrix(parentToIJK) transformNode = inputVolume.GetParentTransformNode() if transformNode: if transformNode.IsTransformToWorldLinear(): rasToParent.DeepCopy(transformNode.GetMatrixTransformToParent()) rasToParent.Invert() else: print ("Cannot handle non-linear transforms - ignoring transform of the input volume") vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK) rulerStartPoint_IJK1 = [0,0,0,1] rulerEndPoint_IJK1 = [0,0,0,1] rasToIJK.MultiplyPoint(rulerStartPoint_RAS1,rulerStartPoint_IJK1) rasToIJK.MultiplyPoint(rulerEndPoint_RAS1,rulerEndPoint_IJK1) lineSource=vtk.vtkLineSource() lineSource.SetPoint1(rulerStartPoint_IJK1[0],rulerStartPoint_IJK1[1],rulerStartPoint_IJK1[2]) lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1], rulerEndPoint_IJK1[2]) lineSource.SetResolution(lineResolution-1) probeFilter=vtk.vtkProbeFilter() probeFilter.SetInputConnection(lineSource.GetOutputPort()) if vtk.VTK_MAJOR_VERSION <= 5: probeFilter.SetSource(inputVolume.GetImageData()) else: probeFilter.SetSourceData(inputVolume.GetImageData()) probeFilter.Update() probedPoints=probeFilter.GetOutput() # Create arrays of data a = outputArray.GetArray() a.SetNumberOfTuples(probedPoints.GetNumberOfPoints()) x = xrange(0, probedPoints.GetNumberOfPoints()) xStep=rulerLengthMm/(probedPoints.GetNumberOfPoints()-1) probedPointScalars=probedPoints.GetPointData().GetScalars() for i in range(len(x)): a.SetComponent(i, 0, x[i]*xStep) a.SetComponent(i, 1, probedPointScalars.GetTuple(i)[0]) a.SetComponent(i, 2, 0) probedPoints.GetPointData().GetScalars().Modified()
def createTemplateModel(self): self.templatePathVectors = [] self.templatePathOrigins = [] self.tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID) if self.tempModelNode is None: self.tempModelNode = slicer.vtkMRMLModelNode() self.tempModelNode.SetName('NeedleGuideTemplate') slicer.mrmlScene.AddNode(self.tempModelNode) self.templateModelNodeID = self.tempModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() #dnode.SetColor(self.ModelColor) slicer.mrmlScene.AddNode(dnode) self.tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) self.modelNodetag = self.tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, self.onTemplateTransformUpdated) self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID) if self.pathModelNode is None: self.pathModelNode = slicer.vtkMRMLModelNode() self.pathModelNode.SetName('NeedleGuideNeedlePath') slicer.mrmlScene.AddNode(self.pathModelNode) self.needlePathModelNodeID = self.pathModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) self.pathModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) pathModelAppend = vtk.vtkAppendPolyData() tempModelAppend = vtk.vtkAppendPolyData() for row in self.templateConfig: p1 = numpy.array(row[0:3]) p2 = numpy.array(row[3:6]) tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(p1) tempLineSource.SetPoint2(p2) tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() pathLineSource = vtk.vtkLineSource() v = p2-p1 nl = numpy.linalg.norm(v) n = v/nl # normal vector l = row[6] p3 = p1 + l * n pathLineSource.SetPoint1(p1) pathLineSource.SetPoint2(p3) self.templatePathOrigins.append([row[0], row[1], row[2], 1.0]) self.templatePathVectors.append([n[0], n[1], n[2], 1.0]) self.templateMaxDepth.append(row[6]) pathTubeFilter = vtk.vtkTubeFilter() pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort()) pathTubeFilter.SetRadius(0.8) pathTubeFilter.SetNumberOfSides(18) pathTubeFilter.CappingOn() pathTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: tempModelAppend.AddInput(tempTubeFilter.GetOutput()) pathModelAppend.AddInput(pathTubeFilter.GetOutput()) else: tempModelAppend.AddInputData(tempTubeFilter.GetOutput()) pathModelAppend.AddInputData(pathTubeFilter.GetOutput()) tempModelAppend.Update() self.tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput()) pathModelAppend.Update() self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput())
def runSegmentation(self,elList,volume,parentPath,deetoExe,models): ### CHECK that both the fiducials and ct volume have been selected if (len(elList) == 0): # notify error slicer.util.showStatusMessage("Error, no electrode list selected") return if ( volume == None): # notify error slicer.util.showStatusMessage("Error, no volume selected") return ### COMPUTE THE THRESHOLD the 45% of points not null(0.0) im = volume.GetImageData() # linearize the 3D image in a vector vector = vtk.util.numpy_support.vtk_to_numpy(im.GetPointData().GetScalars()) # eliminate 0.0 value from the vector n_vector = vector[vector != 0] # sort the intensity values n_vector.sort() # compute the threshold as the 45% of points not null threshold = n_vector[int(n_vector.size * 0.45)] ### CREATE A NEW FIDUCIAL LIST CALLED ...... [TODO] mlogic = slicer.modules.markups.logic() ### ### [TODO] Accrocchio, non so come cambiare questi parametri solo ### per il nodo corrente, invece che di default mlogic.SetDefaultMarkupsDisplayNodeTextScale(1.3) mlogic.SetDefaultMarkupsDisplayNodeGlyphScale(1.5) mlogic.SetDefaultMarkupsDisplayNodeColor(0.39,0.78,0.78) # AZZURRO CACCA mlogic.SetDefaultMarkupsDisplayNodeSelectedColor(0.39,1.0,0.39) # VERDONE CACCA fidNode = slicer.util.getNode(mlogic.AddNewFiducialNode("recon")) # Save the volume as has been modified self.tmpVolumeFile = parentPath + "/Tmp/tmp.nii.gz" self.saveNode(volume,self.tmpVolumeFile) # Set the parameters of the progess bar and show it self.pb.setRange(0,len(elList)) self.pb.show() self.pb.setValue(0) slicer.app.processEvents() # For each electrode "e": for i in xrange(len(elList)): tFlag = "-l" if (elList[i].tailCheckBox.isChecked() == True) else "-t" hFlag = "-h" if (elList[i].headCheckBox.isChecked() == True) else "-e" # Construct the cmdLine to run the segmentation on "e" cmdLine = [str(deetoExe),'-s',str(threshold),'-ct',str(self.tmpVolumeFile),\ hFlag, str(-1*elList[i].entry[0]), str(-1*elList[i].entry[1]), \ str(elList[i].entry[2]), tFlag ,\ str(-1*elList[i].target[0]),str(-1*elList[i].target[1]),\ str(elList[i].target[2]),'-m'] +\ map(str,models[elList[i].model.currentText]) print cmdLine # RUN the command line cmdLine. # [NOTE] : I have used Popen since subprocess.check_output wont work at the moment # It Looks a problem of returning code from deetoS points = subprocess.Popen(cmdLine,stdout=subprocess.PIPE).communicate()[0].splitlines() # print points ### For each of the point returned by deeto we add it to the new markup fiducial name = elList[i].name.text for p in range(0,(len(points) - 1),3): a = fidNode.AddFiducial(float(points[p]),float(points[p+1]),float(points[p+2])) fidNode.SetNthFiducialLabel(a, name + str((p/3) + 1)) ### For each electrode we create a line from the start point to the last + 3mm ### Look for two points p1 and p3 starting from p1 and p2 (first and last point segmented last = len(points) - 1 p1 = [float(points[0]), float(points[1]), float(points[2])] p2 = [float(points[last - 2]), float(points[last-1]), float(points[last])] delta = math.sqrt(math.pow((p1[0] - p2[0]),2) + math.pow((p1[1] - p2[1]),2) + math.pow((p1[2] - p2[2]),2)) p3 = [0.0,0.0,0.0] p3[0] = p2[0] + (p2[0] - p1[0]) / delta * 3 # distance 3mm p3[1] = p2[1] + (p2[1] - p1[1]) / delta * 3 # distance 3mm p3[2] = p2[2] + (p2[2] - p1[2]) / delta * 3 # distance 3mm ### Create a vtk line lineSource = vtk.vtkLineSource() lineSource.SetPoint1(p1) lineSource.SetPoint2(p3) lineSource.SetResolution(100) ## why? lineSource.Update() ### Create a model of the line to add to the scene model = slicer.vtkMRMLModelNode() model.SetName(name + "_direction") model.SetAndObservePolyData(lineSource.GetOutput()) modelDisplay = slicer.vtkMRMLModelDisplayNode() modelDisplay.SetSliceIntersectionVisibility(True) # Hide in slice view modelDisplay.SetVisibility(True) # Show in 3D view modelDisplay.SetColor(1,0,0) modelDisplay.SetLineWidth(2) slicer.mrmlScene.AddNode(modelDisplay) model.SetAndObserveDisplayNodeID(modelDisplay.GetID()) slicer.mrmlScene.AddNode(model) # update progress bar self.pb.setValue(i+1) slicer.app.processEvents() self.pb.hide()