0
# Transforms
1
2
Geometric transformation classes for image registration, spatial alignment, and coordinate system manipulation. SimpleITK provides a comprehensive set of transformation types from simple rigid transformations to complex deformable transforms, with parameter optimization and inverse computation capabilities.
3
4
## Capabilities
5
6
### Base Transform Class
7
8
All transforms inherit from the base Transform class which provides common functionality.
9
10
```python { .api }
11
class Transform:
12
def __init__(self, dimension: int = 3, transformType: str = ""):
13
"""
14
Initialize transform.
15
16
Args:
17
dimension: Spatial dimension (2 or 3)
18
transformType: Specific transform type name
19
"""
20
21
def GetParameters(self) -> tuple:
22
"""Get transform parameters as tuple"""
23
24
def SetParameters(self, parameters: tuple):
25
"""
26
Set transform parameters.
27
28
Args:
29
parameters: Parameter values as tuple
30
"""
31
32
def GetFixedParameters(self) -> tuple:
33
"""Get fixed parameters (e.g., center of rotation)"""
34
35
def SetFixedParameters(self, parameters: tuple):
36
"""Set fixed parameters"""
37
38
def GetNumberOfParameters(self) -> int:
39
"""Get number of parameters"""
40
41
def GetNumberOfFixedParameters(self) -> int:
42
"""Get number of fixed parameters"""
43
44
def TransformPoint(self, point: tuple) -> tuple:
45
"""
46
Transform a single point.
47
48
Args:
49
point: Input point coordinates as tuple
50
51
Returns:
52
Transformed point coordinates
53
"""
54
55
def GetInverse(self) -> Transform:
56
"""
57
Get inverse transform.
58
59
Returns:
60
Inverse transform object
61
62
Raises:
63
Exception if transform is not invertible
64
"""
65
66
def SetIdentity(self):
67
"""Set transform to identity"""
68
69
def GetDimension(self) -> int:
70
"""Get spatial dimension"""
71
72
def GetTransformEnum(self) -> int:
73
"""Get transform type enumeration"""
74
75
def GetName(self) -> str:
76
"""Get transform name"""
77
```
78
79
### Translation Transform
80
81
Pure translation without rotation or scaling.
82
83
```python { .api }
84
class TranslationTransform(Transform):
85
def __init__(self, dimension: int = 3):
86
"""
87
Initialize translation transform.
88
89
Args:
90
dimension: Spatial dimension (2 or 3)
91
"""
92
93
def SetOffset(self, offset: tuple):
94
"""
95
Set translation offset.
96
97
Args:
98
offset: Translation vector
99
"""
100
101
def GetOffset(self) -> tuple:
102
"""Get translation offset"""
103
```
104
105
### Rigid Transforms
106
107
Rotation and translation without scaling or shearing.
108
109
```python { .api }
110
class Euler2DTransform(Transform):
111
def __init__(self):
112
"""Initialize 2D rigid transform with rotation and translation"""
113
114
def SetAngle(self, angle: float):
115
"""Set rotation angle in radians"""
116
117
def GetAngle(self) -> float:
118
"""Get rotation angle in radians"""
119
120
def SetTranslation(self, translation: tuple):
121
"""Set translation vector"""
122
123
def GetTranslation(self) -> tuple:
124
"""Get translation vector"""
125
126
def SetCenter(self, center: tuple):
127
"""Set center of rotation"""
128
129
def GetCenter(self) -> tuple:
130
"""Get center of rotation"""
131
132
class Euler3DTransform(Transform):
133
def __init__(self):
134
"""Initialize 3D rigid transform with rotation and translation"""
135
136
def SetRotation(self, angleX: float, angleY: float, angleZ: float):
137
"""
138
Set rotation angles around X, Y, Z axes.
139
140
Args:
141
angleX: Rotation around X-axis in radians
142
angleY: Rotation around Y-axis in radians
143
angleZ: Rotation around Z-axis in radians
144
"""
145
146
def GetAngleX(self) -> float:
147
"""Get rotation around X-axis"""
148
149
def GetAngleY(self) -> float:
150
"""Get rotation around Y-axis"""
151
152
def GetAngleZ(self) -> float:
153
"""Get rotation around Z-axis"""
154
155
def SetTranslation(self, translation: tuple):
156
"""Set translation vector"""
157
158
def GetTranslation(self) -> tuple:
159
"""Get translation vector"""
160
161
def SetCenter(self, center: tuple):
162
"""Set center of rotation"""
163
164
def GetCenter(self) -> tuple:
165
"""Get center of rotation"""
166
167
class VersorTransform(Transform):
168
def __init__(self):
169
"""3D rotation using versor (unit quaternion) representation"""
170
171
def SetRotation(self, versor: tuple):
172
"""
173
Set rotation using versor (unit quaternion).
174
175
Args:
176
versor: Versor as (x, y, z, w) tuple
177
"""
178
179
def GetVersor(self) -> tuple:
180
"""Get versor representation"""
181
182
def SetCenter(self, center: tuple):
183
"""Set center of rotation"""
184
185
def GetCenter(self) -> tuple:
186
"""Get center of rotation"""
187
188
class VersorRigid3DTransform(Transform):
189
def __init__(self):
190
"""3D rigid transform using versor for rotation"""
191
192
def SetRotation(self, versor: tuple):
193
"""Set rotation using versor"""
194
195
def GetVersor(self) -> tuple:
196
"""Get versor representation"""
197
198
def SetTranslation(self, translation: tuple):
199
"""Set translation vector"""
200
201
def GetTranslation(self) -> tuple:
202
"""Get translation vector"""
203
204
def SetCenter(self, center: tuple):
205
"""Set center of rotation"""
206
207
def GetCenter(self) -> tuple:
208
"""Get center of rotation"""
209
```
210
211
### Similarity Transforms
212
213
Uniform scaling, rotation, and translation.
214
215
```python { .api }
216
class Similarity2DTransform(Transform):
217
def __init__(self):
218
"""2D similarity transform (rotation, uniform scaling, translation)"""
219
220
def SetScale(self, scale: float):
221
"""Set uniform scaling factor"""
222
223
def GetScale(self) -> float:
224
"""Get scaling factor"""
225
226
def SetAngle(self, angle: float):
227
"""Set rotation angle in radians"""
228
229
def GetAngle(self) -> float:
230
"""Get rotation angle"""
231
232
def SetTranslation(self, translation: tuple):
233
"""Set translation vector"""
234
235
def GetTranslation(self) -> tuple:
236
"""Get translation vector"""
237
238
def SetCenter(self, center: tuple):
239
"""Set center of transformation"""
240
241
def GetCenter(self) -> tuple:
242
"""Get center of transformation"""
243
244
class Similarity3DTransform(Transform):
245
def __init__(self):
246
"""3D similarity transform"""
247
248
def SetScale(self, scale: float):
249
"""Set uniform scaling factor"""
250
251
def GetScale(self) -> float:
252
"""Get scaling factor"""
253
254
def SetRotation(self, versor: tuple):
255
"""Set rotation using versor"""
256
257
def GetVersor(self) -> tuple:
258
"""Get versor representation"""
259
260
def SetTranslation(self, translation: tuple):
261
"""Set translation vector"""
262
263
def GetTranslation(self) -> tuple:
264
"""Get translation vector"""
265
266
def SetCenter(self, center: tuple):
267
"""Set center of transformation"""
268
269
def GetCenter(self) -> tuple:
270
"""Get center of transformation"""
271
272
class ScaleVersor3DTransform(Transform):
273
def __init__(self):
274
"""3D transform with non-uniform scaling and versor rotation"""
275
276
def SetScale(self, scale: tuple):
277
"""
278
Set non-uniform scaling factors.
279
280
Args:
281
scale: Scaling factors for (x, y, z) axes
282
"""
283
284
def GetScale(self) -> tuple:
285
"""Get scaling factors"""
286
287
def SetRotation(self, versor: tuple):
288
"""Set rotation using versor"""
289
290
def GetVersor(self) -> tuple:
291
"""Get versor representation"""
292
293
def SetTranslation(self, translation: tuple):
294
"""Set translation vector"""
295
296
def GetTranslation(self) -> tuple:
297
"""Get translation vector"""
298
299
def SetCenter(self, center: tuple):
300
"""Set center of transformation"""
301
302
def GetCenter(self) -> tuple:
303
"""Get center of transformation"""
304
```
305
306
### Affine Transform
307
308
General linear transformation including scaling, shearing, rotation, and translation.
309
310
```python { .api }
311
class AffineTransform(Transform):
312
def __init__(self, dimension: int = 3):
313
"""
314
Initialize affine transform.
315
316
Args:
317
dimension: Spatial dimension (2 or 3)
318
"""
319
320
def SetMatrix(self, matrix: tuple):
321
"""
322
Set transformation matrix (without translation).
323
324
Args:
325
matrix: Matrix elements as flat tuple (row-major order)
326
"""
327
328
def GetMatrix(self) -> tuple:
329
"""Get transformation matrix"""
330
331
def SetTranslation(self, translation: tuple):
332
"""Set translation vector"""
333
334
def GetTranslation(self) -> tuple:
335
"""Get translation vector"""
336
337
def SetCenter(self, center: tuple):
338
"""Set center of transformation"""
339
340
def GetCenter(self) -> tuple:
341
"""Get center of transformation"""
342
343
def Translate(self, offset: tuple):
344
"""Apply additional translation"""
345
346
def Scale(self, factor: float, pre: bool = False):
347
"""
348
Apply uniform scaling.
349
350
Args:
351
factor: Scaling factor
352
pre: Apply before (True) or after (False) current transform
353
"""
354
355
def Rotate2D(self, angle: float, pre: bool = False):
356
"""Apply 2D rotation (2D transforms only)"""
357
358
def Rotate3D(self, axis: tuple, angle: float, pre: bool = False):
359
"""Apply 3D rotation around axis (3D transforms only)"""
360
361
def Shear(self, axis1: int, axis2: int, coeff: float, pre: bool = False):
362
"""
363
Apply shearing transformation.
364
365
Args:
366
axis1: First axis index
367
axis2: Second axis index
368
coeff: Shearing coefficient
369
pre: Apply before (True) or after (False) current transform
370
"""
371
```
372
373
### Scale Transform
374
375
Non-uniform scaling transformation.
376
377
```python { .api }
378
class ScaleTransform(Transform):
379
def __init__(self, dimension: int = 3):
380
"""
381
Initialize scale transform.
382
383
Args:
384
dimension: Spatial dimension (2 or 3)
385
"""
386
387
def SetScale(self, scale: tuple):
388
"""
389
Set scaling factors for each axis.
390
391
Args:
392
scale: Scaling factors as tuple
393
"""
394
395
def GetScale(self) -> tuple:
396
"""Get scaling factors"""
397
398
def SetCenter(self, center: tuple):
399
"""Set center of scaling"""
400
401
def GetCenter(self) -> tuple:
402
"""Get center of scaling"""
403
```
404
405
### Deformable Transforms
406
407
Non-linear transformations for complex deformations.
408
409
```python { .api }
410
class BSplineTransform(Transform):
411
def __init__(self, dimension: int = 3, splineOrder: int = 3):
412
"""
413
Initialize B-spline deformable transform.
414
415
Args:
416
dimension: Spatial dimension (2 or 3)
417
splineOrder: B-spline order (typically 3 for cubic)
418
"""
419
420
def SetTransformDomainOrigin(self, origin: tuple):
421
"""Set origin of transform domain"""
422
423
def GetTransformDomainOrigin(self) -> tuple:
424
"""Get origin of transform domain"""
425
426
def SetTransformDomainPhysicalDimensions(self, dimensions: tuple):
427
"""Set physical size of transform domain"""
428
429
def GetTransformDomainPhysicalDimensions(self) -> tuple:
430
"""Get physical size of transform domain"""
431
432
def SetTransformDomainMeshSize(self, meshSize: tuple):
433
"""
434
Set mesh size (number of control points - 1).
435
436
Args:
437
meshSize: Mesh size in each dimension
438
"""
439
440
def GetTransformDomainMeshSize(self) -> tuple:
441
"""Get mesh size"""
442
443
def SetTransformDomainDirection(self, direction: tuple):
444
"""Set direction matrix of transform domain"""
445
446
def GetTransformDomainDirection(self) -> tuple:
447
"""Get direction matrix of transform domain"""
448
449
def GetCoefficientImages(self) -> list:
450
"""
451
Get coefficient images as list of Image objects.
452
453
Returns:
454
List of coefficient images (one per dimension)
455
"""
456
457
def SetCoefficientImages(self, images: list):
458
"""
459
Set coefficient images.
460
461
Args:
462
images: List of coefficient images (one per dimension)
463
"""
464
465
class DisplacementFieldTransform(Transform):
466
def __init__(self, dimension: int = 3):
467
"""
468
Initialize displacement field transform.
469
470
Args:
471
dimension: Spatial dimension (2 or 3)
472
"""
473
474
def SetDisplacementField(self, field: Image):
475
"""
476
Set displacement field image.
477
478
Args:
479
field: Vector image containing displacement vectors
480
"""
481
482
def GetDisplacementField(self) -> Image:
483
"""Get displacement field image"""
484
485
def SetInverseDisplacementField(self, field: Image):
486
"""Set inverse displacement field for inverse transforms"""
487
488
def GetInverseDisplacementField(self) -> Image:
489
"""Get inverse displacement field"""
490
491
def SetInterpolator(self, interpolator: int):
492
"""Set interpolation method for field sampling"""
493
494
def GetInterpolator(self) -> int:
495
"""Get interpolation method"""
496
```
497
498
### Transform I/O
499
500
Functions for reading and writing transforms to/from files.
501
502
```python { .api }
503
def ReadTransform(filename: str) -> Transform:
504
"""
505
Read transform from file.
506
507
Args:
508
filename: Path to transform file (.txt, .tfm, .h5, .mat)
509
510
Returns:
511
Transform object
512
"""
513
514
def WriteTransform(transform: Transform, filename: str):
515
"""
516
Write transform to file.
517
518
Args:
519
transform: Transform object to write
520
filename: Output file path
521
"""
522
```
523
524
### Transform Composition
525
526
Combine multiple transforms into composite transformations.
527
528
```python { .api }
529
class CompositeTransform(Transform):
530
def __init__(self, dimension: int = 3):
531
"""
532
Initialize composite transform.
533
534
Args:
535
dimension: Spatial dimension
536
"""
537
538
def AddTransform(self, transform: Transform):
539
"""
540
Add transform to composition.
541
542
Args:
543
transform: Transform to add (applied last)
544
"""
545
546
def GetNumberOfTransforms(self) -> int:
547
"""Get number of transforms in composition"""
548
549
def GetNthTransform(self, n: int) -> Transform:
550
"""
551
Get nth transform in composition.
552
553
Args:
554
n: Transform index (0-based)
555
556
Returns:
557
Transform at index n
558
"""
559
560
def RemoveTransform(self):
561
"""Remove last transform from composition"""
562
563
def ClearTransformQueue(self):
564
"""Remove all transforms from composition"""
565
566
def FlattenTransformQueue(self) -> Transform:
567
"""
568
Flatten composition into equivalent single transform if possible.
569
570
Returns:
571
Flattened transform or composite if flattening not possible
572
"""
573
```
574
575
### Usage Examples
576
577
#### Basic Transform Operations
578
579
```python
580
import SimpleITK as sitk
581
582
# Create 3D translation
583
translation = sitk.TranslationTransform(3)
584
translation.SetOffset([10.0, 5.0, -2.0])
585
586
# Transform a point
587
point = [100.0, 150.0, 75.0]
588
transformed_point = translation.TransformPoint(point)
589
print(f"Original: {point}")
590
print(f"Transformed: {transformed_point}")
591
592
# Get inverse transform
593
inverse_translation = translation.GetInverse()
594
back_to_original = inverse_translation.TransformPoint(transformed_point)
595
print(f"Back to original: {back_to_original}")
596
```
597
598
#### Rigid Transform Setup
599
600
```python
601
import SimpleITK as sitk
602
import math
603
604
# Create 3D rigid transform
605
rigid = sitk.Euler3DTransform()
606
607
# Set center of rotation to image center
608
image_center = [128.0, 128.0, 64.0]
609
rigid.SetCenter(image_center)
610
611
# Set rotation (45 degrees around Z-axis)
612
rigid.SetRotation(0.0, 0.0, math.pi/4)
613
614
# Set translation
615
rigid.SetTranslation([10.0, -5.0, 0.0])
616
617
print(f"Parameters: {rigid.GetParameters()}")
618
print(f"Fixed parameters: {rigid.GetFixedParameters()}")
619
```
620
621
#### Affine Transform with Operations
622
623
```python
624
import SimpleITK as sitk
625
import math
626
627
# Create 2D affine transform
628
affine = sitk.AffineTransform(2)
629
630
# Set center
631
affine.SetCenter([128.0, 128.0])
632
633
# Apply transformations in sequence
634
affine.Scale(1.2) # Scale by 20%
635
affine.Rotate2D(math.pi/6) # Rotate 30 degrees
636
affine.Translate([10.0, -5.0]) # Translate
637
638
# Check final parameters
639
print(f"Matrix: {affine.GetMatrix()}")
640
print(f"Translation: {affine.GetTranslation()}")
641
```
642
643
#### B-spline Deformable Transform
644
645
```python
646
import SimpleITK as sitk
647
648
# Read reference image to define transform domain
649
reference_image = sitk.ReadImage('reference.nii')
650
651
# Create B-spline transform
652
bspline = sitk.BSplineTransform(3, 3) # 3D, cubic B-splines
653
654
# Set transform domain from reference image
655
bspline.SetTransformDomainOrigin(reference_image.GetOrigin())
656
bspline.SetTransformDomainPhysicalDimensions(
657
[reference_image.GetSize()[i] * reference_image.GetSpacing()[i]
658
for i in range(3)]
659
)
660
bspline.SetTransformDomainDirection(reference_image.GetDirection())
661
662
# Set mesh size (controls resolution of deformation)
663
mesh_size = [8, 8, 8] # 9x9x9 control points
664
bspline.SetTransformDomainMeshSize(mesh_size)
665
666
# Initialize with small random deformations
667
import random
668
num_params = bspline.GetNumberOfParameters()
669
params = [random.uniform(-2.0, 2.0) for _ in range(num_params)]
670
bspline.SetParameters(params)
671
672
print(f"B-spline parameters: {num_params}")
673
print(f"Mesh size: {bspline.GetTransformDomainMeshSize()}")
674
```
675
676
#### Transform Composition
677
678
```python
679
import SimpleITK as sitk
680
681
# Create individual transforms
682
translation = sitk.TranslationTransform(3)
683
translation.SetOffset([10.0, 0.0, 0.0])
684
685
rotation = sitk.Euler3DTransform()
686
rotation.SetCenter([128.0, 128.0, 64.0])
687
rotation.SetRotation(0.0, 0.0, 0.5) # Rotate around Z
688
689
scaling = sitk.ScaleTransform(3)
690
scaling.SetScale([1.2, 1.2, 1.0])
691
scaling.SetCenter([128.0, 128.0, 64.0])
692
693
# Compose transforms (applied in reverse order)
694
composite = sitk.CompositeTransform(3)
695
composite.AddTransform(translation) # Applied first
696
composite.AddTransform(rotation) # Applied second
697
composite.AddTransform(scaling) # Applied third
698
699
# Test composition
700
point = [100.0, 100.0, 50.0]
701
result = composite.TransformPoint(point)
702
print(f"Composite result: {result}")
703
704
# Alternative: apply individually to verify
705
temp1 = translation.TransformPoint(point)
706
temp2 = rotation.TransformPoint(temp1)
707
temp3 = scaling.TransformPoint(temp2)
708
print(f"Manual composition: {temp3}")
709
```
710
711
#### Transform File I/O
712
713
```python
714
import SimpleITK as sitk
715
716
# Create and configure transform
717
transform = sitk.Similarity3DTransform()
718
transform.SetScale(1.1)
719
transform.SetCenter([128.0, 128.0, 64.0])
720
transform.SetRotation([0.1, 0.0, 0.0, 0.995]) # Small rotation
721
transform.SetTranslation([5.0, -2.0, 1.0])
722
723
# Write transform to file
724
sitk.WriteTransform(transform, 'my_transform.tfm')
725
726
# Read transform back
727
loaded_transform = sitk.ReadTransform('my_transform.tfm')
728
729
# Verify they're equivalent
730
test_point = [100.0, 150.0, 75.0]
731
original_result = transform.TransformPoint(test_point)
732
loaded_result = loaded_transform.TransformPoint(test_point)
733
734
print(f"Original: {original_result}")
735
print(f"Loaded: {loaded_result}")
736
print(f"Difference: {[abs(a-b) for a,b in zip(original_result, loaded_result)]}")
737
```