def ImageModelSnapshot(self, dataNode, labelNode, outputDir, IDcurrPatient, ImageFilePath, progress_filename, selLabels=False, levels=False): cast1 = vtk.vtkImageCast() cast1.SetOutputScalarTypeToInt() cast1.SetInputConnection(labelNode.GetImageDataConnection()) cast1.Update() labelNode.SetImageDataConnection(cast1.GetOutputPort()) cast2 = vtk.vtkImageCast() cast2.SetOutputScalarTypeToInt() cast2.SetInputConnection(dataNode.GetImageDataConnection()) cast2.Update() dataNode.SetImageDataConnection(cast2.GetOutputPort()) labelNode.SetOrigin(dataNode.GetOrigin()) try: imageNodeSITK = su.PullFromSlicer(dataNode.GetName()) labelNodeSITK = su.PullFromSlicer(labelNode.GetName()) labelArraySITK = sitk.GetArrayFromImage(labelNodeSITK) lbound, hbound = squeeze(self, labelArraySITK, labelNode) self.cmaj = sitk.CropImageFilter() self.cmaj.SetLowerBoundaryCropSize(lbound) self.cmaj.SetUpperBoundaryCropSize(hbound) zoomLabelNodeSITK = self.cmaj.Execute(labelNodeSITK) zoomImageNodeSITK = self.cmaj.Execute(imageNodeSITK) zoomLabelNodeName = 'zoomLabelNode' + '_' + IDcurrPatient zoomImageNodeName = 'zoomImageNode' + '_' + IDcurrPatient su.PushToSlicer(zoomLabelNodeSITK, zoomLabelNodeName) su.PushToSlicer(zoomImageNodeSITK, zoomImageNodeName) zoomLabelNode = slicer.util.getNode(zoomLabelNodeName) zoomImageNode = slicer.util.getNode(zoomImageNodeName) zoomLabelNodeArraySITK = sitk.GetArrayFromImage(zoomLabelNodeSITK) zoomLabelNodeArraySITK = numpy.where(zoomLabelNodeArraySITK == 0, numpy.NAN, zoomLabelNodeArraySITK) maxZind = find_LargestSlices(self, zoomLabelNodeArraySITK) imgOutputDir = str(outputDir) modelHandler(ImageFilePath, zoomImageNode, zoomLabelNode, imgOutputDir, IDcurrPatient, maxZind) return (maxZind) except Exception, e: with open(progress_filename, mode='a') as printfile: printfile.write('ERROR: ' + str(e) + '\n') os.makedirs(os.path.join(outputDir, IDcurrPatient + '_flagged')) return (-1, -1, -1)
def removeIslands(self): # # change the label values based on the parameter node # if not self.sliceLogic: self.sliceLogic = self.editUtil.getSliceLogic() parameterNode = self.editUtil.getParameterNode() minimumSize = int( parameterNode.GetParameter("IslandEffect,minimumSize")) fullyConnected = bool( parameterNode.GetParameter("IslandEffect,fullyConnected")) label = self.editUtil.getLabel() # note that island operation happens in unsigned long space # but the slicer editor works in Short castIn = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castIn.SetInput(self.getScopedLabelInput()) else: castIn.SetInputData(self.getScopedLabelInput()) castIn.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() if vtk.VTK_MAJOR_VERSION <= 5: islandMath.SetInput(castIn.GetOutput()) else: islandMath.SetInputConnection(castIn.GetOutputPort()) islandMath.SetFullyConnected(fullyConnected) islandMath.SetMinimumSize(minimumSize) # TODO: $this setProgressFilter $islandMath "Calculating Islands..." # note that island operation happens in unsigned long space # but the slicer editor works in Short castOut = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castOut.SetInput(islandMath.GetOutput()) else: castOut.SetInputConnection(islandMath.GetOutputPort()) castOut.SetOutputScalarTypeToShort() castOut.SetOutput(self.getScopedLabelOutput()) # TODO $this setProgressFilter $postThresh "Applying to Label Map..." castOut.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print("%d islands created (%d ignored)" % (islandCount, ignoredIslands)) self.applyScopedLabel() castOut.SetOutput(None)
def removeIslands(self): # # change the label values based on the parameter node # if not self.sliceLogic: self.sliceLogic = self.editUtil.getSliceLogic() parameterNode = self.editUtil.getParameterNode() minimumSize = int(parameterNode.GetParameter("IslandEffect,minimumSize")) fullyConnected = bool(parameterNode.GetParameter("IslandEffect,fullyConnected")) label = self.editUtil.getLabel() # note that island operation happens in unsigned long space # but the slicer editor works in Short castIn = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castIn.SetInput( self.getScopedLabelInput() ) else: castIn.SetInputData( self.getScopedLabelInput() ) castIn.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() if vtk.VTK_MAJOR_VERSION <= 5: islandMath.SetInput( castIn.GetOutput() ) else: islandMath.SetInputConnection( castIn.GetOutputPort() ) islandMath.SetFullyConnected( fullyConnected ) islandMath.SetMinimumSize( minimumSize ) # TODO: $this setProgressFilter $islandMath "Calculating Islands..." # note that island operation happens in unsigned long space # but the slicer editor works in Short castOut = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castOut.SetInput( islandMath.GetOutput() ) else: castOut.SetInputConnection( islandMath.GetOutputPort() ) castOut.SetOutputScalarTypeToShort() castOut.SetOutput( self.getScopedLabelOutput() ) # TODO $this setProgressFilter $postThresh "Applying to Label Map..." castOut.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) ) self.applyScopedLabel() castOut.SetOutput( None )
def ImageModelSnapshot(self, dataNode, labelNode, outputDir, IDcurrPatient, ImageFilePath, progress_filename, selLabels=False, levels=False): cast1 = vtk.vtkImageCast() cast1.SetOutputScalarTypeToInt() cast1.SetInputConnection(labelNode.GetImageDataConnection()) cast1.Update() labelNode.SetImageDataConnection(cast1.GetOutputPort()) cast2 = vtk.vtkImageCast() cast2.SetOutputScalarTypeToInt() cast2.SetInputConnection(dataNode.GetImageDataConnection()) cast2.Update() dataNode.SetImageDataConnection(cast2.GetOutputPort()) labelNode.SetOrigin(dataNode.GetOrigin()) try: imageNodeSITK = su.PullFromSlicer(dataNode.GetName()) labelNodeSITK = su.PullFromSlicer(labelNode.GetName()) labelArraySITK = sitk.GetArrayFromImage(labelNodeSITK) lbound, hbound = squeeze(self, labelArraySITK, labelNode) self.cmaj = sitk.CropImageFilter() self.cmaj.SetLowerBoundaryCropSize(lbound) self.cmaj.SetUpperBoundaryCropSize(hbound) zoomLabelNodeSITK = self.cmaj.Execute(labelNodeSITK) zoomImageNodeSITK = self.cmaj.Execute(imageNodeSITK) zoomLabelNodeName = 'zoomLabelNode'+'_'+IDcurrPatient zoomImageNodeName = 'zoomImageNode'+'_'+IDcurrPatient su.PushToSlicer(zoomLabelNodeSITK, zoomLabelNodeName) su.PushToSlicer(zoomImageNodeSITK, zoomImageNodeName) zoomLabelNode = slicer.util.getNode(zoomLabelNodeName) zoomImageNode = slicer.util.getNode(zoomImageNodeName) zoomLabelNodeArraySITK = sitk.GetArrayFromImage(zoomLabelNodeSITK) zoomLabelNodeArraySITK = numpy.where(zoomLabelNodeArraySITK == 0, numpy.NAN, zoomLabelNodeArraySITK) maxZind = find_LargestSlices(self, zoomLabelNodeArraySITK) imgOutputDir = str(outputDir) modelHandler(ImageFilePath, zoomImageNode, zoomLabelNode, imgOutputDir, IDcurrPatient, maxZind) return(maxZind) except Exception, e: with open(progress_filename,mode='a') as printfile: printfile.write('ERROR: ' + str(e) + '\n') os.makedirs(os.path.join(outputDir,IDcurrPatient+'_flagged')) return(-1,-1,-1)
def castScalarToInt(volumeNode): castScalarToInt = vtk.vtkImageCast() castScalarToInt.SetOutputScalarTypeToInt() castScalarToInt.SetInputConnection(volumeNode.GetImageDataConnection()) castScalarToInt.Update() volumeNode.SetImageDataConnection(castScalarToInt.GetOutputPort())
def recolorLabelMap(self, modelNode, labelMap, initialValue, outputValue): import vtkSlicerRtCommonPython if (modelNode != None and labelMap != None): self.labelMapImgData = labelMap.GetImageData() self.resectionPolyData = modelNode.GetPolyData() # IJK -> RAS ijkToRasMatrix = vtk.vtkMatrix4x4() labelMap.GetIJKToRASMatrix(ijkToRasMatrix) # RAS -> IJK rasToIjkMatrix = vtk.vtkMatrix4x4() labelMap.GetRASToIJKMatrix(rasToIjkMatrix) rasToIjkTransform = vtk.vtkTransform() rasToIjkTransform.SetMatrix(rasToIjkMatrix) rasToIjkTransform.Update() # Transform Resection model from RAS -> IJK polyDataTransformFilter = vtk.vtkTransformPolyDataFilter() if (vtk.VTK_MAJOR_VERSION <= 5): polyDataTransformFilter.SetInput(self.resectionPolyData) else: polyDataTransformFilter.SetInputData(self.resectionPolyData) polyDataTransformFilter.SetTransform(rasToIjkTransform) polyDataTransformFilter.Update() # Convert Resection model to label map polyDataToLabelmapFilter = vtkSlicerRtCommonPython.vtkPolyDataToLabelmapFilter() polyDataToLabelmapFilter.SetInputPolyData(polyDataTransformFilter.GetOutput()) polyDataToLabelmapFilter.SetReferenceImage(self.labelMapImgData) polyDataToLabelmapFilter.UseReferenceValuesOn() polyDataToLabelmapFilter.SetBackgroundValue(0) polyDataToLabelmapFilter.SetLabelValue(outputValue) polyDataToLabelmapFilter.Update() # Cast resection label map to unsigned char for use with mask filter castFilter = vtk.vtkImageCast() if (vtk.VTK_MAJOR_VERSION <= 5): castFilter.SetInput(polyDataToLabelmapFilter.GetOutput()) else: castFilter.SetInputData(polyDataToLabelmapFilter.GetOutput()) castFilter.SetOutputScalarTypeToUnsignedChar() castFilter.Update() # Create mask for recoloring the original label map maskFilter = vtk.vtkImageMask() if (vtk.VTK_MAJOR_VERSION <= 5): maskFilter.SetImageInput(self.labelMapImgData) maskFilter.SetMaskInput(castFilter.GetOutput()) else: maskFilter.SetImageInputData(self.labelMapImgData) maskFilter.SetMaskInputData(castFilter.GetOutput()) maskFilter.SetMaskedOutputValue(outputValue) maskFilter.NotMaskOn() maskFilter.Update() self.labelMapImgData = maskFilter.GetOutput() self.labelMapImgData.Modified() labelMap.SetAndObserveImageData(self.labelMapImgData)
def run(self,inputVolume,outputVolume,algorithm=0,variance=2,thresholdmin=0,thresholdmax=0): """ Run the edge detection algorithm """ self.input=inputVolume self.output=outputVolume self.algorithm=algorithm self.variance=variance self.threshold=[thresholdmin,thresholdmax] slicer.util.delayDisplay('Running the edge detection aglorithm') im=self.input.GetImageData() cast=vtk.vtkImageCast() cast.SetOutputScalarTypeToDouble() cast.SetInputData(im) cast.Update() em=slicer.vtkITKEdgeDetection() em.SetInputData(cast.GetOutput()) em.SetAlgorithmInt(self.algorithm) em.Setvariance(self.variance) em.Setthreshold(self.threshold) em.Update() self.output.GetImageData().DeepCopy(em.GetOutput()) return True
def performFrangiVesselness( self, image, minimumDiameter, maximumDiameter, discretizationSteps, alpha, beta, gamma ): ''' ''' # import the vmtk libraries try: #from libvtkvmtkSegmentationPython import * import libvtkvmtkSegmentationPython as s except ImportError: print "FAILURE: Unable to import the SlicerVmtk libraries!" cast = vtk.vtkImageCast() cast.SetInput( image ) cast.SetOutputScalarTypeToFloat() cast.Update() image = cast.GetOutput() v = s.vtkvmtkVesselnessMeasureImageFilter() v.SetInput( image ) v.SetSigmaMin( minimumDiameter ) v.SetSigmaMax( maximumDiameter ) v.SetNumberOfSigmaSteps( discretizationSteps ) v.SetAlpha( alpha ) v.SetBeta( beta ) v.SetGamma( gamma ) v.Update() outImageData = vtk.vtkImageData() outImageData.DeepCopy( v.GetOutput() ) outImageData.Update() outImageData.GetPointData().GetScalars().Modified() return outImageData
def castVolumeNodeToShort(self, volumeNode): imageData = volumeNode.GetImageData() cast = vtk.vtkImageCast() cast.SetInputData(imageData) cast.SetOutputScalarTypeToShort() cast.SetOutput(imageData) cast.Update()
def castVolumeNodeToDouble(self, volumeNode): castFilter = vtk.vtkImageCast() castFilter.SetInputData(volumeNode.GetImageData()) castFilter.SetOutputScalarTypeToDouble() castFilter.Update() volumeNode.SetAndObserveImageData(castFilter.GetOutput()) logging.info(volumeNode.GetName() + ' was casted to double.')
def performFrangiVesselness(self, image, minimumDiameter, maximumDiameter, discretizationSteps, alpha, beta, gamma): ''' ''' # import the vmtk libraries try: import vtkvmtkSegmentationPython as vtkvmtkSegmentation except ImportError: logging.error("Unable to import the SlicerVmtk libraries") cast = vtk.vtkImageCast() cast.SetInputData(image) cast.SetOutputScalarTypeToFloat() cast.Update() image = cast.GetOutput() v = vtkvmtkSegmentation.vtkvmtkVesselnessMeasureImageFilter() v.SetInputData(image) v.SetSigmaMin(minimumDiameter) v.SetSigmaMax(maximumDiameter) v.SetNumberOfSigmaSteps(discretizationSteps) v.SetAlpha(alpha) v.SetBeta(beta) v.SetGamma(gamma) v.Update() outImageData = vtk.vtkImageData() outImageData.DeepCopy(v.GetOutput()) outImageData.GetPointData().GetScalars().Modified() return outImageData
def buildGradientBasedFeatureImage(self, imageData): ''' ''' # import the vmtk libraries try: import vtkvmtkSegmentationPython as vtkvmtkSegmentation except ImportError: logging.error("Unable to import the SlicerVmtk libraries") derivativeSigma = 0.0 sigmoidRemapping = 1 cast = vtk.vtkImageCast() cast.SetInputData(imageData) cast.SetOutputScalarTypeToFloat() cast.Update() if (derivativeSigma > 0.0): gradientMagnitude = vtkvmtkSegmentation.vtkvmtkGradientMagnitudeRecursiveGaussianImageFilter( ) gradientMagnitude.SetInputData(cast.GetOutput()) gradientMagnitude.SetSigma(derivativeSigma) gradientMagnitude.SetNormalizeAcrossScale(0) gradientMagnitude.Update() else: gradientMagnitude = vtkvmtkSegmentation.vtkvmtkGradientMagnitudeImageFilter( ) gradientMagnitude.SetInputData(cast.GetOutput()) gradientMagnitude.Update() featureImage = None if sigmoidRemapping == 1: scalarRange = gradientMagnitude.GetOutput().GetPointData( ).GetScalars().GetRange() inputMinimum = scalarRange[0] inputMaximum = scalarRange[1] alpha = -(inputMaximum - inputMinimum) / 6.0 beta = (inputMaximum + inputMinimum) / 2.0 sigmoid = vtkvmtkSegmentation.vtkvmtkSigmoidImageFilter() sigmoid.SetInputData(gradientMagnitude.GetOutput()) sigmoid.SetAlpha(alpha) sigmoid.SetBeta(beta) sigmoid.SetOutputMinimum(0.0) sigmoid.SetOutputMaximum(1.0) sigmoid.Update() featureImage = sigmoid.GetOutput() else: boundedReciprocal = vtkvmtkSegmentation.vtkvmtkBoundedReciprocalImageFilter( ) boundedReciprocal.SetInputData(gradientMagnitude.GetOutput()) boundedReciprocal.Update() featureImage = boundedReciprocal.GetOutput() outImageData = vtk.vtkImageData() outImageData.DeepCopy(featureImage) return outImageData
def castVolumeNodeToDouble(self, volumeNode): castFilter = vtk.vtkImageCast() castFilter.SetInputData(volumeNode.GetImageData()) castFilter.SetOutputScalarTypeToDouble() castFilter.Update() volumeNode.SetAndObserveImageData(castFilter.GetOutput()) return True
def buildGradientBasedFeatureImage( self, imageData ): ''' ''' # import the vmtk libraries try: #from libvtkvmtkSegmentationPython import * import libvtkvmtkSegmentationPython as s except ImportError: print "FAILURE: Unable to import the SlicerVmtk libraries!" derivativeSigma = 0.0 sigmoidRemapping = 1 cast = vtk.vtkImageCast() cast.SetInput( imageData ) cast.SetOutputScalarTypeToFloat() cast.Update() if ( derivativeSigma > 0.0 ): gradientMagnitude = s.vtkvmtkGradientMagnitudeRecursiveGaussianImageFilter() gradientMagnitude.SetInput( cast.GetOutput() ) gradientMagnitude.SetSigma( derivativeSigma ) gradientMagnitude.SetNormalizeAcrossScale( 0 ) gradientMagnitude.Update() else: gradientMagnitude = s.vtkvmtkGradientMagnitudeImageFilter() gradientMagnitude.SetInput( cast.GetOutput() ) gradientMagnitude.Update() featureImage = None if sigmoidRemapping == 1: scalarRange = gradientMagnitude.GetOutput().GetPointData().GetScalars().GetRange() inputMinimum = scalarRange[0] inputMaximum = scalarRange[1] alpha = -( inputMaximum - inputMinimum ) / 6.0 beta = ( inputMaximum + inputMinimum ) / 2.0 sigmoid = s.vtkvmtkSigmoidImageFilter() sigmoid.SetInput( gradientMagnitude.GetOutput() ) sigmoid.SetAlpha( alpha ) sigmoid.SetBeta( beta ) sigmoid.SetOutputMinimum( 0.0 ) sigmoid.SetOutputMaximum( 1.0 ) sigmoid.Update() featureImage = sigmoid.GetOutput() else: boundedReciprocal = s.vtkvmtkBoundedReciprocalImageFilter() boundedReciprocal.SetInput( gradientMagnitude.GetOutput() ) boundedReciprocal.Update() featureImage = boundedReciprocal.GetOutput() outImageData = vtk.vtkImageData() outImageData.DeepCopy( featureImage ) outImageData.Update() return outImageData
def onSliderChanged(self, newValue): value = self.__mdSlider.value if self.__mvNode != None: mvDisplayNode = self.__mvNode.GetDisplayNode() mvDisplayNode.SetFrameComponent(newValue) if self.extractFrame == True: frameVolume = self.__vfSelector.currentNode() if frameVolume == None or self.__mvNode == None: return mvImage = self.__mvNode.GetImageData() frameId = newValue extract = vtk.vtkImageExtractComponents() cast = vtk.vtkImageCast() extract.SetInput(mvImage) extract.SetComponents(frameId) cast.SetInput(extract.GetOutput()) cast.SetOutputScalarTypeToShort() cast.Update() frame = cast.GetOutput() ras2ijk = vtk.vtkMatrix4x4() ijk2ras = vtk.vtkMatrix4x4() self.__mvNode.GetRASToIJKMatrix(ras2ijk) self.__mvNode.GetIJKToRASMatrix(ijk2ras) frameImage = frameVolume.GetImageData() if frameImage == None: frameVolume.SetAndObserveImageData(frame) frameVolume.SetRASToIJKMatrix(ras2ijk) frameVolume.SetIJKToRASMatrix(ijk2ras) frameImage = frame frameImage.DeepCopy(frame) displayNode = frameVolume.GetDisplayNode() if displayNode == None: displayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeDisplayNode') displayNode.SetReferenceCount(1) displayNode.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(displayNode) displayNode.SetDefaultColorMap() frameVolume.SetAndObserveDisplayNodeID(displayNode.GetID()) frameName = '%s frame %d' % (self.__mvNode.GetName(), frameId) frameVolume.SetName(frameName)
def detectEdgeInROI(self,edge,alternateEdge=None): qu=QCLib.QCUtil() VOIROI=qu.getVOIfromRectROI(self.ROI) eV=vtk.vtkExtractVOI() eV.SetInputData(self.input.GetImageData()) eV.SetVOI(VOIROI) eV.Update() imROI=eV.GetOutput() thr=[0,0] if self.algorithm==0: #find threshold for edge detection mL=makeROIGhostLogic() ghost=vtk.vtkImageData() ghnode=slicer.vtkMRMLScalarVolumeNode() ghnode.SetAndObserveImageData(ghost) mL.run(self.input,ghnode) rL=ROIStatisticsLogic() rL.run(self.input,ghnode) zROI=VOIROI[4] ghVals=[] stats=rL.stats.values() for n in range(rL.stats.__len__()): ghVals.append(stats[n][zROI]['mean']+stats[n][zROI]['sd']) thr=[max(ghVals),2*max(ghVals)] else: alternateEdge=None cast=vtk.vtkImageCast() cast.SetOutputScalarTypeToDouble() cast.SetInputData(imROI) cast.Update() em=slicer.vtkITKEdgeDetection() em.SetInputData(cast.GetOutput()) em.SetAlgorithmInt(self.algorithm) em.Setthreshold(thr) em.Setvariance(5) em.Update() edge.DeepCopy(em.GetOutput()) if alternateEdge: self.signedDistance(edge,alternateEdge)
def savePNGs(self, node, pattern): wlc = vtk.vtkImageMapToWindowLevelColors() wlc.SetInputData(node.GetImageData()) if not node.GetLabelMap(): displayNode = node.GetDisplayNode() wlc.SetWindow(displayNode.GetWindow()) wlc.SetLevel(displayNode.GetLevel()) wlc.Update() print(wlc.GetOutput().GetScalarRange()) cast = vtk.vtkImageCast() cast.SetInputConnection(wlc.GetOutputPort()) cast.SetOutputScalarTypeToUnsignedChar() pngWriter = vtk.vtkPNGWriter() pngWriter.SetFilePattern(pattern) pngWriter.SetInputConnection(cast.GetOutputPort()) pngWriter.Write() slicer.modules.BitmapGeneratorWidget.pngWriter = pngWriter
def DoIt(inputDir, labelFile, outputDir, forceLabel, forceResample): dbDir1 = slicer.app.temporaryPath+'/LabelConverter' if not hasattr(slicer.modules, 'reporting'): print 'The Reporting module has not been loaded into Slicer, script cannot run!\n\tTry setting the --additional-module-path parameter.' sys.exit(1) reportingLogic = slicer.modules.reporting.logic() print('Temporary directory location: '+dbDir1) qt.QDir().mkpath(dbDir1) dbDir0 = None if slicer.dicomDatabase: dbDir0 = os.path.split(slicer.dicomDatabase.databaseFilename)[0] dicomWidget = slicer.modules.dicom.widgetRepresentation().self() dicomWidget.onDatabaseDirectoryChanged(dbDir1) # import DICOM study indexer = ctk.ctkDICOMIndexer() indexer.addDirectory(slicer.dicomDatabase, inputDir, None) indexer.waitForImportFinished() print('DICOM import finished!') # # Read the input DICOM series as a volume # dcmList = [] for dcm in os.listdir(inputDir): if len(dcm)-dcm.rfind('.dcm') == 4: dcmList.append(inputDir+'/'+dcm) scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']() loadables = scalarVolumePlugin.examine([dcmList]) if len(loadables) == 0: print 'Could not parse the DICOM Study!' sys.exit(1) inputVolume = scalarVolumePlugin.load(loadables[0]) print 'Input volume loaded! ID = ', inputVolume.GetID() # read the label volume labelVolume = slicer.vtkMRMLLabelMapVolumeNode() sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() sNode.SetFileName(labelFile) sNode.ReadData(labelVolume) if forceLabel>0: # print('Forcing label to '+str(forceLabel)) labelImage = labelVolume.GetImageData() thresh = vtk.vtkImageThreshold() if vtk.vtkVersion().GetVTKMajorVersion() < 6: thresh.SetInput(labelImage) else: thresh.SetInputData(labelImage) thresh.ThresholdBetween(1, labelImage.GetScalarRange()[1]) thresh.SetInValue(int(forceLabel)) thresh.SetOutValue(0) thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.Update() labelImage = thresh.GetOutput() labelVolume.SetAndObserveImageData(labelImage) slicer.mrmlScene.AddNode(labelVolume) print 'Label volume added, id = ', labelVolume.GetID() # ensure that the label volume scalar type is unsigned short if labelVolume.GetImageData() != None: scalarType = labelVolume.GetImageData().GetScalarType() if scalarType != vtk.VTK_UNSIGNED_SHORT: print 'Label volume has pixel type of ',vtk.vtkImageScalarTypeNameMacro(scalarType),', casting to unsigned short' cast = vtk.vtkImageCast() cast.SetOutputScalarTypeToUnsignedShort() if vtk.vtkVersion().GetVTKMajorVersion() < 6: cast.SetInput(labelVolume.GetImageData()) cast.Update() labelVolume.SetAndObserveImageData(cast.GetOutput()) else: cast.SetInputConnection(labelVolume.GetImageDataConnection()) cast.Update() labelVolume.SetImageDataConnection(cast.GetOutputPort()) if labelVolume.GetImageData().GetScalarType() != vtk.VTK_UNSIGNED_SHORT: print 'Failed to cast label volume to unsigned short, type is ', vtk.vtkImageScalarTypeNameMacro(labelVolume.GetImageData().GetScalarType()) sys.exit(1) volumesLogic = slicer.modules.volumes.logic() geometryCheckString = volumesLogic.CheckForLabelVolumeValidity(inputVolume, labelVolume) if geometryCheckString != "": # has the user specified that forced resampling is okay? if forceResample == False: print 'Label volume mismatch with input volume:\n',geometryCheckString,'\nForced resample not specified, aborting. Re-run with --force option to ignore geometric inconsistencies' sys.exit(1) # resample label to the input volume raster resampledLabel = slicer.vtkMRMLLabelMapVolumeNode() slicer.mrmlScene.AddNode(resampledLabel) print 'Resampled label added, id = ', resampledLabel.GetID() resampledLabel = volumesLogic.ResampleVolumeToReferenceVolume(labelVolume, inputVolume) labelVolume = resampledLabel displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode() displayNode.SetAndObserveColorNodeID(reportingLogic.GetDefaultColorNode().GetID()) slicer.mrmlScene.AddNode(displayNode) labelVolume.SetAttribute('AssociatedNodeID',inputVolume.GetID()) labelVolume.SetAndObserveDisplayNodeID(displayNode.GetID()) # initialize the DICOM DB for Reporting logic, save as DICOM SEG labelCollection = vtk.vtkCollection() labelCollection.AddItem(labelVolume) print('About to write DICOM SEG!') dbFileName = slicer.dicomDatabase.databaseFilename reportingLogic.InitializeDICOMDatabase(dbFileName) reportingLogic.DicomSegWrite(labelCollection, outputDir) dicomWidget.onDatabaseDirectoryChanged(dbDir0) exit()
def removeIslands(self): # # change the label values based on the parameter node # if not self.sliceLogic: self.sliceLogic = self.editUtil.getSliceLogic() parameterNode = self.editUtil.getParameterNode() minimumSize = int(parameterNode.GetParameter("IslandEffect,minimumSize")) fullyConnected = bool(parameterNode.GetParameter("IslandEffect,fullyConnected")) label = self.editUtil.getLabel() # first, create an inverse binary version of the image # so that islands inside segemented object will be detected, along # with a big island of the background preThresh = vtk.vtkImageThreshold() preThresh.SetInValue( 0 ) preThresh.SetOutValue( 1 ) preThresh.ReplaceInOn() preThresh.ReplaceOutOn() preThresh.ThresholdBetween( label,label ) preThresh.SetInput( self.getScopedLabelInput() ) preThresh.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() islandMath.SetInput( preThresh.GetOutput() ) islandMath.SetFullyConnected( fullyConnected ) islandMath.SetMinimumSize( minimumSize ) # TODO: $this setProgressFilter $islandMath "Calculating Islands..." islandMath.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) ) if islandCount == 0: return bgPixel = self.findNonZeroBorderPixel(islandMath.GetOutput()) # now rethreshold so that everything which is not background becomes the label postThresh = vtk.vtkImageThreshold() postThresh.SetInValue( 0 ) postThresh.SetOutValue( label ) postThresh.ReplaceInOn() postThresh.ReplaceOutOn() postThresh.ThresholdBetween( bgPixel, bgPixel ) postThresh.SetOutputScalarTypeToShort() postThresh.SetInput( islandMath.GetOutput() ) postThresh.SetOutput( self.getScopedLabelOutput() ) # TODO $this setProgressFilter $postThresh "Applying to Label Map..." postThresh.Update() self.applyScopedLabel() if False: # some code for debugging - leave it in layerLogic = self.sliceLogic.GetLabelLayer() labelNode = layerLogic.GetVolumeNode() volumesLogic = slicer.modules.volumes.logic() thresh1 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres1') islands = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'islands') thresh2 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres2') cast = vtk.vtkImageCast() cast.SetOutputScalarTypeToShort() cast.SetInput(preThresh.GetOutput()) cast.Update() thresh1.SetAndObserveImageData(cast.GetOutput()) cast2 = vtk.vtkImageCast() cast2.SetOutputScalarTypeToShort() cast2.SetInput(islandMath.GetOutput()) cast2.Update() islands.SetAndObserveImageData(cast2.GetOutput()) thresh2.SetAndObserveImageData(postThresh.GetOutput())
def createSyntheticMask(self, maskVolumeNode, radius): """ Run the actual algorithm """ roiSphere = vtk.vtkSphere() roiCenter = [0, 0, 0] roiOrigin = [0, 0, 0] roiSpacing = [1, 1, 1] roiDimension = [100, 100, 100] # roiDimension = refVolumeNode.GetImageData().GetDimensions() roiCenter[0] = roiOrigin[0] + roiDimension[0] * roiSpacing[0] / 2 roiCenter[1] = roiOrigin[1] + roiDimension[1] * roiSpacing[1] / 2 roiCenter[2] = roiOrigin[2] + roiDimension[2] * roiSpacing[2] / 2 print "roiCenter", roiCenter """ ijkToRas = vtk.vtkMatrix4x4() refVolumeNode.GetIJKToRASMatrix( ijkToRas ) roiPoint = [0,0,0,1]; roiPoint[0] = roiCenter[0] roiPoint[1] = roiCenter[1] roiPoint[2] = roiCenter[2] roiPoint = ijkToRas.MultiplyPoint(roiPoint) roiCenter[0] = roiPoint[0] roiCenter[1] = roiPoint[1] roiCenter[2] = roiPoint[2] print "roiCenter", roiCenter """ roiSphere.SetCenter(roiCenter) roiSphere.SetRadius(radius) # Determine the transform between the box and the image IJK coordinate systems rasToSphere = vtk.vtkMatrix4x4() # if roiNode.GetTransformNodeID() != None: # roiSphereTransformNode = slicer.mrmlScene.GetNodeByID(roiNode.GetTransformNodeID()) # sphereToRas = vtk.vtkMatrix4x4() # roiSphereTransformNode.GetMatrixTransformToWorld(sphereToRas) # rasToSphere.DeepCopy(sphereToRas) # rasToSphere.Invert() """ ijkToSphere = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(rasToSphere,ijkToRas,ijkToSphere) ijkToSphereTransform = vtk.vtkTransform() ijkToSphereTransform.SetMatrix(ijkToSphere) roiSphere.SetTransform(ijkToSphereTransform) # Use the stencil to fill the volume refImageData = refVolumeNode.GetImageData() """ imageSource = vtk.vtkImageNoiseSource() imageSource.SetMinimum(0) imageSource.SetMaximum(0) imageSource.SetWholeExtent(0, roiDimension[0] - 1, 0, roiDimension[1] - 1, 0, roiDimension[2] - 1) imageSource.Update() imageCast = vtk.vtkImageCast() imageCast.SetInputData(imageSource.GetOutput()) imageCast.SetOutputScalarTypeToUnsignedChar() imageCast.Update() """ changeInfo = vtk.vtkImageChangeInformation() changeInfo.SetInputData(imageCast.GetOutput()) changeInfo.SetOutputOrigin(refImageData.GetOrigin()) changeInfo.SetOutputSpacing(refImageData.GetSpacing()) changeInfo.Update() """ # Convert the implicit function to a stencil functionToStencil = vtk.vtkImplicitFunctionToImageStencil() functionToStencil.SetInput(roiSphere) functionToStencil.SetOutputOrigin(0, 0, 0) functionToStencil.SetOutputSpacing(1, 1, 1) functionToStencil.SetOutputWholeExtent(0, roiDimension[0] - 1, 0, roiDimension[1] - 1, 0, roiDimension[2] - 1) functionToStencil.Update() # Apply the stencil to the volume stencilToImage = vtk.vtkImageStencil() stencilToImage.SetInputData(imageCast.GetOutput()) stencilToImage.SetStencilData(functionToStencil.GetOutput()) stencilToImage.ReverseStencilOn() stencilToImage.SetBackgroundValue(1) stencilToImage.Update() """ extent = refImageData.GetWholeExtent() resample = vtk.vtkImageReslice() resample.SetInputData(stencilToImage.GetOutput()) resample.SetOutputOrigin(refImageData.GetOrigin()) resample.SetOutputSpacing(refImageData.GetSpacing()[0]/2, refImageData.GetSpacing()[1]/2, refImageData.GetSpacing()[2]/2 ) resample.SetOutputExtent(extent[0], (extent[1]-extent[0])*2-1, extent[2], (extent[3]-extent[2])*2-1, extent[4], (extent[5]-extent[4])*2-1) resample.Update() changeInfo2 = vtk.vtkImageChangeInformation() changeInfo2.SetInputData(resample.GetOutput()) changeInfo2.SetOutputOrigin(refImageData.GetOrigin()) changeInfo2.SetOutputSpacing(refImageData.GetSpacing()) changeInfo2.Update() """ # Update the volume with the stencil operation result maskVolumeNode.SetAndObserveImageData(stencilToImage.GetOutput()) maskVolumeNode.SetOrigin(0, 0, 0) maskVolumeNode.SetSpacing(1, 1, 1) # maskVolumeNode.CopyOrientation(refVolumeNode) mgr = slicer.app.layoutManager() mgr.sliceWidget( 'Red').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID()) mgr.sliceWidget( 'Yellow').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID()) mgr.sliceWidget( 'Green').sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( maskVolumeNode.GetID())
def removeIslandsMorphologyDecruft(self,image,foregroundLabel,backgroundLabel,iterations=1): # # make binary mask foregroundLabel->1, backgroundLabel->0 # binThresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: binThresh.SetInput( image ) else: binThresh.SetInputData( image ) binThresh.ThresholdBetween(foregroundLabel,foregroundLabel) binThresh.SetInValue( 1 ) binThresh.SetOutValue( 0 ) binThresh.Update() # # first, erode iterations number of times # eroder = slicer.vtkImageErode() eroderImage = vtk.vtkImageData() eroderImage.DeepCopy(binThresh.GetOutput()) if vtk.VTK_MAJOR_VERSION <= 5: eroder.SetInput(eroderImage) else: eroder.SetInputData(eroderImage) for iteration in range(iterations): eroder.SetForeground( 1 ) eroder.SetBackground( 0 ) eroder.SetNeighborTo8() eroder.Update() eroderImage.DeepCopy(eroder.GetOutput()) # # now save only islands bigger than a specified size # # note that island operation happens in unsigned long space # but the slicer editor works in Short castIn = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castIn.SetInput( eroderImage ) else: castIn.SetInputConnection( eroder.GetInputConnection(0,0) ) castIn.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() if vtk.VTK_MAJOR_VERSION <= 5: islandMath.SetInput( castIn.GetOutput() ) else: islandMath.SetInputConnection( castIn.GetOutputPort() ) islandMath.SetFullyConnected( self.fullyConnected ) islandMath.SetMinimumSize( self.minimumSize ) # note that island operation happens in unsigned long space # but the slicer editor works in Short castOut = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castOut.SetInput( islandMath.GetOutput() ) else: castOut.SetInputConnection( islandMath.GetOutputPort() ) castOut.SetOutputScalarTypeToShort() castOut.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print( "%d islands created (%d ignored)" % (islandCount, ignoredIslands) ) # # now map everything back to 0 and 1 # thresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: thresh.SetInput( castOut.GetOutput() ) else: thresh.SetInputConnection( castOut.GetOutputPort() ) thresh.ThresholdByUpper(1) thresh.SetInValue( 1 ) thresh.SetOutValue( 0 ) thresh.Update() # # now, dilate back (erode background) iterations_plus_one number of times # dilater = slicer.vtkImageErode() dilaterImage = vtk.vtkImageData() dilaterImage.DeepCopy(thresh.GetOutput()) if vtk.VTK_MAJOR_VERSION <= 5: dilater.SetInput(dilaterImage) else: dilater.SetInputData(dilaterImage) for iteration in range(1+iterations): dilater.SetForeground( 0 ) dilater.SetBackground( 1 ) dilater.SetNeighborTo8() dilater.Update() dilaterImage.DeepCopy(dilater.GetOutput()) # # only keep pixels in both original and dilated result # logic = vtk.vtkImageLogic() if vtk.VTK_MAJOR_VERSION <= 5: logic.SetInput1(dilaterImage) logic.SetInput2(binThresh.GetOutput()) else: logic.SetInputConnection(0, dilater.GetInputConnection(0,0)) logic.SetInputConnection(1, binThresh.GetOutputPort()) #if foregroundLabel == 0: # logic.SetOperationToNand() #else: logic.SetOperationToAnd() logic.SetOutputTrueValue(1) logic.Update() # # convert from binary mask to 1->foregroundLabel, 0->backgroundLabel # unbinThresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: unbinThresh.SetInput( logic.GetOutput() ) else: unbinThresh.SetInputConnection( logic.GetOutputPort() ) unbinThresh.ThresholdBetween( 1,1 ) unbinThresh.SetInValue( foregroundLabel ) unbinThresh.SetOutValue( backgroundLabel ) unbinThresh.Update() image.DeepCopy(unbinThresh.GetOutput())
def removeIslands(self): # # change the label values based on the parameter node # if not self.sliceLogic: self.sliceLogic = self.editUtil.getSliceLogic() parameterNode = self.editUtil.getParameterNode() minimumSize = int( parameterNode.GetParameter("IslandEffect,minimumSize")) fullyConnected = bool( parameterNode.GetParameter("IslandEffect,fullyConnected")) label = self.editUtil.getLabel() # first, create an inverse binary version of the image # so that islands inside segemented object will be detected, along # with a big island of the background preThresh = vtk.vtkImageThreshold() preThresh.SetInValue(0) preThresh.SetOutValue(1) preThresh.ReplaceInOn() preThresh.ReplaceOutOn() preThresh.ThresholdBetween(label, label) preThresh.SetInput(self.getScopedLabelInput()) preThresh.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() islandMath.SetInput(preThresh.GetOutput()) islandMath.SetFullyConnected(fullyConnected) islandMath.SetMinimumSize(minimumSize) # TODO: $this setProgressFilter $islandMath "Calculating Islands..." islandMath.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print("%d islands created (%d ignored)" % (islandCount, ignoredIslands)) if islandCount == 0: return bgPixel = self.findNonZeroBorderPixel(islandMath.GetOutput()) # now rethreshold so that everything which is not background becomes the label postThresh = vtk.vtkImageThreshold() postThresh.SetInValue(0) postThresh.SetOutValue(label) postThresh.ReplaceInOn() postThresh.ReplaceOutOn() postThresh.ThresholdBetween(bgPixel, bgPixel) postThresh.SetOutputScalarTypeToShort() postThresh.SetInput(islandMath.GetOutput()) postThresh.SetOutput(self.getScopedLabelOutput()) # TODO $this setProgressFilter $postThresh "Applying to Label Map..." postThresh.Update() self.applyScopedLabel() if False: # some code for debugging - leave it in layerLogic = self.sliceLogic.GetLabelLayer() labelNode = layerLogic.GetVolumeNode() volumesLogic = slicer.modules.volumes.logic() thresh1 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres1') islands = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'islands') thresh2 = volumesLogic.CloneVolume(slicer.mrmlScene, labelNode, 'thres2') cast = vtk.vtkImageCast() cast.SetOutputScalarTypeToShort() cast.SetInput(preThresh.GetOutput()) cast.Update() thresh1.SetAndObserveImageData(cast.GetOutput()) cast2 = vtk.vtkImageCast() cast2.SetOutputScalarTypeToShort() cast2.SetInput(islandMath.GetOutput()) cast2.Update() islands.SetAndObserveImageData(cast2.GetOutput()) thresh2.SetAndObserveImageData(postThresh.GetOutput())
def fastMarching(self, percentMax): self.fm = None # allocate a new filter each time March is hit bgImage = self.editUtil.getBackgroundImage() labelImage = self.editUtil.getLabelImage() # collect seeds dim = bgImage.GetWholeExtent() # initialize the filter self.fm = slicer.vtkPichonFastMarching() scalarRange = bgImage.GetScalarRange() depth = scalarRange[1] - scalarRange[0] # this is more or less arbitrary; large depth values will bring the # algorithm to the knees scaleValue = 0 shiftValue = 0 if depth > 300: scaleValue = 300. / depth if scalarRange[0] < 0: shiftValue = scalarRange[0] * -1 if scaleValue or shiftValue: rescale = vtk.vtkImageShiftScale() rescale.SetInput(bgImage) rescale.SetScale(scaleValue) rescale.SetShift(shiftValue) rescale.Update() bgImage = rescale.GetOutput() scalarRange = bgImage.GetScalarRange() depth = scalarRange[1] - scalarRange[0] print('Input scalar range: ' + str(depth)) self.fm.init(dim[1] + 1, dim[3] + 1, dim[5] + 1, depth, 1, 1, 1) caster = vtk.vtkImageCast() caster.SetOutputScalarTypeToShort() caster.SetInput(bgImage) caster.Update() self.fm.SetInput(caster.GetOutput()) # self.fm.SetOutput(labelImage) npoints = int( (dim[1] + 1) * (dim[3] + 1) * (dim[5] + 1) * percentMax / 100.) self.fm.setNPointsEvolution(npoints) print('Setting active label to ' + str(self.editUtil.getLabel())) self.fm.setActiveLabel(self.editUtil.getLabel()) nSeeds = self.fm.addSeedsFromImage(labelImage) if nSeeds == 0: return 0 self.fm.Modified() self.fm.Update() # TODO: need to call show() twice for data to be updated self.fm.show(1) self.fm.Modified() self.fm.Update() self.fm.show(1) self.fm.Modified() self.fm.Update() self.undoRedo.saveState() self.editUtil.getLabelImage().DeepCopy(self.fm.GetOutput()) self.editUtil.markVolumeNodeAsModified( self.sliceLogic.GetLabelLayer().GetVolumeNode()) # print('FastMarching output image: '+str(output)) print('FastMarching march update completed') return npoints
def DoIt(inputDir, rgbDir, outputDir): # # Read the input DICOM series as a volume # dcmList = [] for dcm in os.listdir(inputDir): if len(dcm)-dcm.rfind('.dcm') == 4: dcmList.append(inputDir+'/'+dcm) scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']() print 'Will examine: ',dcmList indexer = ctk.ctkDICOMIndexer() indexer.addDirectory(slicer.dicomDatabase, inputDir) indexer.waitForImportFinished() loadables = scalarVolumePlugin.examine([dcmList]) if len(loadables) == 0: print 'Could not parse the DICOM Study!' exit() inputVolume = scalarVolumePlugin.load(loadables[0]) sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() ''' sNode.ResetFileNameList() for f in loadables[0].files: sNode.AddFileName(f) sNode.SetFileName(loadables[0].files[0]) sNode.SetSingleFile(0) inputVolume = slicer.vtkMRMLScalarVolumeNode() sNode.ReadData(inputVolume) ''' sNode.SetWriteFileFormat('nrrd') sNode.SetFileName(os.path.join(outputDir,'input_volume.nrrd')) sNode.WriteData(inputVolume) # # Order the input RGBs and rename in a temp directory # rgbList = [] for rgb in os.listdir(rgbDir): if len(rgb)-rgb.rfind('.bmp') == 4: rgbList.append(rgb) tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory') tmpDir = tmpDir+'/PNGStackLabelConverter' if not os.path.exists(tmpDir): os.mkdir(tmpDir) oldFiles = os.listdir(tmpDir) # just in case there is anything in that directory for f in oldFiles: os.unlink(tmpDir+'/'+f) rgbOrdered = [None] * len(loadables[0].files) rgbCnt = 0 rgbExt = rgbList[0][rgbList[0].rfind('.')+1:len(rgbList[0])] print 'Extension for RGBs: ',rgbExt dcmFileList = loadables[0].files rgbRenamedList = [] print 'Number of dcm files: ',len(dcmFileList), ' and rgb files: ',len(rgbOrdered) dcmIdx = 0 for dcm in dcmFileList: rgbIdx = 0 for rgb in rgbList: dcmPrefix = dcm[dcm.rfind('/')+1:dcm.rfind('.')] if rgb.find(dcmPrefix) != -1: name = string.zfill(str(dcmIdx),5) rgbCnt = rgbCnt+1 src = rgbDir+'/'+rgb dest = tmpDir+'/'+name+'.'+rgbExt rgbRenamedList.append(dest) shutil.copy(src,dest) break rgbIdx = rgbIdx+1 # remove the matched DICOM file from the list if rgbIdx == len(rgbList): print('ERROR: failed to find matching label file for DICOM file '+dcm) return del rgbList[rgbIdx] dcmIdx = dcmIdx+1 if len(rgbRenamedList) == 0: print 'Could not parse the DICOM Study!' return sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() sNode.ResetFileNameList() for f in rgbRenamedList: sNode.AddFileName(f) sNode.SetFileName(rgbRenamedList[0]) sNode.SetSingleFile(0) inputRGBVolume = slicer.vtkMRMLVectorVolumeNode() sNode.ReadData(inputRGBVolume) # run the filter # - extract the RGB portions extract = vtk.vtkImageExtractComponents() extract.SetComponents(0,1,2) if vtk.vtkVersion().GetVTKMajorVersion() < 6: extract.SetInput(inputRGBVolume.GetImageData()) else: extract.SetInputData(inputRGBVolume.GetImageData()) luminance = vtk.vtkImageLuminance() if vtk.vtkVersion().GetVTKMajorVersion() < 6: luminance.SetInput(extract.GetOutput()) else: luminance.SetInputData(extract.GetOutput()) cast = vtk.vtkImageCast() if vtk.vtkVersion().GetVTKMajorVersion() < 6: cast.SetInput(luminance.GetOutput()) else: cast.SetInputData(luminance.GetOutput()) cast.SetOutputScalarTypeToShort() cast.GetOutput().Update() ijkToRAS = vtk.vtkMatrix4x4() inputVolume.GetIJKToRASMatrix(ijkToRAS) outputLabel = slicer.vtkMRMLLabelMapVolumeNode() outputLabel.SetIJKToRASMatrix(ijkToRAS) outputLabel.SetAndObserveImageData(cast.GetOutput()) reportingLogic = slicer.modules.reporting.logic() displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode() displayNode.SetAndObserveColorNodeID(reportingLogic.GetDefaultColorNode().GetID()) slicer.mrmlScene.AddNode(displayNode) outputLabel.SetAndObserveDisplayNodeID(displayNode.GetID()) sNode.SetWriteFileFormat('nrrd') sNode.SetFileName(os.path.join(outputDir,'label_output.nrrd')) sNode.WriteData(outputLabel) # save as DICOM SEG labelCollection = vtk.vtkCollection() labelCollection.AddItem(outputLabel) slicer.mrmlScene.AddNode(inputVolume) outputLabel.SetAttribute('AssociatedNodeID',inputVolume.GetID()) slicer.mrmlScene.AddNode(outputLabel) # initialize the DICOM DB for Reporting logic settings = qt.QSettings() dbFileName = settings.value('DatabaseDirectory','') if dbFileName =='': print('ERROR: database must be initialized') else: dbFileName = dbFileName +'/ctkDICOM.sql' reportingLogic.InitializeDICOMDatabase(dbFileName) reportingLogic.DicomSegWrite(labelCollection, outputDir)
def performInitialization(self, image, lowerThreshold, upperThreshold, sourceSeedIds, targetSeedIds, ignoreSideBranches=0): ''' ''' # import the vmtk libraries try: import vtkvmtkSegmentationPython as vtkvmtkSegmentation except ImportError: logging.error("Unable to import the SlicerVmtk libraries") cast = vtk.vtkImageCast() cast.SetInputData(image) cast.SetOutputScalarTypeToFloat() cast.Update() image = cast.GetOutput() scalarRange = image.GetScalarRange() imageDimensions = image.GetDimensions() maxImageDimensions = max(imageDimensions) threshold = vtk.vtkImageThreshold() threshold.SetInputData(image) threshold.ThresholdBetween(lowerThreshold, upperThreshold) threshold.ReplaceInOff() threshold.ReplaceOutOn() threshold.SetOutValue(scalarRange[0] - scalarRange[1]) threshold.Update() thresholdedImage = threshold.GetOutput() scalarRange = thresholdedImage.GetScalarRange() shiftScale = vtk.vtkImageShiftScale() shiftScale.SetInputData(thresholdedImage) shiftScale.SetShift(-scalarRange[0]) shiftScale.SetScale(1.0 / (scalarRange[1] - scalarRange[0])) shiftScale.Update() speedImage = shiftScale.GetOutput() if ignoreSideBranches: # ignore sidebranches, use colliding fronts fastMarching = vtkvmtkSegmentation.vtkvmtkCollidingFrontsImageFilter( ) fastMarching.SetInputData(speedImage) fastMarching.SetSeeds1(sourceSeedIds) fastMarching.SetSeeds2(targetSeedIds) fastMarching.ApplyConnectivityOn() fastMarching.StopOnTargetsOn() fastMarching.Update() subtract = vtk.vtkImageMathematics() subtract.SetInputData(fastMarching.GetOutput()) subtract.SetOperationToAddConstant() subtract.SetConstantC(-10 * fastMarching.GetNegativeEpsilon()) subtract.Update() else: fastMarching = vtkvmtkSegmentation.vtkvmtkFastMarchingUpwindGradientImageFilter( ) fastMarching.SetInputData(speedImage) fastMarching.SetSeeds(sourceSeedIds) fastMarching.GenerateGradientImageOn() fastMarching.SetTargetOffset(0.0) fastMarching.SetTargets(targetSeedIds) if targetSeedIds.GetNumberOfIds() > 0: fastMarching.SetTargetReachedModeToOneTarget() else: fastMarching.SetTargetReachedModeToNoTargets() fastMarching.Update() if targetSeedIds.GetNumberOfIds() > 0: subtract = vtk.vtkImageMathematics() subtract.SetInputData(fastMarching.GetOutput()) subtract.SetOperationToAddConstant() subtract.SetConstantC(-fastMarching.GetTargetValue()) subtract.Update() else: subtract = vtk.vtkImageThreshold() subtract.SetInputData(fastMarching.GetOutput()) subtract.ThresholdByLower(2000) # TODO find robuste value subtract.ReplaceInOff() subtract.ReplaceOutOn() subtract.SetOutValue(-1) subtract.Update() outImageData = vtk.vtkImageData() outImageData.DeepCopy(subtract.GetOutput()) return outImageData
def performInitialization( self, image, lowerThreshold, upperThreshold, sourceSeedIds, targetSeedIds, ignoreSideBranches=0 ): ''' ''' # import the vmtk libraries try: #from libvtkvmtkSegmentationPython import * import libvtkvmtkSegmentationPython as s except ImportError: print "FAILURE: Unable to import the SlicerVmtk libraries!" cast = vtk.vtkImageCast() cast.SetInput( image ) cast.SetOutputScalarTypeToFloat() cast.Update() image = cast.GetOutput() scalarRange = image.GetScalarRange() imageDimensions = image.GetDimensions() maxImageDimensions = max( imageDimensions ) threshold = vtk.vtkImageThreshold() threshold.SetInput( image ) threshold.ThresholdBetween( lowerThreshold, upperThreshold ) threshold.ReplaceInOff() threshold.ReplaceOutOn() threshold.SetOutValue( scalarRange[0] - scalarRange[1] ) threshold.Update() thresholdedImage = threshold.GetOutput() scalarRange = thresholdedImage.GetScalarRange() shiftScale = vtk.vtkImageShiftScale() shiftScale.SetInput( thresholdedImage ) shiftScale.SetShift( -scalarRange[0] ) shiftScale.SetScale( 1.0 / ( scalarRange[1] - scalarRange[0] ) ) shiftScale.Update() speedImage = shiftScale.GetOutput() if ignoreSideBranches: # ignore sidebranches, use colliding fronts fastMarching = s.vtkvmtkCollidingFrontsImageFilter() fastMarching.SetInput( speedImage ) fastMarching.SetSeeds1( sourceSeedIds ) fastMarching.SetSeeds2( targetSeedIds ) fastMarching.ApplyConnectivityOn() fastMarching.StopOnTargetsOn() fastMarching.Update() subtract = vtk.vtkImageMathematics() subtract.SetInput( fastMarching.GetOutput() ) subtract.SetOperationToAddConstant() subtract.SetConstantC( -10 * fastMarching.GetNegativeEpsilon() ) subtract.Update() else: fastMarching = s.vtkvmtkFastMarchingUpwindGradientImageFilter() fastMarching.SetInput( speedImage ) fastMarching.SetSeeds( sourceSeedIds ) fastMarching.GenerateGradientImageOn() fastMarching.SetTargetOffset( 0.0 ) fastMarching.SetTargets( targetSeedIds ) if targetSeedIds.GetNumberOfIds() > 0: fastMarching.SetTargetReachedModeToOneTarget() else: fastMarching.SetTargetReachedModeToNoTargets() fastMarching.Update() if targetSeedIds.GetNumberOfIds() > 0: subtract = vtk.vtkImageMathematics() subtract.SetInput( fastMarching.GetOutput() ) subtract.SetOperationToAddConstant() subtract.SetConstantC( -fastMarching.GetTargetValue() ) subtract.Update() else: subtract = vtk.vtkImageThreshold() subtract.SetInput( fastMarching.GetOutput() ) subtract.ThresholdByLower( 2000 ) # TODO find robuste value subtract.ReplaceInOff() subtract.ReplaceOutOn() subtract.SetOutValue( -1 ) subtract.Update() outImageData = vtk.vtkImageData() outImageData.DeepCopy( subtract.GetOutput() ) outImageData.Update() return outImageData
def removeIslandsMorphologyDecruft(self, image, foregroundLabel, backgroundLabel, iterations=1): # # make binary mask foregroundLabel->1, backgroundLabel->0 # binThresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: binThresh.SetInput(image) else: binThresh.SetInputData(image) binThresh.ThresholdBetween(foregroundLabel, foregroundLabel) binThresh.SetInValue(1) binThresh.SetOutValue(0) binThresh.Update() # # first, erode iterations number of times # eroder = slicer.vtkImageErode() eroderImage = vtk.vtkImageData() eroderImage.DeepCopy(binThresh.GetOutput()) if vtk.VTK_MAJOR_VERSION <= 5: eroder.SetInput(eroderImage) else: eroder.SetInputData(eroderImage) for iteration in range(iterations): eroder.SetForeground(1) eroder.SetBackground(0) eroder.SetNeighborTo8() eroder.Update() eroderImage.DeepCopy(eroder.GetOutput()) # # now save only islands bigger than a specified size # # note that island operation happens in unsigned long space # but the slicer editor works in Short castIn = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castIn.SetInput(eroderImage) else: castIn.SetInputConnection(eroder.GetInputConnection(0, 0)) castIn.SetOutputScalarTypeToUnsignedLong() # now identify the islands in the inverted volume # and find the pixel that corresponds to the background islandMath = vtkITK.vtkITKIslandMath() if vtk.VTK_MAJOR_VERSION <= 5: islandMath.SetInput(castIn.GetOutput()) else: islandMath.SetInputConnection(castIn.GetOutputPort()) islandMath.SetFullyConnected(self.fullyConnected) islandMath.SetMinimumSize(self.minimumSize) # note that island operation happens in unsigned long space # but the slicer editor works in Short castOut = vtk.vtkImageCast() if vtk.VTK_MAJOR_VERSION <= 5: castOut.SetInput(islandMath.GetOutput()) else: castOut.SetInputConnection(islandMath.GetOutputPort()) castOut.SetOutputScalarTypeToShort() castOut.Update() islandCount = islandMath.GetNumberOfIslands() islandOrigCount = islandMath.GetOriginalNumberOfIslands() ignoredIslands = islandOrigCount - islandCount print("%d islands created (%d ignored)" % (islandCount, ignoredIslands)) # # now map everything back to 0 and 1 # thresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: thresh.SetInput(castOut.GetOutput()) else: thresh.SetInputConnection(castOut.GetOutputPort()) thresh.ThresholdByUpper(1) thresh.SetInValue(1) thresh.SetOutValue(0) thresh.Update() # # now, dilate back (erode background) iterations_plus_one number of times # dilater = slicer.vtkImageErode() dilaterImage = vtk.vtkImageData() dilaterImage.DeepCopy(thresh.GetOutput()) if vtk.VTK_MAJOR_VERSION <= 5: dilater.SetInput(dilaterImage) else: dilater.SetInputData(dilaterImage) for iteration in range(1 + iterations): dilater.SetForeground(0) dilater.SetBackground(1) dilater.SetNeighborTo8() dilater.Update() dilaterImage.DeepCopy(dilater.GetOutput()) # # only keep pixels in both original and dilated result # logic = vtk.vtkImageLogic() if vtk.VTK_MAJOR_VERSION <= 5: logic.SetInput1(dilaterImage) logic.SetInput2(binThresh.GetOutput()) else: logic.SetInputConnection(0, dilater.GetInputConnection(0, 0)) logic.SetInputConnection(1, binThresh.GetOutputPort()) # if foregroundLabel == 0: # logic.SetOperationToNand() # else: logic.SetOperationToAnd() logic.SetOutputTrueValue(1) logic.Update() # # convert from binary mask to 1->foregroundLabel, 0->backgroundLabel # unbinThresh = vtk.vtkImageThreshold() if vtk.VTK_MAJOR_VERSION <= 5: unbinThresh.SetInput(logic.GetOutput()) else: unbinThresh.SetInputConnection(logic.GetOutputPort()) unbinThresh.ThresholdBetween(1, 1) unbinThresh.SetInValue(foregroundLabel) unbinThresh.SetOutValue(backgroundLabel) unbinThresh.Update() image.DeepCopy(unbinThresh.GetOutput())
def DoIt(inputDir, rgbDir, outputDir): # # Read the input DICOM series as a volume # dcmList = [] for dcm in os.listdir(inputDir): if len(dcm) - dcm.rfind('.dcm') == 4: dcmList.append(inputDir + '/' + dcm) scalarVolumePlugin = slicer.modules.dicomPlugins[ 'DICOMScalarVolumePlugin']() print 'Will examine: ', dcmList indexer = ctk.ctkDICOMIndexer() indexer.addDirectory(slicer.dicomDatabase, inputDir) indexer.waitForImportFinished() loadables = scalarVolumePlugin.examine([dcmList]) if len(loadables) == 0: print 'Could not parse the DICOM Study!' exit() inputVolume = scalarVolumePlugin.load(loadables[0]) sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() ''' sNode.ResetFileNameList() for f in loadables[0].files: sNode.AddFileName(f) sNode.SetFileName(loadables[0].files[0]) sNode.SetSingleFile(0) inputVolume = slicer.vtkMRMLScalarVolumeNode() sNode.ReadData(inputVolume) ''' sNode.SetWriteFileFormat('nrrd') sNode.SetFileName(os.path.join(outputDir, 'input_volume.nrrd')) sNode.WriteData(inputVolume) # # Order the input RGBs and rename in a temp directory # rgbList = [] for rgb in os.listdir(rgbDir): if len(rgb) - rgb.rfind('.bmp') == 4: rgbList.append(rgb) tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory') tmpDir = tmpDir + '/PNGStackLabelConverter' if not os.path.exists(tmpDir): os.mkdir(tmpDir) oldFiles = os.listdir(tmpDir) # just in case there is anything in that directory for f in oldFiles: os.unlink(tmpDir + '/' + f) rgbOrdered = [None] * len(loadables[0].files) rgbCnt = 0 rgbExt = rgbList[0][rgbList[0].rfind('.') + 1:len(rgbList[0])] print 'Extension for RGBs: ', rgbExt dcmFileList = loadables[0].files rgbRenamedList = [] print 'Number of dcm files: ', len(dcmFileList), ' and rgb files: ', len( rgbOrdered) dcmIdx = 0 for dcm in dcmFileList: rgbIdx = 0 for rgb in rgbList: dcmPrefix = dcm[dcm.rfind('/') + 1:dcm.rfind('.')] if rgb.find(dcmPrefix) != -1: name = string.zfill(str(dcmIdx), 5) rgbCnt = rgbCnt + 1 src = rgbDir + '/' + rgb dest = tmpDir + '/' + name + '.' + rgbExt rgbRenamedList.append(dest) shutil.copy(src, dest) break rgbIdx = rgbIdx + 1 # remove the matched DICOM file from the list if rgbIdx == len(rgbList): print('ERROR: failed to find matching label file for DICOM file ' + dcm) return del rgbList[rgbIdx] dcmIdx = dcmIdx + 1 if len(rgbRenamedList) == 0: print 'Could not parse the DICOM Study!' return sNode = slicer.vtkMRMLVolumeArchetypeStorageNode() sNode.ResetFileNameList() for f in rgbRenamedList: sNode.AddFileName(f) sNode.SetFileName(rgbRenamedList[0]) sNode.SetSingleFile(0) inputRGBVolume = slicer.vtkMRMLVectorVolumeNode() sNode.ReadData(inputRGBVolume) # run the filter # - extract the RGB portions extract = vtk.vtkImageExtractComponents() extract.SetComponents(0, 1, 2) if vtk.vtkVersion().GetVTKMajorVersion() < 6: extract.SetInput(inputRGBVolume.GetImageData()) else: extract.SetInputData(inputRGBVolume.GetImageData()) luminance = vtk.vtkImageLuminance() if vtk.vtkVersion().GetVTKMajorVersion() < 6: luminance.SetInput(extract.GetOutput()) else: luminance.SetInputData(extract.GetOutput()) cast = vtk.vtkImageCast() if vtk.vtkVersion().GetVTKMajorVersion() < 6: cast.SetInput(luminance.GetOutput()) else: cast.SetInputData(luminance.GetOutput()) cast.SetOutputScalarTypeToShort() cast.GetOutput().Update() ijkToRAS = vtk.vtkMatrix4x4() inputVolume.GetIJKToRASMatrix(ijkToRAS) outputLabel = slicer.vtkMRMLLabelMapVolumeNode() outputLabel.SetIJKToRASMatrix(ijkToRAS) outputLabel.SetAndObserveImageData(cast.GetOutput()) reportingLogic = slicer.modules.reporting.logic() displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode() displayNode.SetAndObserveColorNodeID( reportingLogic.GetDefaultColorNode().GetID()) slicer.mrmlScene.AddNode(displayNode) outputLabel.SetAndObserveDisplayNodeID(displayNode.GetID()) sNode.SetWriteFileFormat('nrrd') sNode.SetFileName(os.path.join(outputDir, 'label_output.nrrd')) sNode.WriteData(outputLabel) # save as DICOM SEG labelCollection = vtk.vtkCollection() labelCollection.AddItem(outputLabel) slicer.mrmlScene.AddNode(inputVolume) outputLabel.SetAttribute('AssociatedNodeID', inputVolume.GetID()) slicer.mrmlScene.AddNode(outputLabel) # initialize the DICOM DB for Reporting logic settings = qt.QSettings() dbFileName = settings.value('DatabaseDirectory', '') if dbFileName == '': print('ERROR: database must be initialized') else: dbFileName = dbFileName + '/ctkDICOM.sql' reportingLogic.InitializeDICOMDatabase(dbFileName) reportingLogic.DicomSegWrite(labelCollection, outputDir)
def fastMarching(self,percentMax): self.fm = None # allocate a new filter each time March is hit bgImage = EditUtil.getBackgroundImage() labelImage = EditUtil.getLabelImage() # collect seeds if vtk.VTK_MAJOR_VERSION <= 5: dim = bgImage.GetWholeExtent() else: dim = bgImage.GetDimensions() print dim # initialize the filter self.fm = slicer.vtkPichonFastMarching() scalarRange = bgImage.GetScalarRange() depth = scalarRange[1]-scalarRange[0] # this is more or less arbitrary; large depth values will bring the # algorithm to the knees scaleValue = 0 shiftValue = 0 if depth>300: scaleValue = 300./depth if scalarRange[0] < 0: shiftValue = scalarRange[0]*-1 if scaleValue or shiftValue: rescale = vtk.vtkImageShiftScale() if vtk.VTK_MAJOR_VERSION <= 5: rescale.SetInput(bgImage) else: rescale.SetInputData(bgImage) rescale.SetScale(scaleValue) rescale.SetShift(shiftValue) rescale.Update() bgImage = rescale.GetOutput() scalarRange = bgImage.GetScalarRange() depth = scalarRange[1]-scalarRange[0] print('Input scalar range: '+str(depth)) if vtk.VTK_MAJOR_VERSION <= 5: self.fm.init(dim[1]+1, dim[3]+1, dim[5]+1, depth, 1, 1, 1) else: self.fm.init(dim[0], dim[1], dim[2], depth, 1, 1, 1) caster = vtk.vtkImageCast() caster.SetOutputScalarTypeToShort() if vtk.VTK_MAJOR_VERSION <= 5: caster.SetInput(bgImage) caster.Update() self.fm.SetInput(caster.GetOutput()) else: caster.SetInputData(bgImage) self.fm.SetInputConnection(caster.GetOutputPort()) # self.fm.SetOutput(labelImage) if vtk.VTK_MAJOR_VERSION <= 5: npoints = int((dim[1]+1)*(dim[3]+1)*(dim[5]+1)*percentMax/100.) else: npoints = int(dim[0]*dim[1]*dim[2]*percentMax/100.) self.fm.setNPointsEvolution(npoints) print('Setting active label to '+str(EditUtil.getLabel())) self.fm.setActiveLabel(EditUtil.getLabel()) nSeeds = self.fm.addSeedsFromImage(labelImage) if nSeeds == 0: return 0 self.fm.Modified() self.fm.Update() # TODO: need to call show() twice for data to be updated self.fm.show(1) self.fm.Modified() self.fm.Update() self.fm.show(1) self.fm.Modified() self.fm.Update() self.undoRedo.saveState() EditUtil.getLabelImage().DeepCopy(self.fm.GetOutput()) EditUtil.markVolumeNodeAsModified(self.sliceLogic.GetLabelLayer().GetVolumeNode()) # print('FastMarching output image: '+str(output)) print('FastMarching march update completed') return npoints
def GetDistanceMap(self,edgeImg,altedgeImg): tmpimage=vtk.vtkImageData() cast=vtk.vtkImageCast() cast.SetOutputScalarTypeToDouble() cast.SetInputData(edgeImg) cast.Update() #invert edge image edge=0 and background=2x Math=vtk.vtkImageMathematics() Math.SetInput1Data(cast.GetOutput()) Math.SetConstantC(0) Math.SetConstantK(2) Math.SetOperationToReplaceCByK() Math.Update() tmpimage.DeepCopy(Math.GetOutput()) Math.SetInput1Data(tmpimage) Math.SetConstantC(1) Math.SetConstantK(0) Math.Update() cast.SetInputData(Math.GetOutput()) cast.Update() tmpimage.DeepCopy(cast.GetOutput()) tmpimage2=vtk.vtkImageData() #calculate distance map if self.distalg==0: dm=slicer.vtkITKSignedDistanceTransform() # tmpimage.SetSpacing(self.input.GetSpacing()) # dm.SetUseImageSpacing(True) dm.SetAlgorithmToSignedMaurer() dm.SetInputData(tmpimage) dm.Update() tmpimage2.DeepCopy(dm.GetOutput()) elif self.distalg==1: dm=slicer.vtkITKSignedDistanceTransform() dm.SetAlgorithmToApproximateSigned() dm.SetInputData(tmpimage) dm.Update() tmpimage2.DeepCopy(dm.GetOutput()) elif self.distalg==2: dm=slicer.vtkITKSignedDistanceTransform() # tmpimage.SetSpacing(self.input.GetSpacing()) # dm.SetUseImageSpacing(True) dm.SetAlgorithmToSignedDanielsson() dm.SetObjectValue(2) dm.SetInputData(tmpimage) dm.Update() tmpimage2.DeepCopy(dm.GetOutput()) elif self.distalg==3: dm=vtk.vtkImageEuclideanDistance() #tmpimage.SetSpacing(self.input.GetSpacing()) dm.InitializeOn() #dm.ConsiderAnisotropyOn() dm.SetInputData(tmpimage) dm.Update() Math.SetInputData(dm.GetOutput()) Math.SetOperationToSquareRoot() Math.Update() tmpimage2.DeepCopy(Math.GetOutput()) if not altedgeImg: altedgeImg=tmpimage2 qu=QCLib.QCUtil() rect=qu.minRectangle(self.ROI) for i in range(rect['xmin'].__len__()): if rect['xmin'][i]>=0: index=i break xmin=rect['xmin'][index] xmax=rect['xmax'][index] ymin=rect['ymin'][index] ymax=rect['ymax'][index] distMap=vtk.vtkImageData() distMap.DeepCopy(edgeImg) for x in range(xmin,xmax+1): for y in range(ymin,ymax+1): isedge=math.copysign(edgeImg.GetScalarComponentAsDouble(x,y,index,0)-1,1) if self.distalg!=3: val=math.copysign((math.fabs(tmpimage2.GetScalarComponentAsDouble(x,y,index,0))+1)*isedge,altedgeImg.GetScalarComponentAsDouble(x,y,index,0)) else: val=math.copysign((math.fabs(tmpimage2.GetScalarComponentAsDouble(x,y,index,0)))*isedge,altedgeImg.GetScalarComponentAsDouble(x,y,index,0)) distMap.SetScalarComponentFromDouble(x,y,index,0,val) return distMap
def recolorLabelMap(self, modelNode, labelMap, initialValue, outputValue): import vtkSlicerRtCommonPython if (modelNode != None and labelMap != None): self.labelMapImgData = labelMap.GetImageData() self.resectionPolyData = modelNode.GetPolyData() # IJK -> RAS ijkToRasMatrix = vtk.vtkMatrix4x4() labelMap.GetIJKToRASMatrix(ijkToRasMatrix) # RAS -> IJK rasToIjkMatrix = vtk.vtkMatrix4x4() labelMap.GetRASToIJKMatrix(rasToIjkMatrix) rasToIjkTransform = vtk.vtkTransform() rasToIjkTransform.SetMatrix(rasToIjkMatrix) rasToIjkTransform.Update() # Transform Resection model from RAS -> IJK polyDataTransformFilter = vtk.vtkTransformPolyDataFilter() if (vtk.VTK_MAJOR_VERSION <= 5): polyDataTransformFilter.SetInput(self.resectionPolyData) else: polyDataTransformFilter.SetInputData(self.resectionPolyData) polyDataTransformFilter.SetTransform(rasToIjkTransform) polyDataTransformFilter.Update() # Convert Resection model to label map polyDataToLabelmapFilter = vtkSlicerRtCommonPython.vtkPolyDataToLabelmapFilter( ) polyDataToLabelmapFilter.SetInputPolyData( polyDataTransformFilter.GetOutput()) polyDataToLabelmapFilter.SetReferenceImage(self.labelMapImgData) polyDataToLabelmapFilter.UseReferenceValuesOn() polyDataToLabelmapFilter.SetBackgroundValue(0) polyDataToLabelmapFilter.SetLabelValue(outputValue) polyDataToLabelmapFilter.Update() # Cast resection label map to unsigned char for use with mask filter castFilter = vtk.vtkImageCast() if (vtk.VTK_MAJOR_VERSION <= 5): castFilter.SetInput(polyDataToLabelmapFilter.GetOutput()) else: castFilter.SetInputData(polyDataToLabelmapFilter.GetOutput()) castFilter.SetOutputScalarTypeToUnsignedChar() castFilter.Update() # Create mask for recoloring the original label map maskFilter = vtk.vtkImageMask() if (vtk.VTK_MAJOR_VERSION <= 5): maskFilter.SetImageInput(self.labelMapImgData) maskFilter.SetMaskInput(castFilter.GetOutput()) else: maskFilter.SetImageInputData(self.labelMapImgData) maskFilter.SetMaskInputData(castFilter.GetOutput()) maskFilter.SetMaskedOutputValue(outputValue) maskFilter.NotMaskOn() maskFilter.Update() self.labelMapImgData = maskFilter.GetOutput() self.labelMapImgData.Modified() labelMap.SetAndObserveImageData(self.labelMapImgData)