0
# Registration and Transforms
1
2
Comprehensive image registration techniques and geometric transformations for aligning medical images, motion correction, and multi-modal fusion using SimpleITK.
3
4
## Capabilities
5
6
### Basic Transforms
7
8
Fundamental geometric transformations for image registration and spatial manipulation.
9
10
```python { .api }
11
def TranslationTransform(dimension: int, offset: list = None) -> Transform:
12
"""
13
Translation transform for rigid translation
14
15
Args:
16
dimension: Spatial dimension (2D or 3D)
17
offset: Translation offset [tx, ty] or [tx, ty, tz]
18
19
Returns:
20
Translation transform object
21
"""
22
23
def Euler2DTransform(center: list = [0.0, 0.0], angle: float = 0.0,
24
translation: list = [0.0, 0.0]) -> Transform:
25
"""
26
2D rigid transformation (rotation + translation)
27
28
Args:
29
center: Center of rotation [cx, cy]
30
angle: Rotation angle in radians
31
translation: Translation vector [tx, ty]
32
33
Returns:
34
2D Euler transform
35
"""
36
37
def Euler3DTransform(center: list = [0.0, 0.0, 0.0], rotation: list = [0.0, 0.0, 0.0],
38
translation: list = [0.0, 0.0, 0.0]) -> Transform:
39
"""
40
3D rigid transformation (rotation + translation)
41
42
Args:
43
center: Center of rotation [cx, cy, cz]
44
rotation: Rotation angles [rx, ry, rz] in radians
45
translation: Translation vector [tx, ty, tz]
46
47
Returns:
48
3D Euler transform
49
"""
50
51
def Similarity2DTransform(center: list = [0.0, 0.0], scale: float = 1.0,
52
angle: float = 0.0, translation: list = [0.0, 0.0]) -> Transform:
53
"""
54
2D similarity transform (scale + rotation + translation)
55
56
Args:
57
center: Center of transformation
58
scale: Uniform scaling factor
59
angle: Rotation angle in radians
60
translation: Translation vector
61
62
Returns:
63
2D similarity transform
64
"""
65
66
def Similarity3DTransform(center: list = [0.0, 0.0, 0.0], scale: float = 1.0,
67
versor: list = [0.0, 0.0, 0.0, 1.0],
68
translation: list = [0.0, 0.0, 0.0]) -> Transform:
69
"""
70
3D similarity transform with quaternion rotation
71
72
Args:
73
center: Center of transformation
74
scale: Uniform scaling factor
75
versor: Quaternion rotation [x, y, z, w]
76
translation: Translation vector
77
78
Returns:
79
3D similarity transform
80
"""
81
82
def AffineTransform(dimension: int, matrix: list = None,
83
translation: list = None) -> Transform:
84
"""
85
Affine transformation (linear + translation)
86
87
Args:
88
dimension: Spatial dimension
89
matrix: Transformation matrix (flattened)
90
translation: Translation vector
91
92
Returns:
93
Affine transform
94
"""
95
```
96
97
**Usage Examples:**
98
99
```python
100
import SimpleITK as sitk
101
import numpy as np
102
103
# Create basic transforms
104
translation = sitk.TranslationTransform(3, [10.0, 5.0, -2.0])
105
106
# 2D rigid transform
107
rigid_2d = sitk.Euler2DTransform()
108
rigid_2d.SetCenter([128.0, 128.0])
109
rigid_2d.SetAngle(np.pi / 4) # 45 degrees
110
rigid_2d.SetTranslation([20.0, -10.0])
111
112
# 3D rigid transform
113
rigid_3d = sitk.Euler3DTransform()
114
rigid_3d.SetCenter([64.0, 64.0, 32.0])
115
rigid_3d.SetRotation(np.pi/6, 0.0, np.pi/8) # Rotation around axes
116
rigid_3d.SetTranslation([5.0, -8.0, 12.0])
117
118
# Similarity transform with scaling
119
similarity = sitk.Similarity3DTransform()
120
similarity.SetScale(1.2)
121
similarity.SetCenter([100.0, 100.0, 50.0])
122
123
# Affine transform
124
affine = sitk.AffineTransform(3)
125
# Set 3x3 transformation matrix (flattened to 9 elements)
126
matrix = [1.1, 0.1, 0.0, # Scale and shear in x
127
0.0, 0.9, 0.1, # Scale and shear in y
128
0.0, 0.0, 1.0] # No change in z
129
affine.SetMatrix(matrix)
130
affine.SetTranslation([15.0, -5.0, 8.0])
131
132
print(f"Translation: {translation.GetOffset()}")
133
print(f"Rigid 2D angle: {rigid_2d.GetAngle()}")
134
print(f"Affine matrix: {affine.GetMatrix()}")
135
```
136
137
### Deformable Transforms
138
139
Non-rigid transformations for modeling complex anatomical deformations.
140
141
```python { .api }
142
def BSplineTransform(transformDomainOrigin: list, transformDomainSize: list,
143
transformDomainDirection: list, transformDomainSpacing: list,
144
order: int = 3) -> Transform:
145
"""
146
B-spline deformable transformation
147
148
Args:
149
transformDomainOrigin: Origin of transform grid
150
transformDomainSize: Size of control point grid
151
transformDomainDirection: Direction cosines matrix
152
transformDomainSpacing: Spacing between control points
153
order: B-spline order (typically 3)
154
155
Returns:
156
B-spline transform with control point grid
157
"""
158
159
def DisplacementFieldTransform(displacementField: Image) -> Transform:
160
"""
161
Dense displacement field transformation
162
163
Args:
164
displacementField: Vector image with displacement vectors
165
166
Returns:
167
Displacement field transform
168
"""
169
170
def BSplineTransformInitializer(image: Image, transformDomainMeshSize: list,
171
order: int = 3) -> Transform:
172
"""
173
Initialize B-spline transform from reference image
174
175
Args:
176
image: Reference image defining spatial domain
177
transformDomainMeshSize: Control point mesh size per dimension
178
order: B-spline order
179
180
Returns:
181
Initialized B-spline transform
182
"""
183
```
184
185
**Usage Examples:**
186
187
```python
188
import SimpleITK as sitk
189
190
# Load reference image
191
fixed_image = sitk.ReadImage('reference.nii')
192
193
# Initialize B-spline transform
194
mesh_size = [8, 8, 4] # Control point grid
195
bspline = sitk.BSplineTransformInitializer(fixed_image, mesh_size)
196
197
# Set some control point displacements
198
num_params = bspline.GetNumberOfParameters()
199
params = list(bspline.GetParameters())
200
201
# Modify some parameters (displacements)
202
for i in range(0, min(24, num_params), 3):
203
params[i] += 2.0 # x displacement
204
params[i+1] -= 1.0 # y displacement
205
params[i+2] += 0.5 # z displacement
206
207
bspline.SetParameters(params)
208
209
# Create displacement field from function
210
def displacement_function(x, y, z):
211
"""Custom displacement function"""
212
dx = 5.0 * np.sin(2 * np.pi * x / 100.0)
213
dy = 3.0 * np.cos(2 * np.pi * y / 100.0)
214
dz = 1.0 * np.sin(2 * np.pi * z / 50.0)
215
return [dx, dy, dz]
216
217
# Create displacement field image
218
size = fixed_image.GetSize()
219
displacement_field = sitk.Image(size, sitk.sitkVectorFloat64)
220
displacement_field.CopyInformation(fixed_image)
221
222
for k in range(size[2]):
223
for j in range(size[1]):
224
for i in range(size[0]):
225
point = displacement_field.TransformIndexToPhysicalPoint([i, j, k])
226
disp = displacement_function(point[0], point[1], point[2])
227
displacement_field[i, j, k] = disp
228
229
# Create displacement field transform
230
df_transform = sitk.DisplacementFieldTransform(displacement_field)
231
```
232
233
### Registration Framework
234
235
Comprehensive image registration using optimization-based alignment.
236
237
```python { .api }
238
def ImageRegistrationMethod() -> RegistrationMethod:
239
"""
240
Create image registration method for optimized alignment
241
242
Returns:
243
Registration method object for configuration
244
"""
245
246
# Metrics
247
def SetMetricAsMeanSquares() -> None:
248
"""Set mean squares similarity metric"""
249
250
def SetMetricAsCorrelation() -> None:
251
"""Set normalized correlation metric"""
252
253
def SetMetricAsMattesMutualInformation(numberOfHistogramBins: int = 50,
254
samplingPercentage: float = 0.20) -> None:
255
"""Set Mattes mutual information metric"""
256
257
def SetMetricAsJointHistogramMutualInformation(numberOfHistogramBins: int = 20,
258
varianceForJointPDFSmoothing: float = 1.5) -> None:
259
"""Set joint histogram mutual information metric"""
260
261
# Optimizers
262
def SetOptimizerAsRegularStepGradientDescent(learningRate: float = 1.0,
263
minStep: float = 1e-6,
264
numberOfIterations: int = 100,
265
gradientMagnitudeTolerance: float = 1e-8) -> None:
266
"""Set regular step gradient descent optimizer"""
267
268
def SetOptimizerAsGradientDescent(learningRate: float = 1.0,
269
numberOfIterations: int = 100,
270
convergenceMinimumValue: float = 1e-6,
271
convergenceWindowSize: int = 10) -> None:
272
"""Set gradient descent optimizer"""
273
274
def SetOptimizerAsLBFGSB(gradientConvergenceTolerance: float = 1e-5,
275
numberOfIterations: int = 500,
276
maximumNumberOfCorrections: int = 5,
277
maximumNumberOfFunctionEvaluations: int = 2000) -> None:
278
"""Set L-BFGS-B optimizer for bounded optimization"""
279
280
def SetOptimizerAsOnePlusOneEvolutionary(numberOfIterations: int = 100,
281
epsilon: float = 1.5e-4,
282
initialRadius: float = 0.0125) -> None:
283
"""Set evolutionary optimizer for global optimization"""
284
285
# Interpolators
286
def SetInterpolator(interpolator: int) -> None:
287
"""Set image interpolation method (sitkLinear, sitkBSpline, etc.)"""
288
```
289
290
**Usage Examples:**
291
292
```python
293
import SimpleITK as sitk
294
295
def registration_callback(method):
296
"""Callback to monitor registration progress"""
297
print(f"Iteration {method.GetOptimizerIteration():3d}: "
298
f"Metric = {method.GetMetricValue():8.5f}, "
299
f"Position = {method.GetOptimizerPosition()}")
300
301
# Load images
302
fixed = sitk.ReadImage('fixed.nii', sitk.sitkFloat32)
303
moving = sitk.ReadImage('moving.nii', sitk.sitkFloat32)
304
305
# Basic rigid registration
306
def rigid_registration(fixed_image, moving_image):
307
"""Perform rigid registration"""
308
309
registration = sitk.ImageRegistrationMethod()
310
311
# Similarity metric
312
registration.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
313
registration.SetMetricSamplingStrategy(registration.RANDOM)
314
registration.SetMetricSamplingPercentage(0.01)
315
316
# Optimizer
317
registration.SetOptimizerAsRegularStepGradientDescent(
318
learningRate=1.0,
319
minStep=0.001,
320
numberOfIterations=200,
321
gradientMagnitudeTolerance=1e-8
322
)
323
324
# Transform
325
initial_transform = sitk.CenteredTransformInitializer(
326
fixed_image, moving_image,
327
sitk.Euler3DTransform(),
328
sitk.CenteredTransformInitializerFilter.GEOMETRY
329
)
330
registration.SetInitialTransform(initial_transform)
331
332
# Interpolator
333
registration.SetInterpolator(sitk.sitkLinear)
334
335
# Add observer
336
registration.AddCommand(sitk.sitkIterationEvent,
337
lambda: registration_callback(registration))
338
339
# Execute registration
340
final_transform = registration.Execute(fixed_image, moving_image)
341
342
print(f"Final metric value: {registration.GetMetricValue()}")
343
print(f"Optimizer stop condition: {registration.GetOptimizerStopConditionDescription()}")
344
345
return final_transform
346
347
# Multi-modal registration
348
def multimodal_registration(fixed_image, moving_image):
349
"""Multi-modal registration using mutual information"""
350
351
registration = sitk.ImageRegistrationMethod()
352
353
# Mutual information for multi-modal images
354
registration.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
355
registration.SetMetricSamplingStrategy(registration.RANDOM)
356
registration.SetMetricSamplingPercentage(0.01)
357
358
# Multi-resolution framework
359
registration.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])
360
registration.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0])
361
registration.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
362
363
# Advanced optimizer
364
registration.SetOptimizerAsLBFGSB(
365
gradientConvergenceTolerance=1e-5,
366
numberOfIterations=500
367
)
368
369
# Initialize with moments
370
initial_transform = sitk.CenteredTransformInitializer(
371
fixed_image, moving_image,
372
sitk.Similarity3DTransform(),
373
sitk.CenteredTransformInitializerFilter.MOMENTS
374
)
375
registration.SetInitialTransform(initial_transform, inPlace=False)
376
377
# Execute registration
378
final_transform = registration.Execute(fixed_image, moving_image)
379
380
return final_transform
381
382
# Perform registrations
383
rigid_transform = rigid_registration(fixed, moving)
384
multimodal_transform = multimodal_registration(fixed, moving)
385
```
386
387
### Transform Composition and Inversion
388
389
Operations for combining and inverting transforms.
390
391
```python { .api }
392
def CompositeTransform(dimension: int) -> Transform:
393
"""
394
Composite transform for combining multiple transforms
395
396
Args:
397
dimension: Spatial dimension
398
399
Returns:
400
Composite transform container
401
"""
402
403
def InvertTransform(transform: Transform) -> Transform:
404
"""
405
Compute inverse of transform (if possible)
406
407
Args:
408
transform: Input transform to invert
409
410
Returns:
411
Inverted transform
412
"""
413
414
def ReadTransform(fileName: str) -> Transform:
415
"""
416
Read transform from file
417
418
Args:
419
fileName: Path to transform file
420
421
Returns:
422
Loaded transform object
423
"""
424
425
def WriteTransform(transform: Transform, fileName: str) -> None:
426
"""
427
Write transform to file
428
429
Args:
430
transform: Transform to save
431
fileName: Output file path
432
"""
433
```
434
435
**Usage Examples:**
436
437
```python
438
import SimpleITK as sitk
439
440
# Create composite transform
441
composite = sitk.CompositeTransform(3)
442
443
# Add multiple transforms in sequence
444
translation = sitk.TranslationTransform(3, [10, 5, 0])
445
rotation = sitk.Euler3DTransform()
446
rotation.SetRotation(0.1, 0.2, 0.0)
447
scaling = sitk.Similarity3DTransform()
448
scaling.SetScale(1.2)
449
450
composite.AddTransform(translation)
451
composite.AddTransform(rotation)
452
composite.AddTransform(scaling)
453
454
# Apply composite transform
455
transformed_point = composite.TransformPoint([100, 100, 50])
456
print(f"Transformed point: {transformed_point}")
457
458
# Invert transform (for invertible transforms)
459
try:
460
inverse_transform = sitk.InvertTransform(rotation)
461
print("Transform successfully inverted")
462
except:
463
print("Transform is not invertible")
464
465
# Save and load transforms
466
sitk.WriteTransform(composite, 'composite_transform.tfm')
467
loaded_transform = sitk.ReadTransform('composite_transform.tfm')
468
```
469
470
### Image Resampling and Transform Application
471
472
Apply transforms to resample images into new coordinate systems.
473
474
```python { .api }
475
def ResampleImageFilter() -> ResampleFilter:
476
"""Create image resampling filter"""
477
478
def Resample(image: Image, transform: Transform, interpolator: int = sitk.sitkLinear,
479
outputOrigin: list = None, outputSpacing: list = None,
480
outputSize: list = None, outputDirection: list = None,
481
defaultPixelValue: float = 0.0, outputPixelType: int = sitk.sitkUnknown,
482
useNearestNeighborExtrapolator: bool = False) -> Image:
483
"""
484
Resample image using transform
485
486
Args:
487
image: Input image to resample
488
transform: Geometric transform to apply
489
interpolator: Interpolation method
490
outputOrigin: Origin of output image space
491
outputSpacing: Spacing of output image
492
outputSize: Size of output image
493
outputDirection: Direction cosines of output image
494
defaultPixelValue: Value for pixels outside input domain
495
outputPixelType: Output pixel type
496
useNearestNeighborExtrapolator: Use NN extrapolation
497
498
Returns:
499
Resampled image
500
"""
501
```
502
503
**Usage Examples:**
504
505
```python
506
import SimpleITK as sitk
507
508
# Load images and transform
509
moving_image = sitk.ReadImage('moving.nii')
510
fixed_image = sitk.ReadImage('fixed.nii')
511
transform = sitk.ReadTransform('registration_transform.tfm')
512
513
# Basic resampling
514
resampled = sitk.Resample(moving_image, transform)
515
516
# Resample with specific output properties
517
resampled_custom = sitk.Resample(
518
moving_image,
519
fixed_image, # Use fixed image properties as reference
520
transform,
521
sitk.sitkLinear, # Linear interpolation
522
0.0, # Default pixel value
523
moving_image.GetPixelID() # Keep same pixel type
524
)
525
526
# Advanced resampling with custom parameters
527
resampler = sitk.ResampleImageFilter()
528
resampler.SetReferenceImage(fixed_image)
529
resampler.SetInterpolator(sitk.sitkBSpline)
530
resampler.SetDefaultPixelValue(0)
531
resampler.SetTransform(transform)
532
resampled_advanced = resampler.Execute(moving_image)
533
534
# Transform point coordinates
535
physical_point = [100.0, 150.0, 75.0]
536
transformed_point = transform.TransformPoint(physical_point)
537
print(f"Point {physical_point} -> {transformed_point}")
538
539
# Transform multiple points
540
points = [[50, 50, 25], [100, 100, 50], [150, 150, 75]]
541
transformed_points = [transform.TransformPoint(p) for p in points]
542
```
543
544
### Multi-Resolution Registration
545
546
Hierarchical registration for robust alignment of large deformations.
547
548
```python { .api }
549
def SetShrinkFactorsPerLevel(shrinkFactors: list) -> None:
550
"""Set image downsampling factors per resolution level"""
551
552
def SetSmoothingSigmasPerLevel(smoothingSigmas: list) -> None:
553
"""Set Gaussian smoothing per resolution level"""
554
555
def SmoothingSigmasAreSpecifiedInPhysicalUnitsOn() -> None:
556
"""Specify smoothing in physical units (mm)"""
557
558
def SmoothingSigmasAreSpecifiedInPhysicalUnitsOff() -> None:
559
"""Specify smoothing in voxel units"""
560
```
561
562
**Usage Examples:**
563
564
```python
565
import SimpleITK as sitk
566
567
def multiresolution_registration(fixed, moving):
568
"""Multi-resolution registration example"""
569
570
registration = sitk.ImageRegistrationMethod()
571
572
# Multi-resolution pyramid
573
registration.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])
574
registration.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0])
575
registration.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
576
577
# Metric
578
registration.SetMetricAsMattesMutualInformation(50)
579
registration.SetMetricSamplingStrategy(registration.RANDOM)
580
registration.SetMetricSamplingPercentage(0.01)
581
582
# Optimizer with decreasing learning rate
583
registration.SetOptimizerAsRegularStepGradientDescent(
584
learningRate=2.0,
585
minStep=0.001,
586
numberOfIterations=100
587
)
588
registration.SetOptimizerScalesFromPhysicalShift()
589
590
# Transform initialization
591
initial_transform = sitk.CenteredTransformInitializer(
592
fixed, moving,
593
sitk.Euler3DTransform(),
594
sitk.CenteredTransformInitializerFilter.GEOMETRY
595
)
596
registration.SetInitialTransform(initial_transform)
597
598
# Callbacks for each level
599
def level_callback():
600
level = registration.GetCurrentLevel()
601
print(f"Starting level {level}")
602
603
def iteration_callback():
604
if registration.GetOptimizerIteration() % 10 == 0:
605
print(f"Level {registration.GetCurrentLevel()}, "
606
f"Iteration {registration.GetOptimizerIteration()}: "
607
f"Metric = {registration.GetMetricValue()}")
608
609
registration.AddCommand(sitk.sitkMultiResolutionIterationEvent, level_callback)
610
registration.AddCommand(sitk.sitkIterationEvent, iteration_callback)
611
612
# Execute registration
613
final_transform = registration.Execute(fixed, moving)
614
615
return final_transform
616
617
# Apply multi-resolution registration
618
fixed = sitk.ReadImage('fixed.nii')
619
moving = sitk.ReadImage('moving.nii')
620
result_transform = multiresolution_registration(fixed, moving)
621
```
622
623
## Advanced Registration Patterns
624
625
### Deformable Registration Workflow
626
627
```python
628
import SimpleITK as sitk
629
630
def deformable_registration_workflow(fixed_image, moving_image):
631
"""Complete deformable registration workflow"""
632
633
# Step 1: Rigid registration
634
rigid_reg = sitk.ImageRegistrationMethod()
635
rigid_reg.SetMetricAsMattesMutualInformation(50)
636
rigid_reg.SetOptimizerAsRegularStepGradientDescent(1.0, 0.001, 200)
637
638
initial_rigid = sitk.CenteredTransformInitializer(
639
fixed_image, moving_image, sitk.Euler3DTransform(),
640
sitk.CenteredTransformInitializerFilter.GEOMETRY
641
)
642
rigid_reg.SetInitialTransform(initial_rigid)
643
rigid_reg.SetInterpolator(sitk.sitkLinear)
644
645
rigid_transform = rigid_reg.Execute(fixed_image, moving_image)
646
647
# Step 2: Apply rigid transform to moving image
648
rigid_resampled = sitk.Resample(moving_image, fixed_image, rigid_transform,
649
sitk.sitkLinear, 0.0, moving_image.GetPixelID())
650
651
# Step 3: Affine registration
652
affine_reg = sitk.ImageRegistrationMethod()
653
affine_reg.SetMetricAsMattesMutualInformation(50)
654
affine_reg.SetOptimizerAsLBFGSB(gradientConvergenceTolerance=1e-5,
655
numberOfIterations=200)
656
657
# Initialize affine with rigid result
658
affine_transform = sitk.AffineTransform(3)
659
affine_transform.SetMatrix(rigid_transform.GetMatrix())
660
affine_transform.SetTranslation(rigid_transform.GetTranslation())
661
affine_transform.SetCenter(rigid_transform.GetCenter())
662
663
affine_reg.SetInitialTransform(affine_transform, inPlace=False)
664
affine_reg.SetInterpolator(sitk.sitkLinear)
665
666
affine_result = affine_reg.Execute(fixed_image, rigid_resampled)
667
668
# Step 4: B-spline deformable registration
669
bspline_reg = sitk.ImageRegistrationMethod()
670
671
# Initialize B-spline transform
672
mesh_size = [6, 6, 4]
673
bspline_transform = sitk.BSplineTransformInitializer(fixed_image, mesh_size)
674
675
bspline_reg.SetInitialTransform(bspline_transform, inPlace=True)
676
bspline_reg.SetMetricAsMattesMutualInformation(50)
677
bspline_reg.SetOptimizerAsLBFGSB(gradientConvergenceTolerance=1e-5,
678
numberOfIterations=300)
679
bspline_reg.SetInterpolator(sitk.sitkLinear)
680
681
# Multi-resolution for B-spline
682
bspline_reg.SetShrinkFactorsPerLevel([4, 2, 1])
683
bspline_reg.SetSmoothingSigmasPerLevel([2, 1, 0])
684
685
# Apply affine transform to moving image first
686
affine_resampled = sitk.Resample(rigid_resampled, fixed_image, affine_result,
687
sitk.sitkLinear, 0.0)
688
689
bspline_result = bspline_reg.Execute(fixed_image, affine_resampled)
690
691
# Step 5: Compose all transforms
692
composite = sitk.CompositeTransform(3)
693
composite.AddTransform(rigid_transform)
694
composite.AddTransform(affine_result)
695
composite.AddTransform(bspline_result)
696
697
return composite, {
698
'rigid': rigid_transform,
699
'affine': affine_result,
700
'bspline': bspline_result
701
}
702
703
# Apply complete deformable registration
704
fixed = sitk.ReadImage('fixed_image.nii')
705
moving = sitk.ReadImage('moving_image.nii')
706
707
final_transform, intermediate_transforms = deformable_registration_workflow(fixed, moving)
708
709
# Apply final transform
710
final_result = sitk.Resample(moving, fixed, final_transform, sitk.sitkLinear)
711
sitk.WriteImage(final_result, 'deformable_registration_result.nii')
712
```
713
714
### Landmark-Based Registration
715
716
```python
717
import SimpleITK as sitk
718
import numpy as np
719
720
def landmark_based_registration(fixed_landmarks, moving_landmarks):
721
"""Registration based on corresponding landmark points"""
722
723
# Convert landmarks to SimpleITK format
724
fixed_points = sitk.VectorDouble()
725
moving_points = sitk.VectorDouble()
726
727
for fp, mp in zip(fixed_landmarks, moving_landmarks):
728
for coord in fp:
729
fixed_points.append(coord)
730
for coord in mp:
731
moving_points.append(coord)
732
733
# Landmark-based transform estimation
734
landmark_transform = sitk.LandmarkBasedTransformInitializer(
735
sitk.Similarity3DTransform(),
736
fixed_points,
737
moving_points
738
)
739
740
return landmark_transform
741
742
# Example landmark coordinates
743
fixed_landmarks = [
744
[100.0, 150.0, 75.0], # Landmark 1
745
[200.0, 100.0, 80.0], # Landmark 2
746
[150.0, 200.0, 70.0], # Landmark 3
747
]
748
749
moving_landmarks = [
750
[105.0, 145.0, 78.0], # Corresponding landmark 1
751
[195.0, 105.0, 75.0], # Corresponding landmark 2
752
[155.0, 195.0, 72.0], # Corresponding landmark 3
753
]
754
755
landmark_transform = landmark_based_registration(fixed_landmarks, moving_landmarks)
756
```
757
758
## Performance and Optimization
759
760
### GPU-Accelerated Registration
761
762
```python
763
import SimpleITK as sitk
764
765
# Enable GPU acceleration (if available)
766
def setup_gpu_registration():
767
"""Configure registration for GPU acceleration"""
768
769
# Check for GPU support
770
if sitk.ProcessObject.GetGlobalDefaultNumberOfThreads() > 1:
771
print("Multi-threading available")
772
773
# Set number of threads for CPU optimization
774
sitk.ProcessObject.SetGlobalDefaultNumberOfThreads(8)
775
776
registration = sitk.ImageRegistrationMethod()
777
778
# Use GPU-optimized metrics if available
779
registration.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
780
781
# Optimize sampling for GPU
782
registration.SetMetricSamplingStrategy(registration.RANDOM)
783
registration.SetMetricSamplingPercentage(0.05) # Higher sampling for GPU
784
785
return registration
786
```
787
788
### Memory-Efficient Large Image Registration
789
790
```python
791
import SimpleITK as sitk
792
793
def large_image_registration(fixed_path, moving_path, output_path):
794
"""Memory-efficient registration for large images"""
795
796
# Read image metadata without loading full images
797
fixed_reader = sitk.ImageFileReader()
798
fixed_reader.SetFileName(fixed_path)
799
fixed_reader.ReadImageInformation()
800
801
moving_reader = sitk.ImageFileReader()
802
moving_reader.SetFileName(moving_path)
803
moving_reader.ReadImageInformation()
804
805
# Determine appropriate downsampling
806
fixed_size = fixed_reader.GetSize()
807
max_dimension = max(fixed_size)
808
809
if max_dimension > 1024:
810
downsample_factor = max_dimension // 512
811
812
# Create downsampled versions for registration
813
fixed_small = sitk.Shrink(sitk.ReadImage(fixed_path),
814
[downsample_factor] * 3)
815
moving_small = sitk.Shrink(sitk.ReadImage(moving_path),
816
[downsample_factor] * 3)
817
818
# Register downsampled images
819
registration = sitk.ImageRegistrationMethod()
820
registration.SetMetricAsMattesMutualInformation(50)
821
registration.SetOptimizerAsLBFGSB(numberOfIterations=100)
822
823
initial_transform = sitk.CenteredTransformInitializer(
824
fixed_small, moving_small, sitk.Similarity3DTransform(),
825
sitk.CenteredTransformInitializerFilter.GEOMETRY
826
)
827
registration.SetInitialTransform(initial_transform)
828
829
coarse_transform = registration.Execute(fixed_small, moving_small)
830
831
# Scale transform parameters for full resolution
832
scaled_transform = sitk.Similarity3DTransform()
833
scaled_transform.SetMatrix(coarse_transform.GetMatrix())
834
835
# Scale translation by downsample factor
836
translation = coarse_transform.GetTranslation()
837
scaled_translation = [t * downsample_factor for t in translation]
838
scaled_transform.SetTranslation(scaled_translation)
839
840
# Scale center by downsample factor
841
center = coarse_transform.GetCenter()
842
scaled_center = [c * downsample_factor for c in center]
843
scaled_transform.SetCenter(scaled_center)
844
845
return scaled_transform
846
847
else:
848
# Direct registration for smaller images
849
fixed = sitk.ReadImage(fixed_path)
850
moving = sitk.ReadImage(moving_path)
851
852
registration = sitk.ImageRegistrationMethod()
853
# ... standard registration setup ...
854
855
return registration.Execute(fixed, moving)
856
```
857
858
## Type Definitions
859
860
```python { .api }
861
# Core Types
862
Transform = sitk.Transform
863
"""Base class for all geometric transforms"""
864
865
Image = sitk.Image
866
"""SimpleITK Image object"""
867
868
RegistrationMethod = sitk.ImageRegistrationMethod
869
"""Image registration framework object"""
870
871
ResampleFilter = sitk.ResampleImageFilter
872
"""Image resampling filter"""
873
874
# Transform Types
875
TranslationTransform = sitk.TranslationTransform
876
"""Translation-only transform"""
877
878
Euler2DTransform = sitk.Euler2DTransform
879
"""2D rigid transform (rotation + translation)"""
880
881
Euler3DTransform = sitk.Euler3DTransform
882
"""3D rigid transform (rotation + translation)"""
883
884
Similarity2DTransform = sitk.Similarity2DTransform
885
"""2D similarity transform (scale + rotation + translation)"""
886
887
Similarity3DTransform = sitk.Similarity3DTransform
888
"""3D similarity transform (scale + rotation + translation)"""
889
890
AffineTransform = sitk.AffineTransform
891
"""Affine transform (linear transformation + translation)"""
892
893
BSplineTransform = sitk.BSplineTransform
894
"""B-spline deformable transform"""
895
896
CompositeTransform = sitk.CompositeTransform
897
"""Container for multiple transforms"""
898
899
# Parameter Types
900
TransformParameters = list[float]
901
"""Transform parameter vector"""
902
903
PhysicalPoint = list[float]
904
"""3D physical coordinate point [x, y, z]"""
905
906
LandmarkPoint = list[float]
907
"""Landmark coordinate [x, y, z]"""
908
909
LandmarkSet = list[LandmarkPoint]
910
"""Collection of corresponding landmarks"""
911
912
# Registration Parameter Types
913
MetricValue = float
914
"""Registration metric value (similarity measure)"""
915
916
OptimizerPosition = list[float]
917
"""Current optimizer parameter values"""
918
919
ShrinkFactors = list[int]
920
"""Downsampling factors per resolution level"""
921
922
SmoothingSigmas = list[float]
923
"""Gaussian smoothing per resolution level"""
924
925
# Interpolation Types
926
InterpolatorEnum = int
927
"""Interpolation method identifier (sitkLinear, sitkBSpline, etc.)"""
928
```