Exemple #1
0
 def testStorageValue(self, logic):
     print " Test storage of Values: "
     bool = True
     arrayValue = vtk.vtkDoubleArray()
     arrayMask = vtk.vtkDoubleArray()
     for i in range(0, 1000, 2):
         arrayValue.InsertNextValue(i)
         arrayValue.InsertNextValue(i)
         arrayMask.InsertNextValue(0.0)
         arrayMask.InsertNextValue(0.0)
     listOfRandomNumber = list()
     del listOfRandomNumber[:]
     for i in range(0, 250):
         listOfRandomNumber.append(randint(0, 998))
     listOfRandomNumber = set(listOfRandomNumber)
     listOfRandomNumber = sorted(listOfRandomNumber)
     for index in listOfRandomNumber:
         arrayMask.SetValue(index, 1.0)
     array = logic.defineArray(arrayValue, arrayMask)
     array = sorted(array)
     a = 0
     for i in listOfRandomNumber:
         if arrayValue.GetValue(i) != array[a]:
             bool = False
             print "        Failed", a, array[a], i, arrayValue.GetValue(i)
             break
         a += 1
     if bool:
         print "         Passed"
    def testStorageValue(self):
        logic = MeshStatisticsLogic()
        print " Test storage of Values: "
        arrayValue = vtk.vtkDoubleArray()
        arrayMask = vtk.vtkDoubleArray()
        for i in range(0, 1000, 2):
            arrayValue.InsertNextValue(i)
            arrayValue.InsertNextValue(i)
            arrayMask.InsertNextValue(0.0)
            arrayMask.InsertNextValue(0.0)
        listOfRandomNumber = list()
        del listOfRandomNumber[:]
        for i in range(0, 250):
            listOfRandomNumber.append(randint(0, 998))

        listOfRandomNumber = list(set(listOfRandomNumber))
        listOfRandomNumber = sorted(listOfRandomNumber)
        for index in listOfRandomNumber:
            arrayMask.SetValue(index, 1.0)
        bool, array = logic.defineArray(arrayValue, arrayMask)
        array = sorted(array)
        a = 0
        for i in listOfRandomNumber:
            if arrayValue.GetValue(i) != array[a]:
                print "        Failed", a, array[a], i, arrayValue.GetValue(i)
                return False
            a += 1
        print "         Passed"
        return True
Exemple #3
0
    def testStorageValue(self):
        logic = MeshStatisticsLogic()
        print ' Test storage of Values: '
        arrayValue = vtk.vtkDoubleArray()
        arrayMask = vtk.vtkDoubleArray()
        for i in range(0, 1000, 2):
            arrayValue.InsertNextValue(i)
            arrayValue.InsertNextValue(i)
            arrayMask.InsertNextValue(0.0)
            arrayMask.InsertNextValue(0.0)
        listOfRandomNumber = list()
        del listOfRandomNumber[:]
        for i in range(0, 250):
            listOfRandomNumber.append(randint(0, 998))

        listOfRandomNumber = list(set(listOfRandomNumber))
        listOfRandomNumber = sorted(listOfRandomNumber)
        for index in listOfRandomNumber:
            arrayMask.SetValue(index, 1.0)
        bool, array = logic.defineArray(arrayValue, arrayMask)
        array = sorted(array)
        a = 0
        for i in listOfRandomNumber:
            if arrayValue.GetValue(i) != array[a]:
                print '        Failed', a, array[a], i, arrayValue.GetValue(i)
                return False
            a += 1
        print '         Passed'
        return True
Exemple #4
0
 def defineArrays(self, logic, firstValue, lastValue):
     arrayValue = vtk.vtkDoubleArray()
     ROIArray = vtk.vtkDoubleArray()
     for i in range(firstValue, lastValue):
         arrayValue.InsertNextValue(i)
         ROIArray.InsertNextValue(1.0)
     array = logic.defineArray(arrayValue, ROIArray)
     return array
Exemple #5
0
 def defineArrays(self, logic, firstValue, lastValue):
     arrayValue = vtk.vtkDoubleArray()
     ROIArray = vtk.vtkDoubleArray()
     for i in range(firstValue, lastValue):
         arrayValue.InsertNextValue(i)
         ROIArray.InsertNextValue(1.0)
     bool, array = logic.defineArray(arrayValue, ROIArray)
     if bool:
         return array
     return False
Exemple #6
0
    def populateChart(self):
        # strip elements from 2nd 3d view
        # and add our own chart renderer to it
        self.aModeImageNode = slicer.util.getNode('Image_NeedleTip')
        if self.aModeImageNode is None:
            logging.debug(
                "Cannot locate Image_NeedleTip, can't visualize chart")
            return

        self.imageData = self.aModeImageNode.GetImageData()

        if not self.table is None:
            # We already have created all of the things, don't recreate
            self.view.GetInteractor().Initialize()
            self.chart.RecalculateBounds()
            return

        self.table = vtk.vtkTable()
        self.chart = vtk.vtkChartXY()
        self.line = self.chart.AddPlot(0)
        self.view = vtk.vtkContextView()
        self.signalArray = vtk.vtkDoubleArray()
        self.signalArray.SetName("RF Signal")
        self.distanceArray = vtk.vtkDoubleArray()
        self.distanceArray.SetName("Distance (mm)")

        self.imageDimensions = self.imageData.GetDimensions()
        self.signalArray.SetNumberOfTuples(self.imageDimensions[0])
        self.distanceArray.SetNumberOfTuples(self.imageDimensions[0])

        self.table.AddColumn(self.distanceArray)
        self.table.AddColumn(self.signalArray)

        self.line = self.chart.AddPlot(0)
        self.line.SetInputData(self.table, 0, 1)
        self.line.SetColor(0, 255, 0, 255)
        self.line.SetWidth(1.0)

        inc = 1000 * 1480 / (
            2 * 420e6
        )  # distance in mm. The delay distance is added to the increments.  (2e-6*1480/2) +
        distanceDelay = 1000 * 2e-6 * 1480 / 2
        for i in range(self.imageDimensions[0]):
            self.distanceArray.SetComponent(i, 0, distanceDelay + inc * i)

        self.view.GetRenderer().SetBackground(1.0, 1.0, 1.0)
        self.view.GetRenderWindow().SetSize(400, 300)
        # self.contextScene = vtk.vtkContextScene()
        # self.contextScene.AddItem(self.chart)
        # self.contextActor = vtk.vtkContextActor()
        self.view.GetScene().AddItem(self.chart)
        self.view.GetRenderWindow().SetMultiSamples(0)
        # self.layoutManager.threeDWidget(1).threeDView.renderWindow().GetRenderer().GetFirstRenderer().AddActor(self.contextActor)

        self.view.GetInteractor().Initialize()
Exemple #7
0
def ConvertTextureToPointAttribute(modelNode, textureImageNode):
  polyData=modelNode.GetPolyData()
  textureImageFlipVert=vtk.vtkImageFlip()
  textureImageFlipVert.SetFilteredAxis(1)
  textureImageFlipVert.SetInputConnection(textureImageNode.GetImageDataConnection())
  textureImageFlipVert.Update()
  textureImageData=textureImageFlipVert.GetOutput()
  pointData=polyData.GetPointData()
  tcoords=pointData.GetTCoords()
  numOfPoints=pointData.GetNumberOfTuples()
  assert numOfPoints==tcoords.GetNumberOfTuples(), "Number of texture coordinates does not equal number of points"
  textureSamplingPointsUv=vtk.vtkPoints()
  textureSamplingPointsUv.SetNumberOfPoints(numOfPoints)
  for pointIndex in xrange(numOfPoints):
    uv=tcoords.GetTuple2(pointIndex)
    textureSamplingPointsUv.SetPoint(pointIndex, uv[0], uv[1], 0)

  textureSamplingPointDataUv=vtk.vtkPolyData()
  uvToXyz=vtk.vtkTransform()
  textureImageDataSpacingSpacing=textureImageData.GetSpacing()
  textureImageDataSpacingOrigin=textureImageData.GetOrigin()
  textureImageDataSpacingDimensions=textureImageData.GetDimensions()
  uvToXyz.Scale(textureImageDataSpacingDimensions[0]/textureImageDataSpacingSpacing[0], textureImageDataSpacingDimensions[1]/textureImageDataSpacingSpacing[1], 1)
  uvToXyz.Translate(textureImageDataSpacingOrigin)
  textureSamplingPointDataUv.SetPoints(textureSamplingPointsUv)
  transformPolyDataToXyz=vtk.vtkTransformPolyDataFilter()
  transformPolyDataToXyz.SetInputData(textureSamplingPointDataUv)
  transformPolyDataToXyz.SetTransform(uvToXyz)
  probeFilter=vtk.vtkProbeFilter()
  probeFilter.SetInputConnection(transformPolyDataToXyz.GetOutputPort())
  probeFilter.SetSourceData(textureImageData)
  probeFilter.Update()
  rgbPoints=probeFilter.GetOutput().GetPointData().GetArray('ImageScalars')
  colorArrayRed=vtk.vtkDoubleArray()
  colorArrayRed.SetName('ColorRed')
  colorArrayRed.SetNumberOfTuples(numOfPoints)
  colorArrayGreen=vtk.vtkDoubleArray()
  colorArrayGreen.SetName('ColorGreen')
  colorArrayGreen.SetNumberOfTuples(numOfPoints)
  colorArrayBlue=vtk.vtkDoubleArray()
  colorArrayBlue.SetName('ColorBlue')
  colorArrayBlue.SetNumberOfTuples(numOfPoints)
  for pointIndex in xrange(numOfPoints):
    rgb=rgbPoints.GetTuple3(pointIndex)
    colorArrayRed.SetValue(pointIndex,rgb[0])
    colorArrayGreen.SetValue(pointIndex,rgb[1])
    colorArrayBlue.SetValue(pointIndex,rgb[2])
  colorArrayRed.Modified()
  colorArrayGreen.Modified()
  colorArrayBlue.Modified()
  pointData.AddArray(colorArrayRed)
  pointData.AddArray(colorArrayGreen)
  pointData.AddArray(colorArrayBlue)
  pointData.Modified()
  polyData.Modified()
  def CalculatePlane( self, inPoints, base, dir1, dir2, normal ):

    # Create arrays for the dataset
    points2D = vtk.vtkPoints()
  
    arrayX = vtk.vtkDoubleArray()
    arrayX.SetNumberOfComponents( 1 )
    arrayX.SetName ( 'X' )
    arrayY = vtk.vtkDoubleArray()
    arrayY.SetNumberOfComponents( 1 )
    arrayY.SetName ( 'Y' )
    arrayZ = vtk.vtkDoubleArray()
    arrayZ.SetNumberOfComponents( 1 )
    arrayZ.SetName ( 'Z' )
    
    # Add the points to the table
    for i in range( 0, inPoints.GetNumberOfPoints() ):
    
      currPoint = [ 0, 0, 0 ]
      inPoints.GetPoint( i, currPoint )   
      
      arrayX.InsertNextValue( currPoint[ 0 ] )
      arrayY.InsertNextValue( currPoint[ 1 ] ) 
      arrayZ.InsertNextValue( currPoint[ 2 ] )
    
    # Create a table for the dataset
    table = vtk.vtkTable()
    table.AddColumn( arrayX )
    table.AddColumn( arrayY )
    table.AddColumn( arrayZ )
    
    # Setting up the PCA
    pca = vtk.vtkPCAStatistics()
    pca.SetInputData( vtk.vtkStatisticsAlgorithm.INPUT_DATA, table )
    pca.SetColumnStatus( 'X', 1 )
    pca.SetColumnStatus( 'Y', 1 )
    pca.SetColumnStatus( 'Z', 1 )
    pca.RequestSelectedColumns()
    pca.SetDeriveOption( True )
    pca.Update()
    
    eigvec = vtk.vtkDoubleArray()
    pca.GetEigenvectors( eigvec )
  
    
    eigvec.GetTuple( 0, dir1 )
    eigvec.GetTuple( 1, dir2 )
    eigvec.GetTuple( 2, normal )
  
    mean = self.CalculateMean( inPoints )
    base[0] = mean[0]
    base[1] = mean[1]
    base[2] = mean[2]
Exemple #9
0
    def importFunction(self):

        # check if the output container exists
        mvNode = self.outputSelector.currentNode()
        #print(mvNode)
        if mvNode == None:
            self.__status.text = 'Status: Select output node!'
            return

        fileNames = []  # file names on disk
        frameList = []  # frames as MRMLScalarVolumeNode's
        frameFolder = ""
        volumeLabels = vtk.vtkDoubleArray()
        frameLabelsAttr = ''
        frameFileListAttr = ''
        dicomTagNameAttr = self.__dicomTag.text
        dicomTagUnitsAttr = self.__veLabel.text
        teAttr = self.__te.text
        trAttr = self.__tr.text
        faAttr = self.__fa.text

        # each frame is saved as a separate volume
        # first filter valid file names and sort alphabetically
        frames = []
        frame0 = None
        inputDir = self.__fDialog.directory
        print(inputDir)
 def performPostProcessing(self, snrThreshold, distanceMinimumValue, distanceMaximumValue): 
   # Create new vtkPolyData
   newPoints = vtk.vtkPoints()
   newVertices = vtk.vtkCellArray()               
   newPolyData = vtk.vtkPolyData()
   newPolyData.SetPoints(newPoints)
   newPolyData.SetVerts(newVertices)
   colorArray = vtk.vtkDoubleArray()
   colorArray.SetNumberOfComponents(4)
   colorArray.SetName('Colors')
   newPolyData.GetPointData().SetScalars(colorArray)   
   # Filter accordingly to the input parameters
   recordedDataBufferFiltered = []    
   for idx in range(len(self.recordedDataBuffer)):
     d = self.recordedDataBuffer[idx][3]
     snr = self.recordedDataBuffer[idx][4]
     if (snr > snrThreshold and
         d < distanceMaximumValue and       
         d > distanceMinimumValue):
         recordedDataBufferFiltered.append(self.recordedDataBuffer[idx])   
         self.addPointToPolyData(newPolyData, self.recordedDataBuffer[idx][0:3])
   # Update recorded model and buffer
   self.recordedModelNode.GetPolyData().DeepCopy(newPolyData)     
   self.recordedModelNode.GetPolyData().Modified()  
   self.recordedDataBuffer = recordedDataBufferFiltered
 def getArrayFromTable(self, outputTable, arrayName):
     distanceArray = outputTable.GetTable().GetColumnByName(arrayName)
     if distanceArray:
         return distanceArray
     newArray = vtk.vtkDoubleArray()
     newArray.SetName(arrayName)
     outputTable.GetTable().AddColumn(newArray)
     return newArray
 def clearPointsInRecordedModel(self): 
   self.recordedDataBuffer = [] 
   newPoints = vtk.vtkPoints()
   newVertices = vtk.vtkCellArray()               
   newPolyData = vtk.vtkPolyData()
   newPolyData.SetPoints(newPoints)
   newPolyData.SetVerts(newVertices)
   colorArray = vtk.vtkDoubleArray()
   colorArray.SetNumberOfComponents(4)
   colorArray.SetName('Colors')
   newPolyData.GetPointData().SetScalars(colorArray)   
   self.recordedModelNode.GetPolyData().DeepCopy(newPolyData)     
   self.recordedModelNode.GetPolyData().Modified()        
 def undoPostProcessing(self):
   # Create new vtkPolyData
   newPoints = vtk.vtkPoints()
   newVertices = vtk.vtkCellArray()               
   newPolyData = vtk.vtkPolyData()
   newPolyData.SetPoints(newPoints)
   newPolyData.SetVerts(newVertices)
   colorArray = vtk.vtkDoubleArray()
   colorArray.SetNumberOfComponents(4)
   colorArray.SetName('Colors')
   newPolyData.GetPointData().SetScalars(colorArray)   
   # Filter accordingly to the input parameters
   recordedDataBufferFiltered = []    
   for idx in range(len(self.recordedDataBufferDefault)):
     self.addPointToPolyData(newPolyData, self.recordedDataBufferDefault[idx][0:3])
   # Update recorded model and buffer
   self.recordedModelNode.GetPolyData().DeepCopy(newPolyData)     
   self.recordedModelNode.GetPolyData().Modified()  
   self.recordedDataBuffer = self.recordedDataBufferDefault
  def onImportButtonClicked(self):
    # check if the output container exists
    mvNode = self.__mvSelector.currentNode()
    if mvNode == None:
      self.__status.text = 'Status: Select output node!'
      return

    modeIdx = self.__modeSelector.currentIndex
    processingMode = self.__processingModes[modeIdx]

    # There are two options:
    # 1. DICOM series in a directory, with either predefined or custom parse tag
    # 2. Series of frames alpha-ordered, all in the input directory
    # Assume here that the last mode in the list is for parsing a list of
    # non-DICOM frames

    fileNames = []    # file names on disk
    frameList = []    # frames as MRMLScalarVolumeNode's
    frameFolder = ""
    volumeLabels = vtk.vtkDoubleArray()

    if modeIdx < len(self.__processingModes)-1:
      # DICOM series

      # get logic
      logic = slicer.modules.multivolumeexplorer.logic()

      # create a clean temporary directory
      tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory')
      if not os.path.exists(tmpDir):
        os.mkdir(tmpDir)
      tmpDir = tmpDir+'/MultiVolumeImporter'
      if not os.path.exists(tmpDir):
        os.mkdir(tmpDir)
      else:
        # clean it up
        print("tmpDir: %s" % tmpDir)
        oldFileNames = os.listdir(tmpDir)
        for f in oldFileNames:
          print("%s will be unlinked" % f)
          os.unlink(tmpDir+'/'+f)

      nFrames = logic.ProcessDICOMSeries(self.__fDialog.directory, tmpDir, self.__dicomTag.text, volumeLabels)

      self.__status.text = 'Series processed OK, '+str(nFrames)+' volumes identified'

      print("Location of files: %s" % tmpDir)
      for f in os.listdir(tmpDir):
        if not f.startswith('.'):
          fileNames.append(f)
      fileNames.sort()

      frameFolder = tmpDir

    else:
      # each frame is saved as a separate volume
      for f in os.listdir(self.__fDialog.directory):
        if not f.startswith('.'):
          fileNames.append(f)
      fileNames.sort()

      frameFolder = self.__fDialog.directory
      nFrames = len(fileNames)
      volumeLabels.SetNumberOfTuples(nFrames)
      volumeLabels.SetNumberOfComponents(1)
      volumeLabels.Allocate(nFrames)
      for i in range(len(fileNames)):
        frameId = self.__veInitial.value+self.__veStep.value*i
        volumeLabels.SetComponent(i, 0, frameId)

    # read the first frame to get the extent for DWI node
    fullName = frameFolder+'/'+fileNames[0]
    volumesLogic = slicer.modules.volumes.logic()
    frame = volumesLogic.AddArchetypeVolume(fullName, processingMode[3]+' Frame 0', 0)
    frameImage = frame.GetImageData()
    frameExtent = frameImage.GetExtent()
    frameSize = frameExtent[1]*frameExtent[3]*frameExtent[5]

    nFrames = len(fileNames)
    mvImage = vtk.vtkImageData()
    mvImage.SetExtent(frameExtent)
    mvImage.SetNumberOfScalarComponents(nFrames)

    mvImage.AllocateScalars()
    mvImageArray = vtk.util.numpy_support.vtk_to_numpy(mvImage.GetPointData().GetScalars())

    mat = vtk.vtkMatrix4x4()
    frame.GetRASToIJKMatrix(mat)
    mvNode.SetRASToIJKMatrix(mat)
    frame.GetIJKToRASMatrix(mat)
    mvNode.SetIJKToRASMatrix(mat)

    self.annihilateScalarNode(frame)

    for frameId in range(0,nFrames):
      fullName = frameFolder+'/'+fileNames[frameId]
      print("Processing frame %d: %s" % (frameId, fullName))
      frame = volumesLogic.AddArchetypeVolume(fullName, 'Frame'+str(frameId), 0)
      frameImage = frame.GetImageData()
      frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())
      mvImageArray.T[frameId] = frameImageArray
      self.annihilateScalarNode(frame)

    mvDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    mvDisplayNode.SetScene(slicer.mrmlScene)
    slicer.mrmlScene.AddNode(mvDisplayNode)
    mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount()-1)
    mvDisplayNode.SetDefaultColorMap()

    mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
    mvNode.SetAndObserveImageData(mvImage)
    mvNode.SetNumberOfFrames(nFrames)
    slicer.mrmlScene.AddNode(mvNode)
    mvNode.SetReferenceCount(mvNode.GetReferenceCount()-1)

    mvNode.SetLabelArray(volumeLabels)
    mvNode.SetLabelName(self.__veLabel.text)
    print("MultiVolume node setup complete !")

    Helper.SetBgFgVolumes(mvNode.GetID(),None)
    def onImportButtonClicked(self):
        # check if the output container exists
        mvNode = self.__mvSelector.currentNode()
        if mvNode == None:
            self.__status.text = 'Status: Select output node!'
            return

        # Series of frames alpha-ordered, all in the input directory
        # Assume here that the last mode in the list is for parsing a list of
        # non-DICOM frames

        fileNames = []  # file names on disk
        frameList = []  # frames as MRMLScalarVolumeNode's
        frameFolder = ""
        volumeLabels = vtk.vtkDoubleArray()
        frameLabelsAttr = ''
        frameFileListAttr = ''
        dicomTagNameAttr = self.__dicomTag.text
        dicomTagUnitsAttr = self.__veLabel.text
        teAttr = self.__te.text
        trAttr = self.__tr.text
        faAttr = self.__fa.text

        # each frame is saved as a separate volume
        for f in os.listdir(self.__fDialog.directory):
            if not f.startswith('.'):
                fileNames.append(f)
                frameFileListAttr += f + ','
        fileNames.sort()

        frameFileListAttr = frameFileListAttr[:-1]

        frameFolder = self.__fDialog.directory
        nFrames = len(fileNames)
        volumeLabels.SetNumberOfTuples(nFrames)
        volumeLabels.SetNumberOfComponents(1)
        volumeLabels.Allocate(nFrames)
        for i in range(len(fileNames)):
            frameId = self.__veInitial.value + self.__veStep.value * i
            volumeLabels.SetComponent(i, 0, frameId)
            frameLabelsAttr += str(frameId) + ','
        frameLabelsAttr = frameLabelsAttr[:-1]

        # read the first frame to get the extent
        fullName = frameFolder + '/' + fileNames[0]
        volumesLogic = slicer.modules.volumes.logic()
        frame = self.readFrame(fullName)
        frameImage = frame.GetImageData()
        frameExtent = frameImage.GetExtent()
        frameSize = frameExtent[1] * frameExtent[3] * frameExtent[5]

        nFrames = len(fileNames)
        mvImage = vtk.vtkImageData()
        mvImage.SetExtent(frameExtent)
        mvImage.SetNumberOfScalarComponents(nFrames)

        mvImage.AllocateScalars()
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(
            mvImage.GetPointData().GetScalars())

        mat = vtk.vtkMatrix4x4()
        frame.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

        for frameId in range(0, nFrames):
            fullName = frameFolder + '/' + fileNames[frameId]
            print("Processing frame %d: %s" % (frameId, fullName))

            frame = self.readFrame(fullName)
            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(
                frameImage.GetPointData().GetScalars())
            mvImageArray.T[frameId] = frameImageArray

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(nFrames)

        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName(self.__veLabel.text)

        mvNode.SetAttribute('MultiVolume.FrameLabels', frameLabelsAttr)
        mvNode.SetAttribute('MultiVolume.NumberOfFrames', str(nFrames))
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName',
                            dicomTagNameAttr)
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits',
                            dicomTagUnitsAttr)

        if dicomTagNameAttr == 'TriggerTime' or dicomTagNameAttr == 'AcquisitionTime':
            if teTag != '':
                mvNode.SetAttribute('MultiVolume.DICOM.EchoTime', teTag)
            if trTag != '':
                mvNode.SetAttribute('MultiVolume.DICOM.RepetitionTime', trTag)
            if faTag != '':
                mvNode.SetAttribute('MultiVolume.DICOM.FlipAngle', faTag)

        mvNode.SetName(str(nFrames) + ' frames MultiVolume')
        Helper.SetBgFgVolumes(mvNode.GetID(), None)
    def read4DNIfTI(self, mvNode, fileName):
        """Try to read a 4D nifti file as a multivolume"""
        print('trying to read %s' % fileName)

        # use the vtk reader which seems to handle most nifti variants well
        reader = vtk.vtkNIFTIImageReader()
        reader.SetFileName(fileName)
        reader.SetTimeAsVector(True)
        reader.Update()
        header = reader.GetNIFTIHeader()
        qFormMatrix = reader.GetQFormMatrix()
        if not qFormMatrix:
            print('Warning: %s does not have a QFormMatrix - using Identity')
            qFormMatrix = vtk.vtkMatrix4x4()
        spacing = reader.GetOutputDataObject(0).GetSpacing()
        timeSpacing = reader.GetTimeSpacing()
        nFrames = reader.GetTimeDimension()
        if header.GetIntentCode() != header.IntentTimeSeries:
            intentName = header.GetIntentName()
            if not intentName:
                intentName = 'Nothing'
            print(
                f'Warning: {fileName} does not have TimeSeries intent, instead it has \"{intentName}\"'
            )
            print('Trying to read as TimeSeries anyway')
        units = header.GetXYZTUnits()

        # try to account for some of the unit options
        # (Note: no test data available but we hope these are right)
        if units & header.UnitsMSec == header.UnitsMSec:
            timeSpacing /= 1000.
        if units & header.UnitsUSec == header.UnitsUSec:
            timeSpacing /= 1000. / 1000.
        spaceScaling = 1.
        if units & header.UnitsMeter == header.UnitsMeter:
            spaceScaling *= 1000.
        if units & header.UnitsMicron == header.UnitsMicron:
            spaceScaling /= 1000.
        spacing = [e * spaceScaling for e in spacing]

        # create frame labels using the timing info from the file
        # but use the advanced info so user can specify offset and scale
        volumeLabels = vtk.vtkDoubleArray()
        volumeLabels.SetNumberOfTuples(nFrames)
        frameLabelsAttr = ''
        for i in range(nFrames):
            frameId = self.__veInitial.value + timeSpacing * self.__veStep.value * i
            volumeLabels.SetComponent(i, 0, frameId)
            frameLabelsAttr += str(frameId) + ','
        frameLabelsAttr = frameLabelsAttr[:-1]

        # create the display node
        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        # spacing and origin are in the ijkToRAS, so clear them from image data
        imageChangeInformation = vtk.vtkImageChangeInformation()
        imageChangeInformation.SetInputConnection(reader.GetOutputPort())
        imageChangeInformation.SetOutputSpacing(1, 1, 1)
        imageChangeInformation.SetOutputOrigin(0, 0, 0)
        imageChangeInformation.Update()

        # QForm includes directions and origin, but not spacing so add that
        # here by multiplying by a diagonal matrix with the spacing
        scaleMatrix = vtk.vtkMatrix4x4()
        for diag in range(3):
            scaleMatrix.SetElement(diag, diag, spacing[diag])
        ijkToRAS = vtk.vtkMatrix4x4()
        ijkToRAS.DeepCopy(qFormMatrix)
        vtk.vtkMatrix4x4.Multiply4x4(ijkToRAS, scaleMatrix, ijkToRAS)
        mvNode.SetIJKToRASMatrix(ijkToRAS)
        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(
            imageChangeInformation.GetOutputDataObject(0))
        mvNode.SetNumberOfFrames(nFrames)

        # set the labels and other attributes, then display the volume
        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName(self.__veLabel.text)

        mvNode.SetAttribute('MultiVolume.FrameLabels', frameLabelsAttr)
        mvNode.SetAttribute('MultiVolume.NumberOfFrames', str(nFrames))
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName', '')
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits', '')

        mvNode.SetName(str(nFrames) + ' frames NIfTI MultiVolume')
        Helper.SetBgFgVolumes(mvNode.GetID(), None)
 def __init__(self):  
   # Member variables
   self.outputLabels = None    
   self.recordedDataBuffer = []   
   self.record = False
   self.reset = False
   self.outputObserverTag = -1
   self.rigidBodyToTrackerTransformNode = None
   self.measurementToMeasurerTransformNode = None
   self.parametersToMeasurerTransformNode = None
   self.plus = None
   self.m = vtk.vtkMatrix4x4()
   self.direction = -1
   self.ras = [0, 0, 0, 1]
   self.d = 0.0
   self.snr = 0
   self.total = 0
   self.LABEL_UPDATE_RATE = 10  
   self.labelUpdateCount = 0
   self.snrThreshold = 40       
   self.distanceMaximumValue = 1000.0       
   self.distanceMinimumValue = 0.0 
   self.lensMaxDistance = 0.0
   self.lensMinDistance = 0.0
   self.normalizingConstant = 0.0
   self.min = -1000.0
   self.addColours = True
   import Viewpoint # Viewpoint
   self.viewpointLogic = Viewpoint.ViewpointLogic()
   self.stopWatch = None # StopWatch        
   # Create style sheets        
   self.errorStyleSheet = "QLabel { color : #FF0000; \
                               font: bold 14px}"
   self.defaultStyleSheet = "QLabel { color : #000000; \
                                 font: bold 14px}"        
   # Create rainbow colour table                                      
   self.colorTable=slicer.vtkMRMLColorTableNode()
   self.colorTable.SetTypeToRainbow ()                                    
   # Add MeasurementPoint
   self.measurementPointMarkupsFiducialNode = slicer.util.getNode('MeasurementPoint')
   if not self.measurementPointMarkupsFiducialNode:
     self.measurementPointMarkupsFiducialNode = slicer.vtkMRMLMarkupsFiducialNode()  
     self.measurementPointMarkupsFiducialNode.SetName('MeasurementPoint')
     self.measurementPointMarkupsFiducialNode.AddFiducial(0, 0, 0)
     self.measurementPointMarkupsFiducialNode.SetNthFiducialLabel(0, '')
     slicer.mrmlScene.AddNode(self.measurementPointMarkupsFiducialNode)
     self.measurementPointMarkupsFiducialNode.GetDisplayNode().SetGlyphScale(2.0)
     self.measurementPointMarkupsFiducialNode.GetDisplayNode().SetGlyphType(13) # Sphere3D
     self.measurementPointMarkupsFiducialNode.GetDisplayNode().SetSelectedColor(1, 0, 0)     
   # Add RecordedModel
   self.recordedModelNode = slicer.util.getNode('RecordedModel')
   if not self.recordedModelNode:
     recordedPoints = vtk.vtkPoints()
     recordedVertices = vtk.vtkCellArray()               
     recordedPolyData = vtk.vtkPolyData()
     recordedPolyData.SetPoints(recordedPoints)
     recordedPolyData.SetVerts(recordedVertices)
     self.recordedModelNode = self.addModelToScene(recordedPolyData, "RecordedModel")    
     self.recordedModelNode.GetModelDisplayNode().SetPointSize(3)
     # Set up coloured scalars  
     colorArray = vtk.vtkDoubleArray()
     colorArray.SetNumberOfComponents(4)
     colorArray.SetName('Colors')
     self.recordedModelNode.GetPolyData().GetPointData().SetScalars(colorArray)          
   # Create share directory
   self.pathToCreatedSaveDir = self.createShareDirectory()    
   # Post-Processing default (for undo)
   self.recordedDataBufferDefault = []
    def onImportButtonClicked(self):
        # check if the output container exists
        mvNode = self.__mvSelector.currentNode()
        if mvNode == None:
            self.__status.text = "Status: Select output node!"
            return

        print("Before processing: " + mvNode.GetID())

        # Series of frames alpha-ordered, all in the input directory
        # Assume here that the last mode in the list is for parsing a list of
        # non-DICOM frames

        fileNames = []  # file names on disk
        frameList = []  # frames as MRMLScalarVolumeNode's
        frameFolder = ""
        volumeLabels = vtk.vtkDoubleArray()
        frameLabelsAttr = ""
        frameFileListAttr = ""
        dicomTagNameAttr = self.__dicomTag.text
        dicomTagUnitsAttr = self.__veLabel.text
        teAttr = self.__te.text
        trAttr = self.__tr.text
        faAttr = self.__fa.text

        # each frame is saved as a separate volume
        for f in os.listdir(self.__fDialog.directory):
            if not f.startswith("."):
                fileNames.append(f)
                frameFileListAttr += f + ","
        fileNames.sort()

        frameFileListAttr = frameFileListAttr[:-1]

        frameFolder = self.__fDialog.directory
        nFrames = len(fileNames)
        volumeLabels.SetNumberOfTuples(nFrames)
        volumeLabels.SetNumberOfComponents(1)
        volumeLabels.Allocate(nFrames)
        for i in range(len(fileNames)):
            frameId = self.__veInitial.value + self.__veStep.value * i
            volumeLabels.SetComponent(i, 0, frameId)
            frameLabelsAttr += str(frameId) + ","
        frameLabelsAttr = frameLabelsAttr[:-1]

        # read the first frame to get the extent
        fullName = frameFolder + "/" + fileNames[0]
        volumesLogic = slicer.modules.volumes.logic()
        frame = self.readFrame(fullName)
        frameImage = frame.GetImageData()
        frameExtent = frameImage.GetExtent()
        frameSize = frameExtent[1] * frameExtent[3] * frameExtent[5]

        nFrames = len(fileNames)
        mvImage = vtk.vtkImageData()
        mvImage.SetExtent(frameExtent)
        mvImage.SetNumberOfScalarComponents(nFrames)

        mvImage.AllocateScalars()
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(mvImage.GetPointData().GetScalars())

        mat = vtk.vtkMatrix4x4()
        frame.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

        for frameId in range(0, nFrames):
            fullName = frameFolder + "/" + fileNames[frameId]
            print("Processing frame %d: %s" % (frameId, fullName))

            frame = self.readFrame(fullName)
            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())
            mvImageArray.T[frameId] = frameImageArray

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLMultiVolumeDisplayNode")
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(nFrames)

        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName(self.__veLabel.text)

        mvNode.SetAttribute("MultiVolume.FrameFileList", frameFileListAttr)
        mvNode.SetAttribute("MultiVolume.FrameLabels", frameLabelsAttr)
        mvNode.SetAttribute("MultiVolume.NumberOfFrames", str(nFrames))
        mvNode.SetAttribute("MultiVolume.FrameIdentifyingDICOMTagName", dicomTagNameAttr)
        mvNode.SetAttribute("MultiVolume.FrameIdentifyingDICOMTagUnits", dicomTagUnitsAttr)

        if dicomTagNameAttr == "TriggerTime" or dicomTagNameAttr == "AcquisitionTime":
            if teTag != "":
                mvNode.SetAttribute("MultiVolume.DICOM.EchoTime", teTag)
            if trTag != "":
                mvNode.SetAttribute("MultiVolume.DICOM.RepetitionTime", trTag)
            if faTag != "":
                mvNode.SetAttribute("MultiVolume.DICOM.FlipAngle", faTag)

        print("MultiVolume node setup complete !")

        Helper.SetBgFgVolumes(mvNode.GetID(), None)

        print("After processing: " + mvNode.GetID())
    def onImportButtonClicked(self):
        # check if the output container exists
        mvNode = self.__mvSelector.currentNode()
        if mvNode == None:
            self.__status.text = 'Status: Select output node!'
            return

        # Series of frames alpha-ordered, all in the input directory
        # Assume here that the last mode in the list is for parsing a list of
        # non-DICOM frames

        fileNames = []  # file names on disk
        frameList = []  # frames as MRMLScalarVolumeNode's
        frameFolder = ""
        volumeLabels = vtk.vtkDoubleArray()
        frameLabelsAttr = ''
        frameFileListAttr = ''
        dicomTagNameAttr = self.__dicomTag.text
        dicomTagUnitsAttr = self.__veLabel.text
        teAttr = self.__te.text
        trAttr = self.__tr.text
        faAttr = self.__fa.text

        # each frame is saved as a separate volume
        # first filter valid file names and sort alphabetically
        frames = []
        frame0 = None
        inputDir = self.__fDialog.directory
        for f in os.listdir(inputDir):
            if not f.startswith('.'):
                fileName = inputDir + '/' + f
                fileNames.append(fileName)
        self.humanSort(fileNames)

        # check for nifti file that may be 4D as special case
        niftiFiles = []
        for fileName in fileNames:
            if fileName.lower().endswith(
                    '.nii.gz') or fileName.lower().endswith('.nii'):
                niftiFiles.append(fileName)
        if len(niftiFiles) == 1:
            self.read4DNIfTI(mvNode, niftiFiles[0])
            return

        # not 4D nifti, so keep trying
        for fileName in fileNames:
            (s, f) = self.readFrame(fileName)
            if s:
                if not frame0:
                    frame0 = f
                    frame0Image = frame0.GetImageData()
                    frame0Extent = frame0Image.GetExtent()
                else:
                    frameImage = f.GetImageData()
                    frameExtent = frameImage.GetExtent()
                    if frameExtent[1] != frame0Extent[1] or frameExtent[
                            3] != frame0Extent[3] or frameExtent[
                                5] != frame0Extent[5]:
                        continue
                frames.append(f)

        nFrames = len(frames)
        print('Successfully read ' + str(nFrames) + ' frames')

        if nFrames == 1:
            print('Single frame dataset - not reading as multivolume!')
            return

        # convert seconds data to milliseconds, which is expected by pkModeling.cxx line 81
        if dicomTagUnitsAttr == 's':
            frameIdMultiplier = 1000.0
            dicomTagUnitsAttr = 'ms'
        else:
            frameIdMultiplier = 1.0

        volumeLabels.SetNumberOfComponents(1)
        volumeLabels.SetNumberOfTuples(nFrames)
        for i in range(nFrames):
            frameId = frameIdMultiplier * (self.__veInitial.value +
                                           self.__veStep.value * i)
            volumeLabels.SetComponent(i, 0, frameId)
            frameLabelsAttr += str(frameId) + ','
        frameLabelsAttr = frameLabelsAttr[:-1]

        # allocate multivolume
        mvImage = vtk.vtkImageData()
        mvImage.SetExtent(frame0Extent)
        mvImage.AllocateScalars(frame0.GetImageData().GetScalarType(), nFrames)

        extent = frame0.GetImageData().GetExtent()
        numPixels = float(extent[1] + 1) * (extent[3] + 1) * (extent[5] +
                                                              1) * nFrames
        scalarType = frame0.GetImageData().GetScalarType()
        print('Will now try to allocate memory for ' + str(numPixels) +
              ' pixels of VTK scalar type ' + str(scalarType))
        print('Memory allocated successfully')
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(
            mvImage.GetPointData().GetScalars())

        mat = vtk.vtkMatrix4x4()
        frame0.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame0.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

        for frameId in range(nFrames):
            # TODO: check consistent size and orientation!
            frame = frames[frameId]
            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(
                frameImage.GetPointData().GetScalars())
            mvImageArray.T[frameId] = frameImageArray

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(nFrames)

        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName(self.__veLabel.text)

        mvNode.SetAttribute('MultiVolume.FrameLabels', frameLabelsAttr)
        mvNode.SetAttribute('MultiVolume.NumberOfFrames', str(nFrames))
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName',
                            dicomTagNameAttr)
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits',
                            dicomTagUnitsAttr)

        if dicomTagNameAttr == 'TriggerTime' or dicomTagNameAttr == 'AcquisitionTime':
            if teAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.EchoTime', teAttr)
            if trAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.RepetitionTime', trAttr)
            if faAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.FlipAngle', faAttr)

        mvNode.SetName(str(nFrames) + ' frames MultiVolume')
        Helper.SetBgFgVolumes(mvNode.GetID(), None)
  def onImportButtonClicked(self):
    # check if the output container exists
    vcNode = self.__vcSelector.currentNode()
    if vcNode == None:
      self.__status.text = 'Status: Select output node!'
      return

    modeIdx = self.__modeSelector.currentIndex
    processingMode = self.__processingModes[modeIdx]

    # There are two options:
    # 1. DICOM series in a directory, with either predefined or custom parse tag
    # 2. Series of frames alpha-ordered, all in the input directory
    # Assume here that the last mode in the list is for parsing a list of
    # non-DICOM frames

    fileNames = []    # file names on disk
    frameList = []    # frames as MRMLScalarVolumeNode's
    frameFolder = ""
    volumeLabels = vtk.vtkDoubleArray()

    if modeIdx < len(self.__processingModes)-1:
      # DICOM series

      # get logic
      logic = slicer.modules.multivolumeexplorer.logic()

      # create a clean temporary directory
      tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory')
      if not os.path.exists(tmpDir):
        os.mkdir(tmpDir)
      tmpDir = tmpDir+'/MultiVolumeImporter'
      if not os.path.exists(tmpDir):
        os.mkdir(tmpDir)
      else:
        # clean it up
        print 'tmpDir = '+tmpDir
        fileNames = os.listdir(tmpDir)
        for f in fileNames:
          print f,' will be unlinked'
          os.unlink(tmpDir+'/'+f)

      nFrames = logic.ProcessDICOMSeries(self.__fDialog.directory, tmpDir, self.__dicomTag.text, volumeLabels)

      self.__status.text = 'Series processed OK, '+str(nFrames)+' volumes identified'

      Helper.Info('Location of files:'+tmpDir)
      fileNames = os.listdir(tmpDir)
      fileNames.sort()

      frameFolder = tmpDir

    else:
      # each frame is saved as a separate volume
      fileNames = os.listdir(self.__fDialog.directory)
      fileNames.sort()
      frameFolder = self.__fDialog.directory
      nFrames = len(fileNames)
      volumeLabels.SetNumberOfTuples(nFrames)
      volumeLabels.SetNumberOfComponents(1)
      volumeLabels.Allocate(nFrames)
      for i in range(len(fileNames)):
        frameId = self.__veInitial.value+self.__veStep.value*i
        volumeLabels.SetComponent(i, 0, frameId)

    # read the first frame to get the extent for DWI node
    fullName = frameFolder+'/'+fileNames[0]
    volumesLogic = slicer.modules.volumes.logic()
    frame = volumesLogic.AddArchetypeVolume(fullName, processingMode[3]+' Frame 0', 0)
    frameImage = frame.GetImageData()
    frameExtent = frameImage.GetExtent()
    frameSize = frameExtent[1]*frameExtent[3]*frameExtent[5]

    nFrames = len(fileNames)
    dwiImage = vtk.vtkImageData()
    dwiImage.SetExtent(frameExtent)
    dwiImage.SetNumberOfScalarComponents(nFrames)

    dwiImage.AllocateScalars()
    dwiImageArray = vtk.util.numpy_support.vtk_to_numpy(dwiImage.GetPointData().GetScalars())

    # create and initialize a blank DWI node
    bValues = vtk.vtkDoubleArray()
    bValues.Allocate(nFrames)
    bValues.SetNumberOfComponents(1)
    bValues.SetNumberOfTuples(nFrames)
    gradients = vtk.vtkDoubleArray()
    gradients.Allocate(nFrames*3)
    gradients.SetNumberOfComponents(3)
    gradients.SetNumberOfTuples(nFrames)

    bValuesArray = vtk.util.numpy_support.vtk_to_numpy(bValues)
    gradientsArray = vtk.util.numpy_support.vtk_to_numpy(gradients)
    bValuesArray[:] = 0
    gradientsArray[:] = 1

    dwiNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLDiffusionWeightedVolumeNode')
    dwiNode.SetName(processingMode[3]+'DisplayVolume')
    dwiNode.SetScene(slicer.mrmlScene)
    dwiNode.SetBValues(bValues)
    dwiNode.SetDiffusionGradients(gradients)

    mat = vtk.vtkMatrix4x4()
    frame.GetRASToIJKMatrix(mat)
    dwiNode.SetRASToIJKMatrix(mat)
    frame.GetIJKToRASMatrix(mat)
    dwiNode.SetIJKToRASMatrix(mat)

    self.annihilateScalarNode(frame)

    for frameId in range(0,nFrames):
      fullName = frameFolder+'/'+fileNames[frameId]
      Helper.Info('Processing frame '+str(frameId)+': '+fullName)
      frame = volumesLogic.AddArchetypeVolume(fullName, 'Frame'+str(frameId), 0)
      frameImage = frame.GetImageData()
      frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())
      dwiImageArray.T[frameId] = frameImageArray
      self.annihilateScalarNode(frame)

    dwiDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLDiffusionWeightedVolumeDisplayNode')
    dwiDisplayNode.SetScene(slicer.mrmlScene)
    slicer.mrmlScene.AddNode(dwiDisplayNode)
    dwiDisplayNode.SetDefaultColorMap()

    dwiNode.SetAndObserveDisplayNodeID(dwiDisplayNode.GetID())
    dwiNode.SetAndObserveImageData(dwiImage)
    slicer.mrmlScene.AddNode(dwiNode)
    Helper.Info('DWI node added to the scene')


    vcNode.SetDWVNodeID(dwiNode.GetID())
    vcNode.SetLabelArray(volumeLabels)
    vcNode.SetLabelName(self.__veLabel.text)
    Helper.Info('VC node setup complete!')

    Helper.SetBgFgVolumes(dwiNode.GetID(),None)
Exemple #21
0
  def setup(self):
    # Instantiate and connect widgets ...

    if self.developerMode:
      #
      # Reload and Test area
      #
      reloadCollapsibleButton = ctk.ctkCollapsibleButton()
      reloadCollapsibleButton.text = "Reload && Test"
      self.layout.addWidget(reloadCollapsibleButton)
      reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

      # reload button
      # (use this during development, but remove it when delivering
      #  your module to users)
      self.reloadButton = qt.QPushButton("Reload")
      self.reloadButton.toolTip = "Reload this module."
      self.reloadButton.name = "VolumeProbe Reload"
      reloadFormLayout.addWidget(self.reloadButton)
      self.reloadButton.connect('clicked()', self.onReload)

      # reload and test button
      # (use this during development, but remove it when delivering
      #  your module to users)
      self.reloadAndTestButton = qt.QPushButton("Reload and Test All")
      self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
      reloadFormLayout.addWidget(self.reloadAndTestButton)
      self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

      # reload and run specific tests
      scenarios = ("Three Volume", "View Watcher", "ROIManager",)
      for scenario in scenarios:
        button = qt.QPushButton("Reload and Test %s" % scenario)
        self.reloadAndTestButton.toolTip = "Reload this module and then run the %s self test." % scenario
        reloadFormLayout.addWidget(button)
        button.connect('clicked()', lambda s=scenario: self.onReloadAndTest(scenario=s))

    #
    # Parameters Area
    #
    parametersCollapsibleButton = ctk.ctkCollapsibleButton()
    parametersCollapsibleButton.text = "Parameters"
    self.layout.addWidget(parametersCollapsibleButton)

    # Layout within the dummy collapsible button
    parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

    """
    #
    # target volume selector
    #
    self.inputSelector = slicer.qMRMLNodeComboBox()
    self.inputSelector.nodeTypes = ( ("vtkMRMLVolumeNode"), "" )
    self.inputSelector.selectNodeUponCreation = True
    self.inputSelector.addEnabled = False
    self.inputSelector.removeEnabled = False
    self.inputSelector.noneEnabled = False
    self.inputSelector.showHidden = False
    self.inputSelector.showChildNodeTypes = True
    self.inputSelector.setMRMLScene( slicer.mrmlScene )
    self.inputSelector.setToolTip( "Pick the input to the algorithm." )
    parametersFormLayout.addRow("Target Volume: ", self.inputSelector)
    """

    #
    # Add ROI
    #
    self.drawROICheck = qt.QCheckBox()
    parametersFormLayout.addRow("Draw ROI", self.drawROICheck)
    self.drawROICheck.connect("toggled(bool)", self.onDrawROIToggled)

    self.ROIRadiusSlider = ctk.ctkSliderWidget()
    #self.ROIRadiusSlider.setMinimum(1)
    #self.ROIRadiusSlider.setMaximum(100)
    self.ROIRadiusSlider.setValue(self.ROIRadius)
    parametersFormLayout.addRow("ROI Radius", self.ROIRadiusSlider)
    self.ROIRadiusSlider.connect("valueChanged(double)", self.onROIRadiusChanged)

    #
    # Add Histogram
    self.numBins = qt.QSpinBox()
    self.numBins.setRange(0, 200)
    self.numBins.setEnabled(1)
    self.numBins.setValue(20)
    parametersFormLayout.addRow("Number of Bins", self.numBins)

    self.histogramArray = vtk.vtkDoubleArray()
    self.histogramArray.SetNumberOfComponents(1)
    self.histogramArray.SetNumberOfTuples(0)

    self.histogram = ctk.ctkVTKHistogram()
    self.histogram.setDataArray(self.histogramArray)
    self.histogram.numberOfBins = self.numBins.value

    self.histogramView = ctk.ctkTransferFunctionView()
    self.histogramItem = ctk.ctkTransferFunctionBarsItem(self.histogram)
    self.histogramItem.barWidth = 0.7

    self.histogramView.scene().addItem(self.histogramItem)
    parametersFormLayout.addRow("Histogram", self.histogramView)
    self.histogramView.show()


    self.minField = qt.QSpinBox()
    self.minField.setRange(-100000, 100000)
    self.minField.setEnabled(0)
    parametersFormLayout.addRow("Min Value", self.minField)

    self.maxField = qt.QSpinBox()
    self.maxField.setRange(-100000, 100000)
    self.maxField.setEnabled(0)
    parametersFormLayout.addRow("Max Value", self.maxField)

    self.meanField = qt.QSpinBox()
    self.meanField.setRange(-100000, 100000)
    self.meanField.setEnabled(0)
    parametersFormLayout.addRow("Mean Value", self.meanField)
    
    self.medianField = qt.QSpinBox()
    self.medianField.setRange(-100000, 100000)
    self.medianField.setEnabled(0)
    parametersFormLayout.addRow("Median Value", self.medianField)
  
    self.stdField = qt.QSpinBox()
    self.stdField.setRange(-100000, 100000)
    self.stdField.setEnabled(0)
    parametersFormLayout.addRow("STD Value", self.stdField)
    
    # Add vertical spacer
    self.layout.addStretch(1)
Exemple #22
0
    def convertTextureToPointAttribute(self, modelNode, textureImageNode,
                                       colorAsVector):
        polyData = modelNode.GetPolyData()
        textureImageFlipVert = vtk.vtkImageFlip()
        textureImageFlipVert.SetFilteredAxis(1)
        textureImageFlipVert.SetInputConnection(
            textureImageNode.GetImageDataConnection())
        textureImageFlipVert.Update()
        textureImageData = textureImageFlipVert.GetOutput()
        pointData = polyData.GetPointData()
        tcoords = pointData.GetTCoords()
        numOfPoints = pointData.GetNumberOfTuples()
        assert numOfPoints == tcoords.GetNumberOfTuples(
        ), "Number of texture coordinates does not equal number of points"
        textureSamplingPointsUv = vtk.vtkPoints()
        textureSamplingPointsUv.SetNumberOfPoints(numOfPoints)
        for pointIndex in range(numOfPoints):
            uv = tcoords.GetTuple2(pointIndex)
            textureSamplingPointsUv.SetPoint(pointIndex, uv[0], uv[1], 0)

        textureSamplingPointDataUv = vtk.vtkPolyData()
        uvToXyz = vtk.vtkTransform()
        textureImageDataSpacingSpacing = textureImageData.GetSpacing()
        textureImageDataSpacingOrigin = textureImageData.GetOrigin()
        textureImageDataSpacingDimensions = textureImageData.GetDimensions()
        uvToXyz.Scale(
            textureImageDataSpacingDimensions[0] /
            textureImageDataSpacingSpacing[0],
            textureImageDataSpacingDimensions[1] /
            textureImageDataSpacingSpacing[1], 1)
        uvToXyz.Translate(textureImageDataSpacingOrigin)
        textureSamplingPointDataUv.SetPoints(textureSamplingPointsUv)
        transformPolyDataToXyz = vtk.vtkTransformPolyDataFilter()
        transformPolyDataToXyz.SetInputData(textureSamplingPointDataUv)
        transformPolyDataToXyz.SetTransform(uvToXyz)
        probeFilter = vtk.vtkProbeFilter()
        probeFilter.SetInputConnection(transformPolyDataToXyz.GetOutputPort())
        probeFilter.SetSourceData(textureImageData)
        probeFilter.Update()
        rgbPoints = probeFilter.GetOutput().GetPointData().GetArray(
            'ImageScalars')

        if colorAsVector:
            colorArray = vtk.vtkDoubleArray()
            colorArray.SetName('Color')
            colorArray.SetNumberOfComponents(3)
            colorArray.SetNumberOfTuples(numOfPoints)
            for pointIndex in range(numOfPoints):
                rgb = rgbPoints.GetTuple3(pointIndex)
                colorArray.SetTuple3(pointIndex, rgb[0] / 255., rgb[1] / 255.,
                                     rgb[2] / 255.)
            colorArray.Modified()
            pointData.AddArray(colorArray)
        else:
            colorArrayRed = vtk.vtkDoubleArray()
            colorArrayRed.SetName('ColorRed')
            colorArrayRed.SetNumberOfTuples(numOfPoints)
            colorArrayGreen = vtk.vtkDoubleArray()
            colorArrayGreen.SetName('ColorGreen')
            colorArrayGreen.SetNumberOfTuples(numOfPoints)
            colorArrayBlue = vtk.vtkDoubleArray()
            colorArrayBlue.SetName('ColorBlue')
            colorArrayBlue.SetNumberOfTuples(numOfPoints)
            for pointIndex in range(numOfPoints):
                rgb = rgbPoints.GetTuple3(pointIndex)
                colorArrayRed.SetValue(pointIndex, rgb[0])
                colorArrayGreen.SetValue(pointIndex, rgb[1])
                colorArrayBlue.SetValue(pointIndex, rgb[2])
            colorArrayRed.Modified()
            colorArrayGreen.Modified()
            colorArrayBlue.Modified()
            pointData.AddArray(colorArrayRed)
            pointData.AddArray(colorArrayGreen)
            pointData.AddArray(colorArrayBlue)

        pointData.Modified()
        polyData.Modified()
Exemple #23
0
    def calcApproachScore(self,
                          point,
                          skinPolyData,
                          obstacleBspTree,
                          skinModelNode=None):

        pTarget = point
        polyData = skinPolyData
        nPoints = polyData.GetNumberOfPoints()
        nCells = polyData.GetNumberOfCells()
        pSurface = [0.0, 0.0, 0.0]
        minDistancePoint = [0.0, 0.0, 0.0]

        tolerance = 0.001
        t = vtk.mutable(0.0)
        x = [0.0, 0.0, 0.0]
        pcoords = [0.0, 0.0, 0.0]
        subId = vtk.mutable(0)

        #print ("nPoints = %d" % (nPoints))
        #print ("nCells = %d" % (nCells))

        # Map surface model
        if skinModelNode != None:
            pointValue = vtk.vtkDoubleArray()
            pointValue.SetName("Colors")
            pointValue.SetNumberOfComponents(1)
            pointValue.SetNumberOfTuples(nPoints)
            pointValue.Reset()
            pointValue.FillComponent(0, 0.0)

        bspTree = obstacleBspTree

        cp0 = [0.0, 0.0, 0.0]
        cp1 = [0.0, 0.0, 0.0]
        cp2 = [0.0, 0.0, 0.0]

        accessibleArea = 0.0
        inaccessibleArea = 0.0

        ids = vtk.vtkIdList()

        minDistance = -1

        for index in range(nCells):
            cell = polyData.GetCell(index)
            if cell.GetCellType() == vtk.VTK_TRIANGLE:
                area = cell.ComputeArea()
                polyData.GetCellPoints(index, ids)
                polyData.GetPoint(ids.GetId(0), cp0)
                polyData.GetPoint(ids.GetId(1), cp1)
                polyData.GetPoint(ids.GetId(2), cp2)
                vtk.vtkTriangle.TriangleCenter(cp0, cp1, cp2, pSurface)
                iD = bspTree.IntersectWithLine(pSurface, pTarget, tolerance, t,
                                               x, pcoords, subId)
                if iD < 1:
                    if skinModelNode != None:
                        d = vtk.vtkMath.Distance2BetweenPoints(
                            pSurface, pTarget)
                        d = math.sqrt(d)
                        if d < minDistance or minDistance < 0:
                            minDistance = d
                            minDistancePoint = [
                                pSurface[0], pSurface[1], pSurface[2]
                            ]
                        v = d + 101
                        pointValue.InsertValue(ids.GetId(0), v)
                        pointValue.InsertValue(ids.GetId(1), v)
                        pointValue.InsertValue(ids.GetId(2), v)
                    accessibleArea = accessibleArea + area
                else:
                    if skinModelNode != None:
                        v = -1.0
                        pointValue.InsertValue(ids.GetId(0), v)
                        pointValue.InsertValue(ids.GetId(1), v)
                        pointValue.InsertValue(ids.GetId(2), v)
                    inaccessibleArea = inaccessibleArea + area

            else:
                print("ERROR: Non-triangular cell.")

        score = accessibleArea / (accessibleArea + inaccessibleArea)

        if skinModelNode != None:
            skinModelNode.AddPointScalars(pointValue)
            skinModelNode.SetActivePointScalars(
                "Colors", vtk.vtkDataSetAttributes.SCALARS)
            skinModelNode.Modified()
            displayNode = skinModelNode.GetModelDisplayNode()
            displayNode.SetActiveScalarName("Colors")
            displayNode.SetScalarRange(0.0, 200.0)

        return (score, minDistance, minDistancePoint)
  def calcApproachScore(self, point, skinPolyData, obstacleBspTree, skinModelNode=None):

    pTarget = point
    polyData = skinPolyData
    nPoints = polyData.GetNumberOfPoints()
    nCells = polyData.GetNumberOfCells()
    pSurface=[0.0, 0.0, 0.0]
    minDistancePoint = [0.0, 0.0, 0.0]

    tolerance = 0.001
    t = vtk.mutable(0.0)
    x = [0.0, 0.0, 0.0]
    pcoords = [0.0, 0.0, 0.0]
    subId = vtk.mutable(0)

    #print ("nPoints = %d" % (nPoints))
    #print ("nCells = %d" % (nCells))

    # Map surface model
    if skinModelNode != None:
      pointValue = vtk.vtkDoubleArray()
      pointValue.SetName("Colors")
      pointValue.SetNumberOfComponents(1)
      pointValue.SetNumberOfTuples(nPoints)
      pointValue.Reset()
      pointValue.FillComponent(0,0.0);
    
    bspTree = obstacleBspTree

    cp0=[0.0, 0.0, 0.0]
    cp1=[0.0, 0.0, 0.0]
    cp2=[0.0, 0.0, 0.0]

    accessibleArea = 0.0
    inaccessibleArea = 0.0

    ids=vtk.vtkIdList()

    minDistance = -1;

    for index in range(nCells):
      cell = polyData.GetCell(index)
      if cell.GetCellType() == vtk.VTK_TRIANGLE:
        area = cell.ComputeArea()
        polyData.GetCellPoints(index, ids)
        polyData.GetPoint(ids.GetId(0), cp0)
        polyData.GetPoint(ids.GetId(1), cp1)
        polyData.GetPoint(ids.GetId(2), cp2)
        vtk.vtkTriangle.TriangleCenter(cp0, cp1, cp2, pSurface)
        iD = bspTree.IntersectWithLine(pSurface, pTarget, tolerance, t, x, pcoords, subId)
        if iD < 1:
          if skinModelNode != None:
            d = vtk.vtkMath.Distance2BetweenPoints(pSurface, pTarget)
            d = math.sqrt(d)
            if d < minDistance or minDistance < 0:
              minDistance = d
              minDistancePoint = [pSurface[0],pSurface[1],pSurface[2]]
            v = d+101
            pointValue.InsertValue(ids.GetId(0), v)
            pointValue.InsertValue(ids.GetId(1), v)
            pointValue.InsertValue(ids.GetId(2), v)
          accessibleArea = accessibleArea + area
        else:
          if skinModelNode != None:
            v = -1.0
            pointValue.InsertValue(ids.GetId(0), v)
            pointValue.InsertValue(ids.GetId(1), v)
            pointValue.InsertValue(ids.GetId(2), v)
          inaccessibleArea = inaccessibleArea + area

      else:
        print ("ERROR: Non-triangular cell.")

    
    score = accessibleArea / (accessibleArea + inaccessibleArea)

    if skinModelNode != None:
      skinModelNode.AddPointScalars(pointValue)
      skinModelNode.SetActivePointScalars("Colors", vtk.vtkDataSetAttributes.SCALARS)
      skinModelNode.Modified()
      displayNode = skinModelNode.GetModelDisplayNode()
      displayNode.SetActiveScalarName("Colors")
      displayNode.SetScalarRange(0.0,200.0)


    return (score, minDistance, minDistancePoint)
Exemple #25
0
  def loadDevelopmentalAtlas(self):

    # get the header - this reader doesn't support 4D
    # but can query the header.
    reader = vtk.vtkNIFTIImageReader()
    reader.SetFileName(self.developmentalPath)
    reader.Update()
    niftiHeader = reader.GetNIFTIHeader()

    print(self.developmentalPath)
    if niftiHeader.GetDataType() != 16:
      print (niftiHeader.GetDataType())
      raise Exception('Can only load float data')

    # create the correct size and shape vtkImageData
    columns = niftiHeader.GetDim(1)
    rows = niftiHeader.GetDim(2)
    slices = niftiHeader.GetDim(3)
    frames = niftiHeader.GetDim(4)

    fp = open(self.developmentalPath, 'rb')
    headerThrowaway = fp.read(niftiHeader.GetVoxOffset())
    niiArray = numpy.fromfile(fp, numpy.dtype('float32'))

    niiShape = (frames, slices, rows, columns)
    niiArray = niiArray.reshape(niiShape)

    image = vtk.vtkImageData()
    image.SetDimensions(columns, rows, slices)
    image.AllocateScalars(vtk.VTK_FLOAT, frames)
    from vtk.util.numpy_support import vtk_to_numpy
    imageShape = (slices, rows, columns, frames)
    imageArray = vtk_to_numpy(image.GetPointData().GetScalars()).reshape(imageShape)

    # copy the data from numpy to vtk (need to shuffle frames to components)
    for frame in range(frames):
      imageArray[:,:,:,frame] = niiArray[frame]

    # create the multivolume node and display it
    multiVolumeNode = slicer.vtkMRMLMultiVolumeNode()

    volumeLabels = vtk.vtkDoubleArray()
    volumeLabels.SetNumberOfTuples(frames)
    volumeLabels.SetNumberOfComponents(1)
    volumeLabels.Allocate(frames)
    for frame in xrange(frames):
      volumeLabels.SetComponent(frame,0,self.agesInYears[frame])

    multiVolumeNode.SetScene(slicer.mrmlScene)

    multiVolumeDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    multiVolumeDisplayNode.SetReferenceCount(multiVolumeDisplayNode.GetReferenceCount()-1)
    multiVolumeDisplayNode.SetScene(slicer.mrmlScene)
    multiVolumeDisplayNode.SetDefaultColorMap()
    slicer.mrmlScene.AddNode(multiVolumeDisplayNode)

    multiVolumeNode.SetAndObserveDisplayNodeID(multiVolumeDisplayNode.GetID())
    multiVolumeNode.SetAndObserveImageData(image)
    multiVolumeNode.SetNumberOfFrames(frames)
    multiVolumeNode.SetName("DevelopmentalAtlas")
    multiVolumeNode.SetLabelArray(volumeLabels)
    multiVolumeNode.SetLabelName("Years")
    multiVolumeNode.SetAttribute("MultiVolume.FrameLabels", str(self.agesInYears)[1:-1])
    multiVolumeNode.SetAttribute("MultiVolume.NumberOfFrames", str(frames))
    multiVolumeNode.SetAttribute("MultiVolume.FrameIdentifyingDICOMTagName", "Age")
    multiVolumeNode.SetAttribute("MultiVolume.FrameIdentifyingDICOMTagUnits", "(Years)")
    slicer.mrmlScene.AddNode(multiVolumeNode)

    return multiVolumeNode
    def registrarButton(self):
        mvNode = self.outputRegSelector.currentNode()
        inputVolume = self.inputRegSelector.currentNode()
        """
    Run the actual algorithm
    """
        #se obtiene la escena y se obtiene el volumen 4D a partir del Volumen 4D de
        #entrada de la ventana desplegable
        escena = slicer.mrmlScene
        imagenvtk4D = inputVolume.GetImageData()
        #Se obtiene el número de volúmenes que tiene el volumen 4D
        numero_imagenes = inputVolume.GetNumberOfFrames()
        print('imagenes: ' + str(numero_imagenes))
        #filtro vtk para descomponer un volumen 4D
        extract1 = vtk.vtkImageExtractComponents()
        extract1.SetInputData(imagenvtk4D)
        #matriz de transformación
        ras2ijk = vtk.vtkMatrix4x4()
        ijk2ras = vtk.vtkMatrix4x4()
        #le solicitamos al volumen original que nos devuelva sus matrices
        inputVolume.GetRASToIJKMatrix(ras2ijk)
        inputVolume.GetIJKToRASMatrix(ijk2ras)
        #creo un volumen nuevo
        volumenFijo = slicer.vtkMRMLScalarVolumeNode()
        volumenSalida = slicer.vtkMRMLMultiVolumeNode()

        #le asigno las transformaciones
        volumenFijo.SetRASToIJKMatrix(ras2ijk)
        volumenFijo.SetIJKToRASMatrix(ijk2ras)
        #le asigno el volumen 3D fijo
        imagen_fija = extract1.SetComponents(0)
        extract1.Update()
        volumenFijo.SetName('fijo')
        volumenFijo.SetAndObserveImageData(extract1.GetOutput())
        #anado el nuevo volumen a la escena
        escena.AddNode(volumenFijo)
        #se crea un vector para guardar el número del volumen que tenga un
        #desplazamiento de mas de 4mm en cualquier dirección
        v = []

        #se hace un ciclo for para registrar todos los demás volúmenes del volumen 4D
        #con el primer volumen que se definió como fijo
        frameLabelsAttr = ''
        frames = []
        volumeLabels = vtk.vtkDoubleArray()

        volumeLabels.SetNumberOfTuples(numero_imagenes)
        volumeLabels.SetNumberOfComponents(1)
        volumeLabels.Allocate(numero_imagenes)

        for i in range(numero_imagenes):
            # extraigo la imagen móvil en la posición i+1 ya que el primero es el fijo
            imagen_movil = extract1.SetComponents(
                i + 1)  #Seleccionar un volumen i+1
            extract1.Update()
            #Creo el volumen móvil, y realizo el mismo procedimiento que con el fijo
            volumenMovil = slicer.vtkMRMLScalarVolumeNode()
            volumenMovil.SetRASToIJKMatrix(ras2ijk)
            volumenMovil.SetIJKToRASMatrix(ijk2ras)
            volumenMovil.SetAndObserveImageData(extract1.GetOutput())
            volumenMovil.SetName('movil ' + str(i + 1))
            escena.AddNode(volumenMovil)

            #creamos la transformada para alinear los volúmenes
            transformadaSalida = slicer.vtkMRMLLinearTransformNode()
            transformadaSalida.SetName('Transformadaderegistro' + str(i + 1))
            slicer.mrmlScene.AddNode(transformadaSalida)
            #parámetros para la operación de registro
            parameters = {}
            #parameters['InitialTransform'] = transI.GetID()
            parameters['fixedVolume'] = volumenFijo.GetID()
            parameters['movingVolume'] = volumenMovil.GetID()
            parameters['transformType'] = 'Rigid'
            parameters['outputTransform'] = transformadaSalida.GetID()
            frames.append(volumenMovil)
            ##      parameters['outputVolume']=volumenSalida.GetID()
            #Realizo el registro
            cliNode = slicer.cli.run(slicer.modules.brainsfit,
                                     None,
                                     parameters,
                                     wait_for_completion=True)
            #obtengo la transformada lineal que se usó en el registro
            transformada = escena.GetFirstNodeByName('Transformadaderegistro' +
                                                     str(i + 1))
            #Obtengo la matriz de la transformada, esta matriz es de dimensiones 4x4
            #en la cual estan todos los desplazamientos y rotaciones que se hicieron
            #en la transformada, a partir de ella se obtienen los volumenes que se
            #desplazaron mas de 4mm en cualquier direccion

            hm = vtk.vtkMatrix4x4()
            transformadaSalida.GetMatrixTransformToWorld(hm)
            volumenMovil.ApplyTransformMatrix(hm)
            volumenMovil.SetAndObserveTransformNodeID(None)

            frameId = i
            volumeLabels.SetComponent(i, 0, frameId)
            frameLabelsAttr += str(frameId) + ','

##      Matriz=transformada.GetMatrixTransformToParent()
##      LR=Matriz.GetElement(0,3)#dirección izquierda o derecha en la fila 1, columna 4
##      PA=Matriz.GetElement(1,3)#dirección anterior o posterior en la fila 2, columna 4
##      IS=Matriz.GetElement(2,3)#dirección inferior o superior en la fila 3, columna 4
##      #Se mira si el volumen "i" en alguna dirección tuvo un desplazamiento
##      #mayor a 4mm, en caso de ser cierto se guarda en el vector "v"
##      if abs(LR)>4:
##        v.append(i+2)
##      elif abs(PA)>4:
##        v.append(i+2)
##      elif abs(IS)>4:
##        v.append(i+2)
##    print("MovilExtent: "+str(volumenMovil.GetImageData().GetExtent()))
####    print("valor de f: "+ str(volumenMovil))
##    frameLabelsAttr = frameLabelsAttr[:-1]

        mvImage = vtk.vtkImageData()
        mvImage.SetExtent(volumenMovil.GetImageData().GetExtent()
                          )  ##Se le asigna la dimensión del miltuvolumen
        mvImage.AllocateScalars(
            volumenMovil.GetImageData().GetScalarType(), numero_imagenes
        )  ##Se le asigna el tipo y número de cortes al multivolumen
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(
            mvImage.GetPointData().GetScalars()
        )  ## Se crea la matriz de datos donde va a ir la imagen

        mat = vtk.vtkMatrix4x4()

        ##Se hace la conversión y se obtiene la matriz de transformación del nodo
        volumenMovil.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        volumenMovil.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

        print("frameId: " + str(frameId))
        print("# imag: " + str(numero_imagenes))
        ##    print("Long frame1: "+str(len(frame)))
        print("Long frames: " + str(len(frames)))

        ##
        for frameId in range(numero_imagenes):
            # TODO: check consistent size and orientation!
            frame = frames[frameId]
            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(
                frameImage.GetPointData().GetScalars())
            mvImageArray.T[frameId] = frameImageArray


##Se crea el nodo del multivolumen

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(numero_imagenes)

        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName('na')
        mvNode.SetAttribute('MultiVolume.FrameLabels', frameLabelsAttr)
        mvNode.SetAttribute('MultiVolume.NumberOfFrames', str(numero_imagenes))
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName', 'NA')
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits', 'na')

        mvNode.SetName('MultiVolume Registrado')
        Helper.SetBgFgVolumes(mvNode.GetID(), None)

        print('Registro completo')
        #al terminar el ciclo for con todos los volúmenes registrados se genera una
        #ventana emergente con un mensaje("Registro completo!") y mostrando los
        #volúmenes que se desplazaron mas de 4mm
        qt.QMessageBox.information(slicer.util.mainWindow(), 'Slicer Python',
                                   'Registro completo')
        return True
Exemple #27
0
    def clipSurfaceAtEndPoints( self, networkPolyData, surfacePolyData ):
        '''
        Clips the surfacePolyData on the endpoints identified using the networkPolyData.

        Returns a tupel of the form [clippedPolyData, endpointsPoints]
        '''
        # import the vmtk libraries
        try:
            import vtkvmtkComputationalGeometryPython as vtkvmtkComputationalGeometry
            import vtkvmtkMiscPython as vtkvmtkMisc
        except ImportError:
            logging.error("Unable to import the SlicerVmtk libraries")

        cleaner = vtk.vtkCleanPolyData()
        cleaner.SetInputData( networkPolyData )
        cleaner.Update()
        network = cleaner.GetOutput()
        network.BuildCells()
        network.BuildLinks( 0 )
        endpointIds = vtk.vtkIdList()

        radiusArray = network.GetPointData().GetArray( 'Radius' )

        endpoints = vtk.vtkPolyData()
        endpointsPoints = vtk.vtkPoints()
        endpointsRadius = vtk.vtkDoubleArray()
        endpointsRadius.SetName( 'Radius' )
        endpoints.SetPoints( endpointsPoints )
        endpoints.GetPointData().AddArray( endpointsRadius )

        radiusFactor = 1.2
        minRadius = 0.01

        for i in range( network.GetNumberOfCells() ):
            numberOfCellPoints = network.GetCell( i ).GetNumberOfPoints()
            pointId0 = network.GetCell( i ).GetPointId( 0 )
            pointId1 = network.GetCell( i ).GetPointId( numberOfCellPoints - 1 )

            pointCells = vtk.vtkIdList()
            network.GetPointCells( pointId0, pointCells )
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId( pointId0 )
                if pointId == numberOfEndpoints:
                    point = network.GetPoint( pointId0 )
                    radius = radiusArray.GetValue( pointId0 )
                    radius = max( radius, minRadius )
                    endpointsPoints.InsertNextPoint( point )
                    endpointsRadius.InsertNextValue( radiusFactor * radius )

            pointCells = vtk.vtkIdList()
            network.GetPointCells( pointId1, pointCells )
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId( pointId1 )
                if pointId == numberOfEndpoints:
                    point = network.GetPoint( pointId1 )
                    radius = radiusArray.GetValue( pointId1 )
                    radius = max( radius, minRadius )
                    endpointsPoints.InsertNextPoint( point )
                    endpointsRadius.InsertNextValue( radiusFactor * radius )

        polyBall = vtkvmtkComputationalGeometry.vtkvmtkPolyBall()
        #polyBall.SetInputData( endpoints )
        polyBall.SetInput( endpoints )
        polyBall.SetPolyBallRadiusArrayName( 'Radius' )

        clipper = vtk.vtkClipPolyData()
        clipper.SetInputData( surfacePolyData )
        clipper.SetClipFunction( polyBall )
        clipper.Update()

        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInputData( clipper.GetOutput() )
        connectivityFilter.ColorRegionsOff()
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()

        clippedSurface = connectivityFilter.GetOutput()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy( clippedSurface )

        return [outPolyData, endpointsPoints]
Exemple #28
0
  def initMultiVolumes(self, files, prescribedTags=None):
    tag2ValueFileList = {}
    multivolumes = []

    if prescribedTags == None:
      consideredTags = self.multiVolumeTags.keys()
    else:
      consideredTags = prescribedTags

    # iterate over all files
    for file in files:

      # iterate over the tags that can be used to separate individual frames
      for frameTag in consideredTags:
        try:
          tagValue2FileList = tag2ValueFileList[frameTag]
        except:
          tagValue2FileList = {}
          tag2ValueFileList[frameTag] = tagValue2FileList

        tagValueStr = slicer.dicomDatabase.fileValue(file,self.tags[frameTag])
        if tagValueStr == '':
          # not found?
          continue
        
        if frameTag == 'AcquisitionTime' or frameTag == 'SeriesTime':
          # extra parsing is needed to convert from DICOM TM VR into ms
          tagValue = self.tm2ms(tagValueStr) # convert to ms
        else:
          tagValue = float(tagValueStr)
        
        try:
          tagValue2FileList[tagValue].append(file)
        except:
          tagValue2FileList[tagValue] = [file]

    # iterate over the parsed items and decide which ones can qualify as mv
    for frameTag in self.multiVolumeTags.keys():

      try:
        tagValue2FileList = tag2ValueFileList[frameTag]
      except:
        # didn't find the tag
        continue

      if len(tagValue2FileList)<2:
        # not enough frames for this tag to be a multivolume
        continue
  
      tagValues = tagValue2FileList.keys()
      # sort the frames
      tagValues.sort()
      firstFrameSize = len(tagValue2FileList[tagValues[0]])
      frameInvalid = False
      for tagValue in tagValues:
        if len(tagValue2FileList[tagValue]) != firstFrameSize:
          # number of frames does not match

          frameInvalid = True
      if frameInvalid == True:
        continue

      # TODO: add a check to confirm individual frames have the same geometry
      # (check pixel dimensions, orientation, position)

      # now this looks like a serious mv!

      # initialize the needed attributes for a new mvNode
      frameFileListStr = ""
      frameLabelsStr = ""
      frameLabelsArray = vtk.vtkDoubleArray()
      tagValue0 = tagValues[0]
      for tagValue in tagValues:
        frameFileList = tagValue2FileList[tagValue]
        for file in frameFileList:
          frameFileListStr = frameFileListStr+file+','

        frameLabelsStr = frameLabelsStr+str(tagValue)+','
        # if mv was parsed by series time, probably makes sense to start from
        # 0
        if frameTag == 'SeriesTime':
          frameLabelsArray.InsertNextValue(tagValue-tagValue0)
        else:
          frameLabelsArray.InsertNextValue(tagValue)

      #print 'File list: ',frameFileList
      #print 'Labels: ',frameLabelsStr

      frameFileListStr = frameFileListStr[:-1]
      frameLabelsStr = frameLabelsStr[:-1]

      mvNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeNode')
      mvNode.SetReferenceCount(mvNode.GetReferenceCount()-1)
      mvNode.SetScene(slicer.mrmlScene)
      mvNode.SetAttribute("MultiVolume.FrameFileList",frameFileListStr)
      mvNode.SetAttribute("MultiVolume.FrameLabels",frameLabelsStr)
      mvNode.SetAttribute("MultiVolume.FrameIdentifyingDICOMTagName",frameTag)
      mvNode.SetAttribute('MultiVolume.NumberOfFrames',str(len(tagValue2FileList)))
      mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits',self.multiVolumeTagsUnits[frameTag])

      mvNode.SetNumberOfFrames(len(tagValue2FileList))
      mvNode.SetLabelName(self.multiVolumeTagsUnits[frameTag])
      mvNode.SetLabelArray(frameLabelsArray)

      if frameTag == 'TriggerTime' or frameTag == 'AcquisitionTime':
        # this is DCE, so let's keep the tag values that will be needed for
        # the analysis
        firstFile = frameFileList[0]
        echoTime = slicer.dicomDatabase.fileValue(firstFile, self.tags['EchoTime'])
        repetitionTime = slicer.dicomDatabase.fileValue(firstFile, self.tags['RepetitionTime'])
        flipAngle = slicer.dicomDatabase.fileValue(firstFile, self.tags['FlipAngle'])
        
        mvNode.SetAttribute('MultiVolume.DICOM.EchoTime',echoTime)
        mvNode.SetAttribute('MultiVolume.DICOM.RepetitionTime',repetitionTime)
        mvNode.SetAttribute('MultiVolume.DICOM.FlipAngle',flipAngle)

      # add the node
      multivolumes.append(mvNode)

    return multivolumes
Exemple #29
0
    def loadDevelopmentalAtlas(self):

        # get the header - this reader doesn't support 4D
        # but can query the header.
        reader = vtk.vtkNIFTIImageReader()
        reader.SetFileName(self.developmentalPath)
        reader.Update()
        niftiHeader = reader.GetNIFTIHeader()

        print(self.developmentalPath)
        if niftiHeader.GetDataType() != 16:
            print(niftiHeader.GetDataType())
            raise Exception('Can only load float data')

        # create the correct size and shape vtkImageData
        columns = niftiHeader.GetDim(1)
        rows = niftiHeader.GetDim(2)
        slices = niftiHeader.GetDim(3)
        frames = niftiHeader.GetDim(4)

        fp = open(self.developmentalPath, 'rb')
        headerThrowaway = fp.read(niftiHeader.GetVoxOffset())
        niiArray = numpy.fromfile(fp, numpy.dtype('float32'))

        niiShape = (frames, slices, rows, columns)
        niiArray = niiArray.reshape(niiShape)

        image = vtk.vtkImageData()
        image.SetDimensions(columns, rows, slices)
        image.AllocateScalars(vtk.VTK_FLOAT, frames)
        from vtk.util.numpy_support import vtk_to_numpy
        imageShape = (slices, rows, columns, frames)
        imageArray = vtk_to_numpy(
            image.GetPointData().GetScalars()).reshape(imageShape)

        # copy the data from numpy to vtk (need to shuffle frames to components)
        for frame in range(frames):
            imageArray[:, :, :, frame] = niiArray[frame]

        # create the multivolume node and display it
        multiVolumeNode = slicer.vtkMRMLMultiVolumeNode()

        volumeLabels = vtk.vtkDoubleArray()
        volumeLabels.SetNumberOfTuples(frames)
        volumeLabels.SetNumberOfComponents(1)
        volumeLabels.Allocate(frames)
        for frame in xrange(frames):
            volumeLabels.SetComponent(frame, 0, self.agesInYears[frame])

        multiVolumeNode.SetScene(slicer.mrmlScene)

        multiVolumeDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        multiVolumeDisplayNode.SetReferenceCount(
            multiVolumeDisplayNode.GetReferenceCount() - 1)
        multiVolumeDisplayNode.SetScene(slicer.mrmlScene)
        multiVolumeDisplayNode.SetDefaultColorMap()
        slicer.mrmlScene.AddNode(multiVolumeDisplayNode)

        multiVolumeNode.SetAndObserveDisplayNodeID(
            multiVolumeDisplayNode.GetID())
        multiVolumeNode.SetAndObserveImageData(image)
        multiVolumeNode.SetNumberOfFrames(frames)
        multiVolumeNode.SetName("DevelopmentalAtlas")
        multiVolumeNode.SetLabelArray(volumeLabels)
        multiVolumeNode.SetLabelName("Years")
        multiVolumeNode.SetAttribute("MultiVolume.FrameLabels",
                                     str(self.agesInYears)[1:-1])
        multiVolumeNode.SetAttribute("MultiVolume.NumberOfFrames", str(frames))
        multiVolumeNode.SetAttribute(
            "MultiVolume.FrameIdentifyingDICOMTagName", "Age")
        multiVolumeNode.SetAttribute(
            "MultiVolume.FrameIdentifyingDICOMTagUnits", "(Years)")
        slicer.mrmlScene.AddNode(multiVolumeNode)

        return multiVolumeNode
Exemple #30
0
    def updateCurve(self):

        if self.AutomaticUpdate == False:
            return

        if self.SourceNode and self.DestinationNode:

            if self.SourceNode.GetNumberOfFiducials() < 2:
                if self.CurvePoly != None:
                    self.CurvePoly.Initialize()

                self.CurveLength = 0.0

            else:

                if self.CurvePoly == None:
                    self.CurvePoly = vtk.vtkPolyData()

                if self.DestinationNode.GetDisplayNodeID() == None:
                    modelDisplayNode = slicer.vtkMRMLModelDisplayNode()
                    modelDisplayNode.SetColor(self.ModelColor)
                    slicer.mrmlScene.AddNode(modelDisplayNode)
                    self.DestinationNode.SetAndObserveDisplayNodeID(
                        modelDisplayNode.GetID())

                if self.InterpolationMethod == 0:

                    if self.RingMode > 0:
                        self.nodeToPoly(self.SourceNode, self.CurvePoly, True)
                    else:
                        self.nodeToPoly(self.SourceNode, self.CurvePoly, False)

                elif self.InterpolationMethod == 1:  # Cardinal Spline

                    if self.RingMode > 0:
                        self.nodeToPolyCardinalSpline(self.SourceNode,
                                                      self.CurvePoly, True)
                    else:
                        self.nodeToPolyCardinalSpline(self.SourceNode,
                                                      self.CurvePoly, False)

                elif self.InterpolationMethod == 2:  # Hermite Spline

                    if self.RingMode > 0:
                        self.nodeToPolyHermiteSpline(self.SourceNode,
                                                     self.CurvePoly, True)
                    else:
                        self.nodeToPolyHermiteSpline(self.SourceNode,
                                                     self.CurvePoly, False)

                self.CurveLength = self.calculateLineLength(self.CurvePoly)

            tubeFilter = vtk.vtkTubeFilter()
            curvatureValues = vtk.vtkDoubleArray()

            if self.Curvature:
                ## If the curvature option is ON, calculate the curvature along the curve.
                (meanKappa, minKappa,
                 maxKappa) = self.computeCurvatures(self.CurvePoly,
                                                    curvatureValues)
                self.CurvePoly.GetPointData().AddArray(curvatureValues)
                self.curvatureMeanKappa = meanKappa
                self.curvatureMinKappa = minKappa
                self.curvatureMaxKappa = maxKappa
            else:
                self.curvatureMeanKappa = None
                self.curvatureMinKappa = None
                self.curvatureMaxKappa = None

            tubeFilter.SetInputData(self.CurvePoly)
            tubeFilter.SetRadius(self.TubeRadius)
            tubeFilter.SetNumberOfSides(20)
            tubeFilter.CappingOn()
            tubeFilter.Update()

            # self.DestinationNode.SetAndObservePolyData(tubeFilter.GetOutput())
            self.DestinationNode.SetAndObservePolyData(self.CurvePoly)
            self.DestinationNode.Modified()

            if self.DestinationNode.GetScene() == None:
                slicer.mrmlScene.AddNode(self.DestinationNode)

            displayNode = self.DestinationNode.GetDisplayNode()
            if displayNode:
                if self.Curvature:
                    displayNode.SetActiveScalarName('Curvature')
                else:
                    displayNode.SetActiveScalarName('')
Exemple #31
0
  def updateCurve(self):

    if self.AutomaticUpdate == False:
      return

    if self.SourceNode and self.DestinationNode:

      if self.SourceNode.GetNumberOfFiducials() < 2:
        if self.CurvePoly != None:
          self.CurvePoly.Initialize()

        self.CurveLength = 0.0

      else:

        if self.CurvePoly == None:
          self.CurvePoly = vtk.vtkPolyData()
        
        if self.DestinationNode.GetDisplayNodeID() == None:
          modelDisplayNode = slicer.vtkMRMLModelDisplayNode()
          modelDisplayNode.SetColor(self.ModelColor)
          slicer.mrmlScene.AddNode(modelDisplayNode)
          self.DestinationNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID())
        
        if self.InterpolationMethod == 0:
        
          if self.RingMode > 0:
            self.nodeToPoly(self.SourceNode, self.CurvePoly, True)
          else:
            self.nodeToPoly(self.SourceNode, self.CurvePoly, False)
        
        elif self.InterpolationMethod == 1: # Cardinal Spline
        
          if self.RingMode > 0:
            self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, True)
          else:
            self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, False)
        
        elif self.InterpolationMethod == 2: # Hermite Spline
        
          if self.RingMode > 0:        
            self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, True)
          else:
            self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, False)
          
        self.CurveLength = self.calculateLineLength(self.CurvePoly)

      tubeFilter = vtk.vtkTubeFilter()
      curvatureValues = vtk.vtkDoubleArray()

      if self.Curvature:
        ## If the curvature option is ON, calculate the curvature along the curve.
        (meanKappa, minKappa, maxKappa) = self.computeCurvatures(self.CurvePoly, curvatureValues)
        self.CurvePoly.GetPointData().AddArray(curvatureValues)
        self.curvatureMeanKappa = meanKappa
        self.curvatureMinKappa = minKappa
        self.curvatureMaxKappa = maxKappa
      else:
        self.curvatureMeanKappa = None
        self.curvatureMinKappa = None
        self.curvatureMaxKappa = None
       
      tubeFilter.SetInputData(self.CurvePoly)
      tubeFilter.SetRadius(self.TubeRadius)
      tubeFilter.SetNumberOfSides(20)
      tubeFilter.CappingOn()
      tubeFilter.Update()

      self.DestinationNode.SetAndObservePolyData(tubeFilter.GetOutput())
      self.DestinationNode.Modified()
      
      if self.DestinationNode.GetScene() == None:
        slicer.mrmlScene.AddNode(self.DestinationNode)

      displayNode = self.DestinationNode.GetDisplayNode()
      if displayNode:
        if self.Curvature:
          displayNode.SetActiveScalarName('Curvature')
        else:
          displayNode.SetActiveScalarName('')
  def onImportButtonClicked(self):
    # check if the output container exists
    mvNode = self.__mvSelector.currentNode()
    if mvNode == None:
      self.__status.text = 'Status: Select output node!'
      return

    # Series of frames alpha-ordered, all in the input directory
    # Assume here that the last mode in the list is for parsing a list of
    # non-DICOM frames

    fileNames = []    # file names on disk
    frameList = []    # frames as MRMLScalarVolumeNode's
    frameFolder = ""
    volumeLabels = vtk.vtkDoubleArray()
    frameLabelsAttr = ''
    frameFileListAttr = ''
    dicomTagNameAttr = self.__dicomTag.text
    dicomTagUnitsAttr = self.__veLabel.text
    teAttr = self.__te.text
    trAttr = self.__tr.text
    faAttr = self.__fa.text

    # each frame is saved as a separate volume
    # first filter valid file names and sort alphabetically
    frames = []
    frame0 = None
    inputDir = self.__fDialog.directory
    for f in os.listdir(inputDir):
      if not f.startswith('.'):
        fileName = inputDir+'/'+f
        fileNames.append(fileName)
    self.humanSort(fileNames)

    # check for nifti file that may be 4D as special case
    niftiFiles = []
    for fileName in fileNames:
      if fileName.lower().endswith('.nii.gz') or fileName.lower().endswith('.nii'):
        niftiFiles.append(fileName)
    if len(niftiFiles) == 1:
     self.read4DNIfTI(mvNode, niftiFiles[0])
     return

    # not 4D nifti, so keep trying
    for fileName in fileNames:
      (s,f) = self.readFrame(fileName)
      if s:
        if not frame0:
          frame0 = f
          frame0Image = frame0.GetImageData()
          frame0Extent = frame0Image.GetExtent()
        else:
          frameImage = f.GetImageData()
          frameExtent = frameImage.GetExtent()
          if frameExtent[1]!=frame0Extent[1] or frameExtent[3]!=frame0Extent[3] or frameExtent[5]!=frame0Extent[5]:
            continue
        frames.append(f)

    nFrames = len(frames)
    print('Successfully read '+str(nFrames)+' frames')

    if nFrames == 1:
      print('Single frame dataset - not reading as multivolume!')
      return

    # convert seconds data to milliseconds, which is expected by pkModeling.cxx line 81
    if dicomTagUnitsAttr == 's':
      frameIdMultiplier = 1000.0
      dicomTagUnitsAttr = 'ms'
    else:
      frameIdMultiplier = 1.0

    volumeLabels.SetNumberOfComponents(1)
    volumeLabels.SetNumberOfTuples(nFrames)
    for i in range(nFrames):
      frameId = frameIdMultiplier*(self.__veInitial.value+self.__veStep.value*i)
      volumeLabels.SetComponent(i, 0, frameId)
      frameLabelsAttr += str(frameId)+','
    frameLabelsAttr = frameLabelsAttr[:-1]

    # allocate multivolume
    mvImage = vtk.vtkImageData()
    mvImage.SetExtent(frame0Extent)
    if vtk.VTK_MAJOR_VERSION <= 5:
      mvImage.SetNumberOfScalarComponents(nFrames)
      mvImage.SetScalarType(frame0.GetImageData().GetScalarType())
      mvImage.AllocateScalars()
    else:
      mvImage.AllocateScalars(frame0.GetImageData().GetScalarType(), nFrames)

    extent = frame0.GetImageData().GetExtent()
    numPixels = float(extent[1]+1)*(extent[3]+1)*(extent[5]+1)*nFrames
    scalarType = frame0.GetImageData().GetScalarType()
    print('Will now try to allocate memory for '+str(numPixels)+' pixels of VTK scalar type '+str(scalarType))
    print('Memory allocated successfully')
    mvImageArray = vtk.util.numpy_support.vtk_to_numpy(mvImage.GetPointData().GetScalars())

    mat = vtk.vtkMatrix4x4()
    frame0.GetRASToIJKMatrix(mat)
    mvNode.SetRASToIJKMatrix(mat)
    frame0.GetIJKToRASMatrix(mat)
    mvNode.SetIJKToRASMatrix(mat)

    for frameId in range(nFrames):
      # TODO: check consistent size and orientation!
      frame = frames[frameId]
      frameImage = frame.GetImageData()
      frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())
      mvImageArray.T[frameId] = frameImageArray

    mvDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    mvDisplayNode.SetScene(slicer.mrmlScene)
    slicer.mrmlScene.AddNode(mvDisplayNode)
    mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount()-1)
    mvDisplayNode.SetDefaultColorMap()

    mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
    mvNode.SetAndObserveImageData(mvImage)
    mvNode.SetNumberOfFrames(nFrames)

    mvNode.SetLabelArray(volumeLabels)
    mvNode.SetLabelName(self.__veLabel.text)

    mvNode.SetAttribute('MultiVolume.FrameLabels',frameLabelsAttr)
    mvNode.SetAttribute('MultiVolume.NumberOfFrames',str(nFrames))
    mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName',dicomTagNameAttr)
    mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits',dicomTagUnitsAttr)

    if dicomTagNameAttr == 'TriggerTime' or dicomTagNameAttr == 'AcquisitionTime':
      if teAttr != '':
        mvNode.SetAttribute('MultiVolume.DICOM.EchoTime',teAttr)
      if trAttr != '':
        mvNode.SetAttribute('MultiVolume.DICOM.RepetitionTime',trAttr)
      if faAttr != '':
        mvNode.SetAttribute('MultiVolume.DICOM.FlipAngle',faAttr)

    mvNode.SetName(str(nFrames)+' frames MultiVolume')
    Helper.SetBgFgVolumes(mvNode.GetID(),None)
    def clipSurfaceAtEndPoints(self, networkPolyData, surfacePolyData):
        '''
        Clips the surfacePolyData on the endpoints identified using the networkPolyData.
        
        Returns a tupel of the form [clippedPolyData, endpointsPoints]
        '''
        # import the vmtk libraries
        try:
            from libvtkvmtkComputationalGeometryPython import *
            from libvtkvmtkMiscPython import *
        except ImportError:
            print "FAILURE: Unable to import the SlicerVmtk4 libraries!"

        cleaner = vtk.vtkCleanPolyData()
        cleaner.SetInput(networkPolyData)
        cleaner.Update()
        network = cleaner.GetOutput()
        network.BuildCells()
        network.BuildLinks(0)
        endpointIds = vtk.vtkIdList()

        radiusArray = network.GetPointData().GetArray('Radius')

        endpoints = vtk.vtkPolyData()
        endpointsPoints = vtk.vtkPoints()
        endpointsRadius = vtk.vtkDoubleArray()
        endpointsRadius.SetName('Radius')
        endpoints.SetPoints(endpointsPoints)
        endpoints.GetPointData().AddArray(endpointsRadius)

        radiusFactor = 1.2
        minRadius = 0.01

        for i in range(network.GetNumberOfCells()):
            numberOfCellPoints = network.GetCell(i).GetNumberOfPoints()
            pointId0 = network.GetCell(i).GetPointId(0)
            pointId1 = network.GetCell(i).GetPointId(numberOfCellPoints - 1)

            pointCells = vtk.vtkIdList()
            network.GetPointCells(pointId0, pointCells)
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId(pointId0)
                if pointId == numberOfEndpoints:
                    point = network.GetPoint(pointId0)
                    radius = radiusArray.GetValue(pointId0)
                    radius = max(radius, minRadius)
                    endpointsPoints.InsertNextPoint(point)
                    endpointsRadius.InsertNextValue(radiusFactor * radius)

            pointCells = vtk.vtkIdList()
            network.GetPointCells(pointId1, pointCells)
            numberOfEndpoints = endpointIds.GetNumberOfIds()
            if pointCells.GetNumberOfIds() == 1:
                pointId = endpointIds.InsertUniqueId(pointId1)
                if pointId == numberOfEndpoints:
                    point = network.GetPoint(pointId1)
                    radius = radiusArray.GetValue(pointId1)
                    radius = max(radius, minRadius)
                    endpointsPoints.InsertNextPoint(point)
                    endpointsRadius.InsertNextValue(radiusFactor * radius)

        polyBall = vtkvmtkPolyBall()
        polyBall.SetInput(endpoints)
        polyBall.SetPolyBallRadiusArrayName('Radius')

        clipper = vtk.vtkClipPolyData()
        clipper.SetInput(surfacePolyData)
        clipper.SetClipFunction(polyBall)
        clipper.Update()

        connectivityFilter = vtk.vtkPolyDataConnectivityFilter()
        connectivityFilter.SetInput(clipper.GetOutput())
        connectivityFilter.ColorRegionsOff()
        connectivityFilter.SetExtractionModeToLargestRegion()
        connectivityFilter.Update()

        clippedSurface = connectivityFilter.GetOutput()

        outPolyData = vtk.vtkPolyData()
        outPolyData.DeepCopy(clippedSurface)
        outPolyData.Update()

        return [outPolyData, endpointsPoints]
  def read4DNIfTI(self, mvNode, fileName):
    """Try to read a 4D nifti file as a multivolume"""
    print('trying to read %s' % fileName)

    # use the vtk reader which seems to handle most nifti variants well
    reader = vtk.vtkNIFTIImageReader()
    reader.SetFileName(fileName)
    reader.SetTimeAsVector(True)
    reader.Update()
    header = reader.GetNIFTIHeader()
    qFormMatrix = reader.GetQFormMatrix()
    if not qFormMatrix:
      print('Warning: %s does not have a QFormMatrix - using Identity')
      qFormMatrix = vtk.vtkMatrix4x4()
    spacing = reader.GetOutputDataObject(0).GetSpacing()
    timeSpacing = reader.GetTimeSpacing()
    nFrames = reader.GetTimeDimension()
    if header.GetIntentCode() != header.IntentTimeSeries:
      intentName = header.GetIntentName()
      if not intentName:
        intentName = 'Nothing'
      print('Warning: %s does not have TimeSeries intent, instead it has \"%s\"' % (fileName,intentName))
      print('Trying to read as TimeSeries anyway')
    units = header.GetXYZTUnits()

    # try to account for some of the unit options
    # (Note: no test data available but we hope these are right)
    if units & header.UnitsMSec:
      timeSpacing /= 1000.
    if units & header.UnitsUSec:
      timeSpacing /= 1000. / 1000.
    spaceScaling = 1.
    if units & header.UnitsMeter:
      spaceScaling *= 1000.
    if units & header.UnitsMicron:
      spaceScaling /= 1000.
    spacing = map(lambda e: e * spaceScaling, spacing)

    # create frame labels using the timing info from the file
    # but use the advanced info so user can specify offset and scale
    volumeLabels = vtk.vtkDoubleArray()
    volumeLabels.SetNumberOfTuples(nFrames)
    frameLabelsAttr = ''
    for i in range(nFrames):
      frameId = self.__veInitial.value + timeSpacing * self.__veStep.value * i
      volumeLabels.SetComponent(i, 0, frameId)
      frameLabelsAttr += str(frameId)+','
    frameLabelsAttr = frameLabelsAttr[:-1]

    # create the display node
    mvDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    mvDisplayNode.SetScene(slicer.mrmlScene)
    slicer.mrmlScene.AddNode(mvDisplayNode)
    mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount()-1)
    mvDisplayNode.SetDefaultColorMap()

    # spacing and origin are in the ijkToRAS, so clear them from image data
    imageChangeInformation = vtk.vtkImageChangeInformation()
    imageChangeInformation.SetInputConnection(reader.GetOutputPort())
    imageChangeInformation.SetOutputSpacing( 1, 1, 1 )
    imageChangeInformation.SetOutputOrigin( 0, 0, 0 )
    imageChangeInformation.Update()

    # QForm includes directions and origin, but not spacing so add that
    # here by multiplying by a diagonal matrix with the spacing
    scaleMatrix = vtk.vtkMatrix4x4()
    for diag in range(3):
      scaleMatrix.SetElement(diag, diag, spacing[diag])
    ijkToRAS = vtk.vtkMatrix4x4()
    ijkToRAS.DeepCopy(qFormMatrix)
    vtk.vtkMatrix4x4.Multiply4x4(ijkToRAS, scaleMatrix, ijkToRAS)
    mvNode.SetIJKToRASMatrix(ijkToRAS)
    mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
    mvNode.SetAndObserveImageData(imageChangeInformation.GetOutputDataObject(0))
    mvNode.SetNumberOfFrames(nFrames)

    # set the labels and other attributes, then display the volume
    mvNode.SetLabelArray(volumeLabels)
    mvNode.SetLabelName(self.__veLabel.text)

    mvNode.SetAttribute('MultiVolume.FrameLabels',frameLabelsAttr)
    mvNode.SetAttribute('MultiVolume.NumberOfFrames',str(nFrames))
    mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName','')
    mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits','')

    mvNode.SetName(str(nFrames)+' frames NIfTI MultiVolume')
    Helper.SetBgFgVolumes(mvNode.GetID(),None)
Exemple #35
0
    def importFunction(self):

        self.__dicomTag = 'NA'
        self.__veLabel = 'na'
        self.__veInitial = 0
        self.__veStep = 1
        self.__te = 1
        self.__tr = 1
        self.__fa = 1
        nameFrame = self.__nameFrame.text

        inputVolume = self.inputSelector.currentNode()
        # check if the output container exists
        mvNode = self.outputSelector.currentNode()
        ##    if mvNode == None:
        ##      self.__status.text = 'Status: Select output node!'
        ##      return

        fileNames = []  # file names on disk
        frameList = []  # frames as MRMLScalarVolumeNode's
        frameFolder = ""
        volumeLabels = vtk.vtkDoubleArray()
        frameLabelsAttr = ''
        frameFileListAttr = ''
        dicomTagNameAttr = self.__dicomTag
        dicomTagUnitsAttr = self.__veLabel
        teAttr = self.__te
        trAttr = self.__tr
        faAttr = self.__fa

        # each frame is saved as a separate volume
        # first filter valid file names and sort alphabetically
        frames = []
        frame0 = None
        inputDir = self.__fDialog.directory

        metadatos = []
        print('hola' + str(len(os.listdir(inputDir))))
        for f in os.listdir(inputDir):

            if not f.startswith('.'):
                fileName = inputDir + '/' + f
                fileName1 = str(inputDir + '/' + f)
                metadato = dicom.read_file(fileName1)
                metadatos.append(metadato)
                fileNames.append(fileName)

            self.humanSort(fileNames)
            n = 0

        for fileName in fileNames:
            #f: información de cada scalar volume de cada corte
            (s, f) = self.readFrame(fileName)

            if s:
                if not frame0:
                    ##          print("valor de f: "+ str(f));
                    frame0 = f
                    ##          print("frame0: "+str(frame0));
                    frame0Image = frame0.GetImageData()
                    frame0Extent = frame0Image.GetExtent()
##          print("frame0Extent: " + str(frame0Extent));
                else:
                    ##          print("valor de f1: "+ str(f))
                    frameImage = f.GetImageData()
                    ##          print("frameImage: "+str(frameImage))
                    frameExtent = frameImage.GetExtent()
                    ##          print("frameExtent: " + str(frameExtent));
                    if frameExtent[1] != frame0Extent[1] or frameExtent[
                            3] != frame0Extent[3] or frameExtent[
                                5] != frame0Extent[5]:
                        continue
##          n=n+1
##          print("for: "+str(n))
                frames.append(f)

        nFrames = len(frames)
        ##    print("nFrames: "+str(nFrames))
        print('Successfully read ' + str(nFrames) + ' frames')

        if nFrames == 1:
            print('Single frame dataset - not reading as multivolume!')
            return

        # convert seconds data to milliseconds, which is expected by pkModeling.cxx line 81
        if dicomTagUnitsAttr == 's':
            frameIdMultiplier = 1000.0
            dicomTagUnitsAttr = 'ms'
        else:
            frameIdMultiplier = 1.0
##    print("volumeLabelsAntes: "+ str(volumeLabels))
        volumeLabels.SetNumberOfTuples(nFrames)
        ##    print("volumeLabelsIntermedio: "+ str(volumeLabels))
        volumeLabels.SetNumberOfComponents(1)
        ##    print("volumeLabelsDespues: "+ str(volumeLabels))
        volumeLabels.Allocate(nFrames)
        ##    print("volumeLabelsTotal: "+ str(volumeLabels))

        ### Después de los 3 pasos el único cambio es size, en vez de 0 pasa a ser nFrames
        for i in range(nFrames):
            frameId = frameIdMultiplier * (self.__veInitial +
                                           self.__veStep * i)
            ##      print("frameId: "+str(frameId))
            volumeLabels.SetComponent(i, 0, frameId)  ##no hay necesidad
            ####      print("volumeLabelsTotal: "+ str(volumeLabels))##Aparentemente no hay cambio en volumeLabels
            frameLabelsAttr += str(frameId) + ','
##      print("frameLabelsAttr: "+str(frameLabelsAttr))
        frameLabelsAttr = frameLabelsAttr[:-1]  ##No hay cambio
        ##    print("frameLabelsAttrTOTAL: "+str(frameLabelsAttr))

        # allocate multivolume
        mvImage = vtk.vtkImageData()
        ##    print("mvImage: "+str(mvImage))
        mvImage.SetExtent(frame0Extent)
        ##    print("mvImageExtent: "+str(mvImage))
        ##    print("vtk.VTK_MAJOR_VERSION: "+str(vtk.VTK_MAJOR_VERSION))
        if vtk.VTK_MAJOR_VERSION <= 5:  ##Versión 7
            mvImage.SetNumberOfScalarComponents(nFrames)
            print("mvImageSC: " + str(mvImage))
            mvImage.SetScalarType(frame0.GetImageData().GetScalarType())
            print("mvImageST: " + str(mvImage))
            mvImage.AllocateScalars()
            print("mvImageAllocate: " + str(mvImage))
        else:
            mvImage.AllocateScalars(frame0.GetImageData().GetScalarType(),
                                    nFrames)
##      print("mvImageElse: "+str(mvImage))

        extent = frame0.GetImageData().GetExtent()
        numPixels = float(extent[1] + 1) * (extent[3] + 1) * (extent[5] +
                                                              1) * nFrames
        scalarType = frame0.GetImageData().GetScalarType()
        print('Will now try to allocate memory for ' + str(numPixels) +
              ' pixels of VTK scalar type' + str(scalarType))
        print('Memory allocated successfully')
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(
            mvImage.GetPointData().GetScalars())
        ##    print("mvImageEArray: "+str(mvImageArray))
        ##    print("mvImage.GetPointData().GetScalars(): " + str(mvImage.GetPointData().GetScalars()));
        ##    print("ID mvImagearray " + str(id(mvImageArray)));
        ##    print("ID 2: " + str(mvImage.GetPointData().GetScalars()));
        ##    print("Que es frame0: " + str(frame0));

        ##EMPIEZA A FORMARCE EL VOLUMEN###############

        mat = vtk.vtkMatrix4x4()
        frame0.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame0.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)
        print("frameId: " + str(frameId))
        print("# imag: " + str(nFrames))
        ##    print("Long frame: "+str(len(frame)))
        for frameId in range(nFrames):
            # TODO: check consistent size and orientation!
            frame = frames[frameId]
            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(
                frameImage.GetPointData().GetScalars())
            mvImageArray.T[frameId] = frameImageArray

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(mvDisplayNode)
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetDefaultColorMap()

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(nFrames)

        mvNode.SetLabelArray(volumeLabels)
        mvNode.SetLabelName(self.__veLabel)

        mvNode.SetAttribute('MultiVolume.FrameLabels', frameLabelsAttr)
        mvNode.SetAttribute('MultiVolume.NumberOfFrames', str(nFrames))
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagName',
                            dicomTagNameAttr)
        mvNode.SetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits',
                            dicomTagUnitsAttr)

        if dicomTagNameAttr == 'TriggerTime' or dicomTagNameAttr == 'AcquisitionTime':
            if teAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.EchoTime', teAttr)
            if trAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.RepetitionTime', trAttr)
            if faAttr != '':
                mvNode.SetAttribute('MultiVolume.DICOM.FlipAngle', faAttr)

        mvNode.SetName(nameFrame)

        NameFrame = nameFrame
        self.Diccionario = {
            NameFrame: metadato
        }
        print(self.Diccionario.get(NameFrame))
        Helper.SetBgFgVolumes(mvNode.GetID(), None)
Exemple #36
0
    def calcApproachScore(self,
                          targetPointNode,
                          skinPolyData,
                          obstacleBspTree,
                          skinModelNode=None):

        #pTargetA = targetPointNode.GetMarkupPointVector(0, 0)
        tListNumber = targetPointNode.GetNumberOfFiducials()

        #pTargetA = pointA
        #pTargetB = pointB
        #pTargetC = pointC
        polyData = skinPolyData
        nPoints = polyData.GetNumberOfPoints()
        nCells = polyData.GetNumberOfCells()
        pSurface = [0.0, 0.0, 0.0]
        minDistancePoint = [0.0, 0.0, 0.0]

        tolerance = 0.001
        t = vtk.mutable(0.0)
        x = [0.0, 0.0, 0.0]
        pcoords = [0.0, 0.0, 0.0]
        subId = vtk.mutable(0)

        #print ("nPoints = %d" % (nPoints))
        #print ("nCells = %d" % (nCells))

        # Map surface model
        if skinModelNode != None:
            pointValue = vtk.vtkDoubleArray()
            pointValue.SetName("Colors")
            pointValue.SetNumberOfComponents(1)
            pointValue.SetNumberOfTuples(nPoints)
            pointValue.Reset()
            pointValue.FillComponent(0, 0.0)

        bspTree = obstacleBspTree

        cp0 = [0.0, 0.0, 0.0]
        cp1 = [0.0, 0.0, 0.0]
        cp2 = [0.0, 0.0, 0.0]

        accessibleArea = 0.0
        inaccessibleArea = 0.0

        ids = vtk.vtkIdList()

        minDistance = -1

        #iDA = 0
        #iDAFlag = 0
        #d = 0

        for index in range(nCells):

            iDA = 0
            iDAFlag = 0
            d = 0
            i = 0
            j = 0

            cell = polyData.GetCell(index)
            if cell.GetCellType() == vtk.VTK_TRIANGLE:
                area = cell.ComputeArea()
                polyData.GetCellPoints(index, ids)
                polyData.GetPoint(ids.GetId(0), cp0)
                polyData.GetPoint(ids.GetId(1), cp1)
                polyData.GetPoint(ids.GetId(2), cp2)
                vtk.vtkTriangle.TriangleCenter(cp0, cp1, cp2, pSurface)

                #####
                for i in range(0, tListNumber, 1):
                    pTargetA = targetPointNode.GetMarkupPointVector(i, 0)
                    iDA = bspTree.IntersectWithLine(pSurface, pTargetA,
                                                    tolerance, t, x, pcoords,
                                                    subId)
                    if iDA >= 1:
                        iDAFlag = 10

                #####
                if iDAFlag < 1:
                    if skinModelNode != None:
                        for j in range(0, tListNumber, 1):
                            pTargetA = targetPointNode.GetMarkupPointVector(
                                j, 0)
                            d += (vtk.vtkMath.Distance2BetweenPoints(
                                pSurface, pTargetA))
                        d = d / tListNumber
                        d = math.sqrt(d)

                        if 100 < d < 240:
                            if d < minDistance or minDistance < 0:
                                minDistance = d
                                minDistancePoint = [
                                    pSurface[0], pSurface[1], pSurface[2]
                                ]

                            v = d + 51
                            pointValue.InsertValue(ids.GetId(0), v)
                            pointValue.InsertValue(ids.GetId(1), v)
                            pointValue.InsertValue(ids.GetId(2), v)

                            accessibleArea = accessibleArea + area
                        else:
                            v = -1.0
                            pointValue.InsertValue(ids.GetId(0), v)
                            pointValue.InsertValue(ids.GetId(1), v)
                            pointValue.InsertValue(ids.GetId(2), v)
                            inaccessibleArea = inaccessibleArea + area
                else:
                    if skinModelNode != None:
                        v = -1.0
                        pointValue.InsertValue(ids.GetId(0), v)
                        pointValue.InsertValue(ids.GetId(1), v)
                        pointValue.InsertValue(ids.GetId(2), v)
                    inaccessibleArea = inaccessibleArea + area

            else:
                print("ERROR: Non-triangular cell.")

        score = accessibleArea

        if skinModelNode != None:
            skinModelNode.AddPointScalars(pointValue)
            skinModelNode.SetActivePointScalars(
                "Colors", vtk.vtkDataSetAttributes.SCALARS)
            skinModelNode.Modified()
            displayNode = skinModelNode.GetModelDisplayNode()
            displayNode.SetActiveScalarName("Colors")
            displayNode.SetScalarRange(0.0, 200.0)

        return (score, minDistance, minDistancePoint)