Insight Toolkit for N-dimensional image processing, segmentation, and registration in medical and scientific applications
—
This guide will get you up and running with ITK in minutes.
pip install itk# Install with specific image I/O support
pip install itk[io]
# Install with registration support
pip install itk[registration]
# Install everything
pip install itk[all]import itk
print(f"ITK version: {itk.Version.GetITKVersion()}")import itk
# Read an image
image = itk.imread('input.png', itk.F)
# Get image properties
print(f"Size: {itk.size(image)}")
print(f"Spacing: {itk.spacing(image)}")
print(f"Origin: {itk.origin(image)}")
# Get intensity range
min_val, max_val = itk.image_intensity_min_max(image)
print(f"Intensity range: [{min_val}, {max_val}]")import itk
# Read image
image = itk.imread('noisy.png', itk.F)
# Apply median filter to reduce noise
smoothed = itk.median_image_filter(image, radius=2)
# Save result
itk.imwrite(smoothed, 'smoothed.png')import itk
import numpy as np
# Read image
image = itk.imread('input.png', itk.F)
# Convert to NumPy array
array = itk.array_from_image(image)
# Process with NumPy
processed = array * 2.0
processed = np.clip(processed, 0, 255)
# Convert back to ITK
result = itk.image_from_array(processed)
# Preserve metadata
result.SetSpacing(image.GetSpacing())
result.SetOrigin(image.GetOrigin())
result.SetDirection(image.GetDirection())
# Save
itk.imwrite(result, 'output.png')ITK uses strongly-typed images. Common type shortcuts:
from itk import F, D, UC, US, UI # float, double, unsigned char/short/int
# Read with specific type
image_float = itk.imread('input.png', itk.F) # 32-bit float
image_uchar = itk.imread('input.png', itk.UC) # 8-bit unsignedITK uses lazy evaluation - filters don't execute until needed:
import itk
image = itk.imread('input.png', itk.F)
# Create filters (no execution yet)
median = itk.MedianImageFilter.New(image)
median.SetRadius(2)
gradient = itk.GradientMagnitudeImageFilter.New(median)
# Execute entire pipeline with single Update()
gradient.Update()
result = gradient.GetOutput()ITK provides convenient function-style wrappers:
# Function style (automatic type deduction)
result = itk.median_image_filter(image, radius=2)
# Equivalent class-based approach
ImageType = itk.Image[itk.F, 2]
filter = itk.MedianImageFilter[ImageType, ImageType].New()
filter.SetInput(image)
filter.SetRadius(2)
filter.Update()
result = filter.GetOutput()import itk
# Simple read (automatic type detection)
image = itk.imread('input.png')
# Read with specific pixel type
image = itk.imread('input.png', itk.F)
# Read DICOM series
image = itk.imread('/path/to/dicom/series/')
# Read specific DICOM series by index
image = itk.imread('/path/to/dicom/', series_uid=0)import itk
# Simple write
itk.imwrite(image, 'output.png')
# Write with compression
itk.imwrite(image, 'output.nii.gz', compression=True)
# Write filter output directly (no intermediate variable)
smoothed = itk.median_image_filter(image, radius=2)
itk.imwrite(smoothed, 'smoothed.png')import itk
image = itk.imread('input.png', itk.F)
# Smoothing
smoothed = itk.median_image_filter(image, radius=2)
gaussian = itk.discrete_gaussian_image_filter(image, variance=2.0)
bilateral = itk.bilateral_image_filter(image, domain_sigma=4.0, range_sigma=50.0)
# Edge detection
edges = itk.canny_edge_detection_image_filter(image, variance=2.0)
gradient = itk.gradient_magnitude_image_filter(image)
# Thresholding
binary = itk.binary_threshold_image_filter(image, lower_threshold=100, upper_threshold=200)
otsu = itk.otsu_threshold_image_filter(image)
# Morphology
eroded = itk.binary_erode_image_filter(binary, radius=2)
dilated = itk.binary_dilate_image_filter(binary, radius=2)import itk
image = itk.imread('input.png', itk.F)
# Define seed point
seed = itk.Index[2]()
seed[0] = 100
seed[1] = 100
# Region growing
segmented = itk.connected_threshold_image_filter(
image,
seed=seed,
lower=50.0,
upper=150.0,
replace_value=255
)
itk.imwrite(segmented, 'segmented.png')Always wrap I/O operations in try-except blocks:
import itk
try:
image = itk.imread('input.png', itk.F)
except RuntimeError as e:
print(f"Error reading image: {e}")
exit(1)
try:
itk.imwrite(image, 'output.png')
except RuntimeError as e:
print(f"Error writing image: {e}")
exit(1)import itk
# Use all available cores
itk.set_nthreads(0)
# Or set specific number
itk.set_nthreads(8)
# Check current setting
n_threads = itk.get_nthreads()
print(f"Using {n_threads} threads")import itk
# Enable progress reporting
itk.auto_progress(True)
# Now long operations will show progress
image = itk.imread('large_image.nii.gz', itk.F)
smoothed = itk.median_image_filter(image, radius=5)import itk
image = itk.imread('large_image.nii.gz', itk.F)
# Use view (shared memory) instead of copy
array_view = itk.array_view_from_image(image) # No copy
array_copy = itk.array_from_image(image) # Copies data
# Modify view (modifies image directly)
array_view *= 0.5
# Image is now modified
itk.imwrite(image, 'modified.nii.gz')# ❌ Wrong: Types don't match
ImageType2D = itk.Image[itk.F, 2]
ImageType3D = itk.Image[itk.F, 3]
filter = itk.MedianImageFilter[ImageType2D, ImageType3D].New() # Error!
# ✅ Correct: Input and output types match
filter = itk.MedianImageFilter[ImageType2D, ImageType2D].New()# ❌ Wrong: Filter not executed
filter = itk.MedianImageFilter.New(image)
result = filter.GetOutput() # Empty/invalid
# ✅ Correct: Call Update() first
filter = itk.MedianImageFilter.New(image)
filter.Update()
result = filter.GetOutput()
# ✅ Or use convenience function (auto-updates)
result = itk.median_image_filter(image, radius=2)# ❌ Wrong: Metadata lost
array = itk.array_from_image(image)
processed = array * 2.0
result = itk.image_from_array(processed) # No spacing/origin!
# ✅ Correct: Preserve metadata
array = itk.array_from_image(image)
processed = array * 2.0
result = itk.image_from_array(processed)
result.SetSpacing(image.GetSpacing())
result.SetOrigin(image.GetOrigin())
result.SetDirection(image.GetDirection())Install with Tessl CLI
npx tessl i tessl/pypi-itkdocs
guides
reference