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)
def onApplyButton(self): mvNode = self.outputSelector.currentNode() inputVolume= self.inputSelector.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 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!\nVolumenes con movimiento mayor a 4mm:\n'+str(v)) return True
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 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 registrarButton(self): #La función registrarButton permitirá recuperar información del multivolumen, #la creación de nodos tipo "ScalarVolumeNode" y "MultiVolumeNode" donde estarán asociados #las matrices de transformación del multivolumen importado. El primer volumen será nombrado #como 'Fijo' y los demás serán volumen tipo 'Móvil'. Se añaden los mismos a la escena creada previamente. #Se creará un multivolumen que sera el reconstruido a partir del registro y se empezará a extraer componente a #componente del multivolumen importado, esto se repite desde el frame 0 hasta el numero de frame totales. #Se añaden a la escena atributos que brindan información sobre la transformada. #Se podrá entonces implementar el modulo cli de registro "brainsfit", que tomará los parámetros de entrada y #aplicará el correspondiente tipo de registro al multivolumen seleccionado. #Finalmente, se recuperarán los datos de desplazamiento por medio de la matriz de transformación y el volumen de salida se usará #para hacer la reconstrucción del multivolumen añadiendo un nodo de visualización. Se mostrarán los volumenes con desplazamiento mayor de 1 mm. if str(self.inputSelector.currentNode()) == 'None': print('ERROR:Select Input Volume Node') qt.QMessageBox.information(slicer.util.mainWindow(), 'Slicer Python', 'ERROR:Select Input Volume Node') return True else: Tipo_registro = self.typeComboBox.currentText #el tipo de registro seleccionado previamente en el layout de parameters mvNode = slicer.vtkMRMLMultiVolumeNode( ) #creación nodo multivolumen slicer.mrmlScene.AddNode(mvNode) #añadir a la escena el nodo escena = slicer.mrmlScene volumen4D = self.inputSelector.currentNode() imagenvtk4D = volumen4D.GetImageData() numero_imagenes = volumen4D.GetNumberOfFrames( ) #numero de frames del MV print('imagenes: ' + str(numero_imagenes)) #filtro vtk para descomponer un volumen 4D extract1 = vtk.vtkImageExtractComponents() extract1.SetInputData(imagenvtk4D) #matriz de transformacion ras2ijk = vtk.vtkMatrix4x4() ijk2ras = vtk.vtkMatrix4x4() #le solicitamos al volumen original que nos devuelva sus matrices volumen4D.GetRASToIJKMatrix(ras2ijk) volumen4D.GetIJKToRASMatrix(ijk2ras) #creo un volumen nuevo #volumenFijo = self.inputVolumeSelector.currentNode(); #le asigno las transformaciones #le asigno el volumen 3D fijo extract1.SetComponents(0) extract1.Update() volumenFijo = slicer.vtkMRMLScalarVolumeNode() volumenFijo.SetName('Fijo') volumenFijo.SetAndObserveImageData(extract1.GetOutput()) volumenFijo.SetRASToIJKMatrix(ras2ijk) volumenFijo.SetIJKToRASMatrix(ijk2ras) #anado el nuevo volumen a la escena escena.AddNode(volumenFijo) vol_desp = [] volumenSalida = slicer.vtkMRMLScalarVolumeNode() #creacion de volumen de salida slicer.mrmlScene.AddNode(volumenSalida) j = 1 bandera = 0 frameLabelsAttr = '' volumeLabels = vtk.vtkDoubleArray() volumeLabels.SetNumberOfTuples(numero_imagenes) volumeLabels.SetNumberOfComponents(1) volumeLabels.Allocate(numero_imagenes) mvImage = vtk.vtkImageData() mvImage.SetExtent(volumenFijo.GetImageData().GetExtent() ) ##Se le asigna la dimension del miltuvolumen mvImage.AllocateScalars( volumenFijo.GetImageData().GetScalarType(), numero_imagenes ) ##Se le asigna el tipo y numero 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 conversion y se obtiene la matriz de transformacion del nodo volumenFijo.GetRASToIJKMatrix(mat) mvNode.SetRASToIJKMatrix(mat) volumenFijo.GetIJKToRASMatrix(mat) mvNode.SetIJKToRASMatrix(mat) ## for i in range(numero_imagenes): # extraigo la imagen movil extract1.SetComponents(i) #Seleccionar un volumen lejano extract1.Update() #Creo un volumen movil, y realizamos el mismo procedimiento que con el fijo volumenMovil = slicer.vtkMRMLScalarVolumeNode() volumenMovil.SetRASToIJKMatrix(ras2ijk) volumenMovil.SetIJKToRASMatrix(ijk2ras) volumenMovil.SetAndObserveImageData(extract1.GetOutput()) volumenMovil.SetName('movil') escena.AddNode(volumenMovil) #creamos la transformada para alinear los volumenes transformadaSalidaBSpline = slicer.vtkMRMLBSplineTransformNode( ) transformadaSalidaBSpline.SetName( 'Transformada de registro BSpline' + str(i + 1)) slicer.mrmlScene.AddNode(transformadaSalidaBSpline) transformadaSalidaLinear = slicer.vtkMRMLLinearTransformNode() transformadaSalidaLinear.SetName( 'Transformada de registro Lineal' + str(i + 1)) slicer.mrmlScene.AddNode(transformadaSalidaLinear) #parametros para la operacion de registro que seran entregados al modulo cli "brainsfit" segun tipo de registro parameters = {} if Tipo_registro == 'Rigid-BSpline': parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = 'Rigid' parameters[ 'outputTransform'] = transformadaSalidaLinear.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) if bandera == 0: bandera = 1 volumenFijo = volumenSalida parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenSalida.GetID() parameters['transformType'] = 'BSpline' parameters[ 'outputTransform'] = transformadaSalidaBSpline.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = frameImageArray elif Tipo_registro == 'Rigid-Affine': parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = 'Rigid' parameters[ 'outputTransform'] = transformadaSalidaLinear.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) Matriz = transformadaSalidaLinear.GetMatrixTransformToParent( ) if bandera == 0: bandera = 1 volumenFijo = volumenSalida parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenSalida.GetID() parameters['transformType'] = 'Affine' parameters[ 'outputTransform'] = transformadaSalidaLinear.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = frameImageArray elif (Tipo_registro == 'Rigid') or (Tipo_registro == 'Bspline') or (Tipo_registro == 'Affine'): parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = Tipo_registro if Tipo_registro == 'Bspline': parameters[ 'outputTransform'] = transformadaSalidaBSpline.GetID( ) else: parameters[ 'outputTransform'] = transformadaSalidaLinear.GetID( ) parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) Parameters = {} Parameters['Conductance'] = 1 Parameters['numberOfIterations'] = 5 Parameters['timeStep'] = 0.0625 Parameters['inputVolume'] = volumenSalida.GetID() Parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run( slicer.modules.gradientanisotropicdiffusion, None, Parameters, wait_for_completion=True) frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = frameImageArray if (i == 9): self.VolumenReferencia = volumenSalida 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) Matriz = transformadaSalidaLinear.GetMatrixTransformToParent() #imprime en la consola los volumenes que tienen desplazamientos mayores 1 mm print('Registro completo') #al terminar el ciclo for con todos los volumenes registrados se genera una #ventana emergente con un mensaje("Registro completo!") y mostrando los #volumenes que se desplazaron mas de 4mm qt.QMessageBox.information(slicer.util.mainWindow(), 'Slicer Python', 'Registro completo') return True
def registrarButton(self): Tipo_registro = self.typeComboBox.currentText mvNode = slicer.vtkMRMLMultiVolumeNode() slicer.mrmlScene.AddNode(mvNode) escena = slicer.mrmlScene volumen4D = self.inputSelector.currentNode() imagenvtk4D = volumen4D.GetImageData() numero_imagenes = volumen4D.GetNumberOfFrames() print('imagenes: ' + str(numero_imagenes)) #filtro vtk para descomponer un volumen 4D #matriz de transformacion ras2ijk = vtk.vtkMatrix4x4() ijk2ras = vtk.vtkMatrix4x4() #le solicitamos al volumen original que nos devuelva sus matrices volumen4D.GetRASToIJKMatrix(ras2ijk) volumen4D.GetIJKToRASMatrix(ijk2ras) extract1 = vtk.vtkImageExtractComponents() extract1.SetInputData(imagenvtk4D) ## print(extract1) #creo un volumen nuevo volumenFijo = slicer.vtkMRMLScalarVolumeNode() #le asigno las transformaciones volumenFijo.SetRASToIJKMatrix(ras2ijk) volumenFijo.SetIJKToRASMatrix(ijk2ras) #le asigno el volumen 3D fijo extract1.SetComponents(0) extract1.Update() volumenFijo.SetName('Fijo') volumenFijo.SetAndObserveImageData(extract1.GetOutput()) #anado el nuevo volumen a la escena escena.AddNode(volumenFijo) vol_desp = [] ## volumenSalida = self.volumeSelector.currentNode() volumenSalida = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(volumenSalida) j = 1 bandera = 0 Desp_LR1 = 0 Desp_PA1 = 0 Desp_IS1 = 0 frameLabelsAttr = '' frames = [] volumeLabels = vtk.vtkDoubleArray() volumeLabels.SetNumberOfTuples(numero_imagenes) volumeLabels.SetNumberOfComponents(1) volumeLabels.Allocate(numero_imagenes) mvImage = vtk.vtkImageData() mvImage.SetExtent(volumenFijo.GetImageData().GetExtent() ) ##Se le asigna la dimension del miltuvolumen mvImage.AllocateScalars( volumenFijo.GetImageData().GetScalarType(), numero_imagenes ) ##Se le asigna el tipo y numero 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 conversion y se obtiene la matriz de transformacion del nodo volumenFijo.GetRASToIJKMatrix(mat) mvNode.SetRASToIJKMatrix(mat) volumenFijo.GetIJKToRASMatrix(mat) mvNode.SetIJKToRASMatrix(mat) ## for i in range(numero_imagenes): # extraigo la imagen movil extract1.SetComponents(i) #Seleccionar un volumen lejano extract1.Update() #Creo un volumen movil, y realizamos el mismo procedimiento que con el fijo volumenMovil = slicer.vtkMRMLScalarVolumeNode() volumenMovil.SetRASToIJKMatrix(ras2ijk) volumenMovil.SetIJKToRASMatrix(ijk2ras) volumenMovil.SetAndObserveImageData(extract1.GetOutput()) volumenMovil.SetName('movil') escena.AddNode(volumenMovil) ## slicer.util.saveNode(volumenMovil,'volumenMovil'+str(i+1)+'.nrrd') #creamos la transformada para alinear los volumenes transformadaSalidaBSpline = slicer.vtkMRMLBSplineTransformNode() transformadaSalidaBSpline.SetName( 'Transformada de registro BSpline' + str(i + 1)) slicer.mrmlScene.AddNode(transformadaSalidaBSpline) transformadaSalidaLinear = slicer.vtkMRMLLinearTransformNode() transformadaSalidaLinear.SetName( 'Transformada de registro Lineal' + str(i + 1)) slicer.mrmlScene.AddNode(transformadaSalidaLinear) #parametros para la operacion de registro parameters = {} if Tipo_registro == 'Rigid-BSpline': parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = 'Rigid' parameters['outputTransform'] = transformadaSalidaLinear.GetID( ) parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) if bandera == 0: bandera = 1 volumenFijo = volumenSalida parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenSalida.GetID() parameters['transformType'] = 'BSpline' parameters[ 'outputTransform'] = transformadaSalidaBSpline.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) slicer.util.saveNode(volumenSalida, 'volumenSalida' + str(i + 1) + '.nrrd') frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = frameImageArray elif Tipo_registro == 'Rigid-Affine': parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = 'Rigid' parameters['outputTransform'] = transformadaSalidaLinear.GetID( ) parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) Matriz = transformadaSalidaLinear.GetMatrixTransformToParent() Desp_LR1 = Matriz.GetElement(0, 3) Desp_PA1 = Matriz.GetElement(1, 3) Desp_IS1 = Matriz.GetElement(2, 3) print(Desp_LR1) if bandera == 0: bandera = 1 volumenFijo = volumenSalida parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenSalida.GetID() parameters['transformType'] = 'Affine' parameters['outputTransform'] = transformadaSalidaLinear.GetID( ) parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) slicer.util.saveNode(volumenSalida, 'volumenSalida' + str(i + 1) + '.nrrd') frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = frameImageArray elif (Tipo_registro == 'Rigid') or (Tipo_registro == 'Bspline') or (Tipo_registro == 'Affine'): parameters['fixedVolume'] = volumenFijo.GetID() parameters['movingVolume'] = volumenMovil.GetID() parameters['transformType'] = Tipo_registro ## parameters['linearTransform'] = transformadaSalidaLinear.GetID() ## parameters['bsplineTransform'] = transformadaSalidaBSpline.GetID() if Tipo_registro == 'Bspline': parameters[ 'outputTransform'] = transformadaSalidaBSpline.GetID() else: parameters[ 'outputTransform'] = transformadaSalidaLinear.GetID() parameters['outputVolume'] = volumenSalida.GetID() cliNode = slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) slicer.util.saveNode(volumenSalida, 'volumenSalida' + str(i + 1) + '.nrrd') print('entre') frameImage = volumenSalida.GetImageData() frameImageArray = vtk.util.numpy_support.vtk_to_numpy( frameImage.GetPointData().GetScalars()) mvImageArray.T[i] = 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(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) Matriz = transformadaSalidaLinear.GetMatrixTransformToParent() Desp_LR2 = Matriz.GetElement(0, 3) Desp_PA2 = Matriz.GetElement(1, 3) Desp_IS2 = Matriz.GetElement(2, 3) print(Desp_LR2) Desp_LR = Desp_LR2 + Desp_LR1 Desp_PA = Desp_PA2 + Desp_PA1 Desp_IS = Desp_IS2 + Desp_IS1 if ((abs(Desp_LR) > 1) or (abs(Desp_PA) > 1) or (abs(Desp_IS) > 1)): print(j) vol_des = 'VOLUMEN' + str( i + 1) + ' Desplazamiento --> LR: ' + str( Desp_LR) + ' PA: ' + str(Desp_PA) + ' IS: ' + str( Desp_IS) vol_desp.append(vol_des) print('Registro completo') print(vol_desp) #al terminar el ciclo for con todos los volumenes registrados se genera una #ventana emergente con un mensaje("Registro completo!") y mostrando los #volumenes que se desplazaron mas de 4mm qt.QMessageBox.information(slicer.util.mainWindow(), 'Slicer Python', 'Registro completo' + str(vol_desp)) return True