Esempio n. 1
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 loadPhilips4DUSAsMultiVolume(self, loadable):
        """Load the selection as an Ultrasound, store in MultiVolume
    """

        # get the key info from the "fake" dicom file
        filePath = loadable.files[0]
        ds = dicom.read_file(filePath, stop_before_pixels=True)
        columns = ds.Columns
        rows = ds.Rows
        slices = ds[(0x3001, 0x1001)].value  # private tag!
        spacing = (
            ds.PhysicalDeltaX * 10,
            ds.PhysicalDeltaY * 10,
            ds[(0x3001, 0x1003)].value * 10  # private tag!
        )
        frames = int(ds.NumberOfFrames)
        imageComponents = frames

        # create the correct size and shape vtkImageData
        image = vtk.vtkImageData()
        imageShape = (slices, rows, columns, frames)
        image.SetDimensions(columns, rows, slices)
        image.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, imageComponents)
        from vtk.util.numpy_support import vtk_to_numpy
        imageArray = vtk_to_numpy(
            image.GetPointData().GetScalars()).reshape(imageShape)

        # put the data in a numpy array
        # -- we need to read the file as raw bytes
        pixelShape = (frames, slices, rows, columns)
        pixels = numpy.fromfile(filePath, dtype=numpy.uint8)
        pixelSize = pixelShape[0] * pixelShape[1] * pixelShape[2] * pixelShape[
            3]
        headerSize = len(pixels) - pixelSize
        pixels = pixels[headerSize:]
        pixels = pixels.reshape(pixelShape)

        slicer.modules.imageArray = imageArray
        slicer.modules.pixels = pixels

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

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

        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(loadable.name)
        slicer.mrmlScene.AddNode(multiVolumeNode)

        #
        # automatically select the volume to display
        #
        appLogic = slicer.app.applicationLogic()
        selNode = appLogic.GetSelectionNode()
        selNode.SetReferenceActiveVolumeID(multiVolumeNode.GetID())
        appLogic.PropagateVolumeSelection()

        return multiVolumeNode
Esempio n. 3
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 loadAsMultiVolume(self,loadable):
    """Load the selection as an Ultrasound, store in MultiVolume
    """

    # get the key info from the "fake" dicom file
    filePath = loadable.files[0]
    ds = dicom.read_file(filePath, stop_before_pixels=True)
    columns = ds.Columns
    rows = ds.Rows
    slices = ds[(0x3001,0x1001)].value # private tag!
    spacing = (
            ds.PhysicalDeltaX * 10,
            ds.PhysicalDeltaY * 10,
            ds[(0x3001,0x1003)].value * 10 # private tag!
            )
    frames  = int(ds.NumberOfFrames)
    imageComponents = frames

    # create the correct size and shape vtkImageData
    image = vtk.vtkImageData()
    imageShape = (slices, rows, columns, frames)
    image.SetDimensions(columns, rows, slices)
    image.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, imageComponents)
    from vtk.util.numpy_support import vtk_to_numpy
    imageArray = vtk_to_numpy(image.GetPointData().GetScalars()).reshape(imageShape)

    # put the data in a numpy array
    # -- we need to read the file as raw bytes
    pixelShape = (frames, slices, rows, columns)
    pixels = numpy.fromfile(filePath, dtype=numpy.uint8)
    pixelSize = reduce(lambda x,y : x*y, pixelShape)
    headerSize = len(pixels)-pixelSize
    pixels = pixels[headerSize:]
    pixels = pixels.reshape(pixelShape)

    slicer.modules.imageArray = imageArray
    slicer.modules.pixels = pixels

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

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

    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(loadable.name)
    slicer.mrmlScene.AddNode(multiVolumeNode)

    #
    # automatically select the volume to display
    #
    appLogic = slicer.app.applicationLogic()
    selNode = appLogic.GetSelectionNode()
    selNode.SetReferenceActiveVolumeID(multiVolumeNode.GetID())
    appLogic.PropagateVolumeSelection()

    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