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
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