def erode(self,fill,neighborMode,iterations): eroder = slicer.vtkImageErode() eroder.SetInputData( self.getScopedLabelInput() ) eroder.SetOutput( self.getScopedLabelOutput() ) eroder.SetForeground( EditUtil.getLabel() ) eroder.SetBackground( fill ) if neighborMode == '8': eroder.SetNeighborTo8() elif neighborMode == '4': eroder.SetNeighborTo4() else: # TODO: error feedback from effect logic? # bad neighbor mode - silently use default print('Bad neighborMode: %s' % neighborMode) for i in range(iterations): # TODO: $this setProgressFilter eroder "Erode ($i)" print('updating') eroder.Update() self.applyScopedLabel() eroder.SetOutput( None )
def onApply(self): # Get parameters neighborMode = self.scriptedEffect.integerParameter("NeighborMode") iterations = self.scriptedEffect.integerParameter("Iterations") # Get edited labelmap editedLabelmap = self.scriptedEffect.parameterSetNode().GetEditedLabelmap() # Perform erosion eroder = slicer.vtkImageErode() eroder.SetInputData(editedLabelmap) eroder.SetForeground(1) eroder.SetBackground(0) if neighborMode == 8: eroder.SetNeighborTo8() elif neighborMode == 4: eroder.SetNeighborTo4() else: logging.error("Invalid neighbor mode!") for i in xrange(iterations): eroder.Update() editedLabelmap.DeepCopy(eroder.GetOutput()) # Notify editor about changes. # This needs to be called so that the changes are written back to the edited segment self.scriptedEffect.apply()
def close(self,fill,neighborMode,iterations): dilater = slicer.vtkImageErode() eroder = slicer.vtkImageErode() if vtk.VTK_MAJOR_VERSION <= 5: dilater.SetInput( self.getScopedLabelInput() ) else: dilater.SetInputData( self.getScopedLabelInput() ) if vtk.VTK_MAJOR_VERSION <= 5: eroder.SetInput( dilater.GetOutput() ) else: eroder.SetInputData( dilater.GetOutput() ) eroder.SetOutput( self.getScopedLabelOutput() ) dilater.SetForeground( fill ) dilater.SetBackground( self.editUtil.getLabel() ) eroder.SetForeground( self.editUtil.getLabel() ) eroder.SetBackground( fill ) if neighborMode == '8': dilater.SetNeighborTo8() eroder.SetNeighborTo8() elif neighborMode == '4': dilater.SetNeighborTo4() eroder.SetNeighborTo4() else: # TODO: error feedback from effect logic? # bad neighbor mode - silently use default print('Bad neighborMode: %s' % neighborMode) for i in xrange(iterations): # TODO: $this setProgressFilter dilater "Interpolate ($i)" dilater.Update() eroder.Update() self.applyScopedLabel() dilater.SetOutput( None ) eroder.SetOutput( None )
def removeIslandsMorphologyDecruft(self, image, foregroundLabel, backgroundLabel, iterations=1): # # make binary mask foregroundLabel->1, backgroundLabel->0 # binThresh = vtk.vtkImageThreshold() 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()) 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() 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() 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() 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() 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()) 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() 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() unbinThresh.SetInputConnection(logic.GetOutputPort()) unbinThresh.ThresholdBetween(1, 1) unbinThresh.SetInValue(foregroundLabel) unbinThresh.SetOutValue(backgroundLabel) unbinThresh.Update() image.DeepCopy(unbinThresh.GetOutput())
def removeIslandsMorphologyDecruft(self,image,foregroundLabel,backgroundLabel,iterations=1): # # make binary mask foregroundLabel->1, backgroundLabel->0 # binThresh = vtk.vtkImageThreshold() 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()) 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() 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() 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() 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() 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()) 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() 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() unbinThresh.SetInputConnection( logic.GetOutputPort() ) unbinThresh.ThresholdBetween( 1,1 ) unbinThresh.SetInValue( foregroundLabel ) unbinThresh.SetOutValue( backgroundLabel ) unbinThresh.Update() image.DeepCopy(unbinThresh.GetOutput())
for scan in range(numberOfScans): # load CT file of sample CT-shest slicer.util.loadVolume(dataPath + 'CT-chest.nrrd') ctImage = slicer.util.getNode('CT-chest') # use vtk to adjust the threshold value threshold = vtk.vtkImageThreshold() threshold.SetInputData(ctImage.GetImageData()) # TODO: adjust a better threshold level threshold.ThresholdBetween(300, 1000) threshold.SetInValue(255) threshold.SetOutValue(0) # use a slicer serode serode = slicer.vtkImageErode() serode.SetInputConnection(threshold.GetOutputPort()) serode.SetNeighborTo4() serode.Update() ctImage.SetAndObserveImageData(serode.GetOutputDataObject(0)) # save label map outFileName = 'CT_label_{}.nrrd'.format(scan) outFilePath = os.path.join(dataPath, outFileName) slicer.util.saveNode(ctImage, outFilePath) # make model out of label parameters = {} parameters['InputVolume'] = ctImage.GetID()