Additional Python Examples¶
Overview¶
Code¶
Python¶
#!/usr/bin/env python
from __future__ import print_function
import sys
import SimpleITK as sitk
import os
# verify that we have the correct number of arguments
if ( len( sys.argv ) != 5 ):
sys.stderr.write( "Usage: prog inputFile outputFile replaceValue upperThreshold\n" )
exit( 1 )
# copy the arguments in to variables
inputFileName = sys.argv[1]
outputFileName = sys.argv[2]
replaceValue = int( sys.argv[3] )
upperThreshold = float( sys.argv[4] )
# Read the file into an sitkImage
image = sitk.ReadImage( inputFileName )
# Threshold the value [0,2), results in values inside the range 1, 0 otherwise
boundary = sitk.BinaryThreshold( image, 0, upperThreshold, 1, 0 )
boundary = sitk.BinaryMorphologicalClosing( boundary, 1 )
# Remove any label pixel not connected to the boarder
boundary = sitk.BinaryGrindPeak( boundary )
boundary = sitk.Cast( boundary, image.GetPixelID() )
# Multiply, the input image by not the boarder.
# This will multiply the image by 0 or 1, where 0 is the
# boarder. Making the board 0
image = image * ~boundary
# add the replace value to the pixel on the board
image = image + ( boundary * replaceValue )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( image, "Boarder Segmentation" )
#!/usr/bin/env python
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
if len ( sys.argv ) < 2:
print( "Usage: %s <input>" % ( sys.argv[0] ) )
sys.exit ( 1 )
image = sitk.Cast( sitk.ReadImage( sys.argv[1] ), sitk.sitkFloat32 )
edges = sitk.CannyEdgeDetection( image, lowerThreshold=200, upperThreshold=400, variance=[4]*3 )
stats = sitk.StatisticsImageFilter()
stats.Execute( image )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( sitk.Maximum( image*0.5, edges*stats.GetMaximum()*.5) )
'''=========================================================================
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
#
# Check Command Line
#
if len( sys.argv ) < 7:
print("Usage: ConnectedThresholdImageFilter inputImage outputImage lowerThreshold upperThreshold seedX seedY [seed2X seed2Y ... ]");
sys.exit( 1 )
#
# Read the image
#
reader = sitk.ImageFileReader()
reader.SetFileName( sys.argv[1] )
image = reader.Execute();
#
# Blur using CurvatureFlowImageFilter
#
blurFilter = sitk.CurvatureFlowImageFilter()
blurFilter.SetNumberOfIterations( 5 )
blurFilter.SetTimeStep( 0.125 )
image = blurFilter.Execute( image )
#
# Set up ConnectedThresholdImageFilter for segmentation
#
segmentationFilter = sitk.ConnectedThresholdImageFilter()
segmentationFilter.SetLower( float(sys.argv[3]) )
segmentationFilter.SetUpper( float(sys.argv[4]) )
segmentationFilter.SetReplaceValue( 255 )
for i in range( 5, len(sys.argv)-1, 2 ):
seed = [ int(sys.argv[i]), int(sys.argv[i+1]) ]
segmentationFilter.AddSeed( seed )
print( "Adding seed at: ", seed, " with intensity: ", image.GetPixel(*seed) )
# Run the segmentation filter
image = segmentationFilter.Execute( image )
image[seed] = 255
#
# Write out the result
#
writer = sitk.ImageFileWriter()
writer.SetFileName( sys.argv[2] )
writer.Execute( image )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( image, "ConntectedThreshold" )
#=========================================================================
from __future__ import print_function
import SimpleITK as sitk
import sys, time
if len( sys.argv ) < 3:
print( "Usage: python " + __file__ + " <input_image> <output_image>" )
sys.exit ( 1 )
# Read the image, single 3D DICOM slice
image = sitk.ReadImage( sys.argv[1] )
# Modify the image (mean)
mean_image = sitk.BoxMean( image, [3,3,1] )
# Save the modified image:
# We do not provide a method that copies all keys blindly. Our intent is
# to force us to remember that we always need to modify the meta-data dicitonary
# keys when we save processed images in DICOM format.
# In case of the DICOM format, amongst other keys we need to set the Image Type (0008,0008),
# the Series Date (0008,0021), and Series Time (0008,0021). Obviously we need to set a
# different series number (0020,0011), series instance UID (0020,000E), etc. - we don't do
# that here.
# Please see the DICOM standard (http://dicom.nema.org/standard.html) for complete details on
# how to create valid DICOM images.
all_keys = image.GetMetaDataKeys()
for key in all_keys:
mean_image.SetMetaData( key, image.GetMetaData( key ) )
mean_image.SetMetaData( "0008|0008", "DERIVED\SECONDARY" )
modification_time = time.strftime("%H%M%S")
modification_date = time.strftime("%Y%m%d")
mean_image.SetMetaData( "0008|0031", modification_time )
mean_image.SetMetaData( "0008|0021", modification_date )
sitk.WriteImage( mean_image, sys.argv[2] )
# Finally, read the image back and see that changes were made
# Note that the image type (0008|0008) can contain additional spaces. The requirement is that
# the string have an even length (ftp://dicom.nema.org/medical/DICOM/2013/output/chtml/part05/sect_6.2.html).
# Where spaces are added is not specified and thus may vary ("DERIVED\SECONDARY ", "DERIVED\ SECONDARY" are
# equivalent).
modified_image = sitk.ReadImage( sys.argv[2] )
if modified_image.GetMetaData( "0008|0008" ).replace(" ","") != "DERIVED\SECONDARY" or \
modified_image.GetMetaData( "0008|0031" ) != modification_time or \
modified_image.GetMetaData( "0008|0021" ) != modification_date:
sys.exit(1)
sys.exit( 0 )
#!/usr/bin/env python
#=========================================================================
#
# This example shows how to read a specific series from a Dicom directory that
# may contain more than one series. The script scans for all series. If an
# output name is given, it writes out the requested series. If no specific
# series name is given, the first series found is written.
#
from __future__ import print_function
import sys, getopt
import SimpleITK as sitk
target_series = ""
output_image = ""
def usage():
print ( "\nUsage: %s [-s series_name] input_directory [output_image]\n" % (sys.argv[0]) )
# Parse command line options
try:
opts, args = getopt.getopt(sys.argv[1:], "s:", [ "series" ] )
except getopt.GetoptError as err:
usage()
sys.exit(1)
for o, a in opts:
if o in ("-s", "--series"):
target_series = a
else:
assert False, "unhandled options"
# Get input/output names
if len(args) < 1:
print( args )
usage()
sys.exit(1)
input_directory = args[0]
if len(args)>1:
output_image = args[1]
# Find the Dicom series
reader = sitk.ImageSeriesReader()
written = False
series_found = reader.GetGDCMSeriesIDs(input_directory)
# Process each Dicom series
if len(series_found):
for serie in series_found:
print( "\nSeries:", serie )
# Get the Dicom filename corresponding to the current series
dicom_names = reader.GetGDCMSeriesFileNames(input_directory, serie)
print( "\nFiles in series: ", dicom_names )
if len(dicom_names):
reader.SetFileNames(dicom_names)
image = reader.Execute()
print( "\nImage size: ", image.GetSize() )
if (output_image != "") and not written:
if (target_series == "" or target_series == serie):
print( "\nWriting", output_image )
sitk.WriteImage(image, output_image)
written = True
else:
sys.exit(1)
print ()
#!/usr/bin/env python
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
if len ( sys.argv ) != 4:
print( "Usage: %s inputImage sliceNumber outputImage" % ( sys.argv[0] ) )
sys.exit ( 1 )
zslice = int( sys.argv[2] )
inputImage = sitk.ReadImage( str(sys.argv[1]) )
size = list( inputImage.GetSize() )
size[2] = 0
index = [ 0, 0, zslice ]
Extractor = sitk.ExtractImageFilter()
Extractor.SetSize( size )
Extractor.SetIndex( index )
sitk.WriteImage( Extractor.Execute( inputImage ), str(sys.argv[3]) )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( Extractor.Execute( inputImage ) )
#!/usr/bin/env python
from __future__ import print_function
from __future__ import division
import SimpleITK as sitk
import sys
import os
import math
if len ( sys.argv ) < 4:
print( "Usage: FFTConvolution <input> <kernel> <output>" )
sys.exit ( 1 )
inputFileName = sys.argv[1]
kernelFileName = sys.argv[2]
outputFileName = sys.argv[3]
### Input Image ###
# read the input image
img = sitk.ReadImage( inputFileName )
# save the type of pixel the input is, so that we can cast the result
# back out to the same type
pixelID = img.GetPixelID()
# pad the image
img = sitk.MirrorPad( img, [128] *2, [128]*2 )
size = img.GetSize();
# perform the FFT
fftimg = sitk.ForwardFFT( sitk.Cast( img, sitk.sitkFloat32 ) )
### Kernel Image ###
# Read the kernel image file
kernel = sitk.ReadImage( kernelFileName )
# flip kernel about all axis
kernel = sitk.Flip( kernel, [True]*2 )
# normalize the kernel to sum to ~1
stats = sitk.StatisticsImageFilter();
stats.Execute( kernel )
kernel = sitk.Cast( kernel / stats.GetSum(), sitk.sitkFloat32 )
upadding = [0]*2
upadding[0] = int( math.floor( (size[0] - kernel.GetSize()[0])/2.0 ) )
upadding[1] = int( math.floor( (size[1] - kernel.GetSize()[1])/2.0 ) )
lpadding = [0]*2
lpadding[0] = int( math.ceil( (size[0] - kernel.GetSize()[0])/2.0 ) )
lpadding[1] = int( math.ceil( (size[1] - kernel.GetSize()[1])/2.0 ) )
# pad the kernel to prevent edge artifacts
kernel = sitk.ConstantPad( kernel, upadding, lpadding, 0.0 )
# perform FFT on kernel
fftkernel = sitk.ForwardFFT( sitk.FFTShift( kernel ) )
# meta-data must match for multiplication
fftkernel.SetSpacing( fftimg.GetSpacing() )
fftkernel.SetOrigin( fftimg.GetOrigin() )
fftkernel.SetDirection( fftimg.GetDirection() )
### Convolution ###
# Finally perform the convolution in Fourier space by multiplication
img = sitk.InverseFFT( fftimg*fftkernel )
# remove the padding
img = sitk.Crop( img, [128]*2, [128]*2 )
### Writing ###
# write the output image the same type as the input
sitk.WriteImage( sitk.Cast( img, pixelID ), outputFileName )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( sitk.ReadImage( inputFileName ), "original" )
sitk.Show( sitk.ReadImage( kernelFileName ), "kernel" )
sitk.Show( sitk.Cast( img, pixelID ), "FFT_Convolution" )
#=========================================================================
from __future__ import print_function
import SimpleITK as sitk
import os
import sys
if len ( sys.argv ) < 8:
print( "Usage:", sys.argv[0], " <inputImage> <outputImage> <sigma> <InitialDistance> <PropagationScaling> <seedX> <seedY> <?seedZ>" )
sys.exit ( 1 )
inputImage = sys.argv[1]
outputImage = sys.argv[2]
sigma = float(sys.argv[3])
initialDistance = float(sys.argv[4])
propagationScaling = float(sys.argv[5])
seed = [float(sys.argv[6]), float(sys.argv[7]) ]
if len( sys.argv ) > 8:
seed.append( float(sys.argv[8]) )
reader = sitk.ImageFileReader()
reader.SetFileName ( inputImage )
image = reader.Execute()
gradientMagnitude = sitk.GradientMagnitudeRecursiveGaussianImageFilter()
gradientMagnitude.SetSigma( sigma )
featureImage = sitk.BoundedReciprocal( gradientMagnitude.Execute( image ) )
seedImage = sitk.Image( image.GetSize()[0], image.GetSize()[1], sitk.sitkUInt8 )
seedImage.SetSpacing( image.GetSpacing() )
seedImage.SetOrigin( image.GetOrigin() )
seedImage.SetDirection( image.GetDirection() )
seedImage[ seedImage.TransformPhysicalPointToIndex(seed) ] = 1
distance = sitk.SignedMaurerDistanceMapImageFilter()
distance.InsideIsPositiveOff()
distance.UseImageSpacingOn()
initialImage = sitk.BinaryThreshold( distance.Execute( seedImage ), -1000, 10 )
initialImage = sitk.Cast( initialImage, featureImage.GetPixelID() ) * -1 + 0.5
geodesicActiveContour = sitk.GeodesicActiveContourLevelSetImageFilter()
geodesicActiveContour.SetPropagationScaling( propagationScaling )
geodesicActiveContour.SetCurvatureScaling( .5 )
geodesicActiveContour.SetAdvectionScaling( 1.0 )
geodesicActiveContour.SetMaximumRMSError( 0.01 )
geodesicActiveContour.SetNumberOfIterations( 1000 )
levelset = geodesicActiveContour.Execute( initialImage, featureImage )
print( "RMS Change: ", geodesicActiveContour.GetRMSChange() )
print( "Elapsed Iterations: ", geodesicActiveContour.GetElapsedIterations() )
contour = sitk.BinaryContour( sitk.BinaryThreshold( levelset, -1000, 0 ) )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( sitk.LabelOverlay( image, contour ), "Levelset Countour" )
#!/usr/bin/env python
from __future__ import print_function
import SimpleITK as sitk
import os
xImg = sitk.Image( 256, 256, sitk.sitkFloat32 )
yImg = sitk.Image( 256, 256, sitk.sitkFloat32 )
for y in range( 0, xImg.GetSize()[1] ):
for x in range( 0, xImg.GetSize()[0] ):
xImg.SetPixel( x, y, x )
yImg[x, y] = y
sigma = 50
xImg = sitk.Subtract( xImg, xImg.GetSize()[0] / 2 )
yImg = yImg - yImg.GetSize()[1] / 2
gaussianImg = sitk.Exp( -1 * (xImg**2 + yImg**2) / (2.0 * sigma**2) )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( gaussianImg, "Gaussian Blob" )
'''=========================================================================
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
#
# Check Command Line
#
if len( sys.argv ) < 7:
print( "Usage: NeighborhoodConnectedImageFilter inputImage outputImage lowerThreshold upperThreshold seedX seedY [seed2X seed2Y ... ]")
sys.exit( 1 )
#
# Read the image
#
reader = sitk.ImageFileReader()
reader.SetFileName( sys.argv[1] )
image = reader.Execute();
#
# Blur using CurvatureFlowImageFilter
#
blurFilter = sitk.CurvatureFlowImageFilter()
blurFilter.SetNumberOfIterations( 5 )
blurFilter.SetTimeStep( 0.125 )
image = blurFilter.Execute( image )
#
# Set up NeighborhoodConnectedImageFilter for segmentation
#
segmentationFilter = sitk.NeighborhoodConnectedImageFilter()
segmentationFilter.SetLower( float(sys.argv[3]) )
segmentationFilter.SetUpper( float(sys.argv[4]) )
segmentationFilter.SetReplaceValue( 255 )
radius = [2,2]
segmentationFilter.SetRadius( radius )
for i in range( 5, len(sys.argv)-1, 2 ):
seed = [int(sys.argv[i]), int(sys.argv[i+1])]
segmentationFilter.AddSeed( seed )
print( "Adding seed at: ", seed, " with intensity: ", image.GetPixel(*seed) )
# Run the segmentation filter
image = segmentationFilter.Execute( image )
#
# Write out the result
#
writer = sitk.ImageFileWriter()
writer.SetFileName( sys.argv[2] )
writer.Execute( image )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( image, "NeighborhoodConnectedThreshold" )
#!/usr/bin/env python
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
if len ( sys.argv ) != 2:
print( "Usage: %s inputImage" % ( sys.argv[0] ) )
sys.exit ( 1 )
inputImage = sitk.ReadImage( sys.argv[1] )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( inputImage )
#!/usr/bin/env python
from __future__ import print_function
import SimpleITK as sitk
import sys
import os
if len ( sys.argv ) < 4:
print( "Usage: %s <input> <sigma> <output>" % ( sys.argv[0] ) )
sys.exit ( 1 )
image = sitk.ReadImage( sys.argv[1] )
pixelID = image.GetPixelID()
image = sitk.SmoothingRecursiveGaussian( image, float( sys.argv[2] ) )
sitk.WriteImage( sitk.Cast( image, pixelID ), sys.argv[3] )
if ( not "SITK_NOSHOW" in os.environ ):
sitk.Show( sitk.Cast( image, pixelID ), "Simple Gaussian Procedural" )