0
# Image Adaptors
1
2
View adaptors that provide different pixel interpretations and mathematical transformations of existing images without copying data. Image adaptors allow you to create different views of the same underlying image data, enabling efficient pixel access patterns and mathematical operations.
3
4
## Capabilities
5
6
### Base Adaptor Classes
7
8
Foundation classes for creating image views with different pixel access patterns.
9
10
```python { .api }
11
class ImageAdaptor[TImage, TAccessor]:
12
"""
13
Base class for image adaptors that provide alternative pixel access.
14
15
Template Parameters:
16
- TImage: Input image type
17
- TAccessor: Accessor class that defines pixel transformation
18
"""
19
def New() -> ImageAdaptor[TImage, TAccessor]: ...
20
def SetImage(self, image: TImage) -> None: ...
21
def GetImage(self) -> TImage: ...
22
def SetPixelAccessor(self, accessor: TAccessor) -> None: ...
23
def GetPixelAccessor(self) -> TAccessor: ...
24
def GetPixel(self, index: Index[ImageDimension]) -> ExternalType: ...
25
def SetPixel(self, index: Index[ImageDimension], value: ExternalType) -> None: ...
26
def GetRegion(self) -> ImageRegion[ImageDimension]: ...
27
def GetLargestPossibleRegion(self) -> ImageRegion[ImageDimension]: ...
28
def GetSpacing(self) -> SpacingType: ...
29
def GetOrigin(self) -> OriginType: ...
30
def GetDirection(self) -> DirectionType: ...
31
```
32
33
### Color Space Adaptors
34
35
Adaptors for converting between different color representations.
36
37
```python { .api }
38
class RGBToLuminanceImageAdaptor[TImage]:
39
"""Extract luminance component from RGB images."""
40
def New() -> RGBToLuminanceImageAdaptor[TImage]: ...
41
def SetImage(self, image: TImage) -> None: ...
42
def GetImage(self) -> TImage: ...
43
def GetPixel(self, index: Index[ImageDimension]) -> ComponentType: ...
44
45
class RGBToVectorImageAdaptor[TImage]:
46
"""Convert RGB pixels to vector pixels."""
47
def New() -> RGBToVectorImageAdaptor[TImage]: ...
48
def SetImage(self, image: TImage) -> None: ...
49
def GetPixel(self, index: Index[ImageDimension]) -> VectorType: ...
50
51
class VectorToRGBImageAdaptor[TImage]:
52
"""Convert vector pixels to RGB pixels."""
53
def New() -> VectorToRGBImageAdaptor[TImage]: ...
54
def SetImage(self, image: TImage) -> None: ...
55
def GetPixel(self, index: Index[ImageDimension]) -> RGBPixelType: ...
56
```
57
58
### Component Extraction Adaptors
59
60
Adaptors for extracting specific components from multi-component pixels.
61
62
```python { .api }
63
class NthElementImageAdaptor[TImage, TOutputPixelType]:
64
"""Extract the Nth component from multi-component pixels."""
65
def New() -> NthElementImageAdaptor[TImage, TOutputPixelType]: ...
66
def SetImage(self, image: TImage) -> None: ...
67
def SelectNthElement(self, nth: int) -> None: ...
68
def GetSelectedElement(self) -> int: ...
69
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
70
def SetPixel(self, index: Index[ImageDimension], value: TOutputPixelType) -> None: ...
71
72
class RedPixelAccessor[T]:
73
"""Pixel accessor for red component of RGB pixels."""
74
def Get(self, pixel: RGBPixel[T]) -> T: ...
75
def Set(self, pixel: RGBPixel[T], value: T) -> None: ...
76
77
class GreenPixelAccessor[T]:
78
"""Pixel accessor for green component of RGB pixels."""
79
def Get(self, pixel: RGBPixel[T]) -> T: ...
80
def Set(self, pixel: RGBPixel[T], value: T) -> None: ...
81
82
class BluePixelAccessor[T]:
83
"""Pixel accessor for blue component of RGB pixels."""
84
def Get(self, pixel: RGBPixel[T]) -> T: ...
85
def Set(self, pixel: RGBPixel[T], value: T) -> None: ...
86
```
87
88
### Complex Number Adaptors
89
90
Adaptors for extracting components from complex-valued images.
91
92
```python { .api }
93
class ComplexToRealImageAdaptor[TImage]:
94
"""Extract real part from complex images."""
95
def New() -> ComplexToRealImageAdaptor[TImage]: ...
96
def SetImage(self, image: TImage) -> None: ...
97
def GetPixel(self, index: Index[ImageDimension]) -> ComponentType: ...
98
99
class ComplexToImaginaryImageAdaptor[TImage]:
100
"""Extract imaginary part from complex images."""
101
def New() -> ComplexToImaginaryImageAdaptor[TImage]: ...
102
def SetImage(self, image: TImage) -> None: ...
103
def GetPixel(self, index: Index[ImageDimension]) -> ComponentType: ...
104
105
class ComplexToModulusImageAdaptor[TImage]:
106
"""Compute modulus (magnitude) of complex images."""
107
def New() -> ComplexToModulusImageAdaptor[TImage]: ...
108
def SetImage(self, image: TImage) -> None: ...
109
def GetPixel(self, index: Index[ImageDimension]) -> ComponentType: ...
110
111
class ComplexToPhaseImageAdaptor[TImage]:
112
"""Compute phase (argument) of complex images."""
113
def New() -> ComplexToPhaseImageAdaptor[TImage]: ...
114
def SetImage(self, image: TImage) -> None: ...
115
def GetPixel(self, index: Index[ImageDimension]) -> ComponentType: ...
116
```
117
118
### Mathematical Function Adaptors
119
120
Adaptors that apply mathematical functions to pixel values on-the-fly.
121
122
```python { .api }
123
class ExpImageAdaptor[TImage, TOutputPixelType]:
124
"""Apply exponential function to pixel values."""
125
def New() -> ExpImageAdaptor[TImage, TOutputPixelType]: ...
126
def SetImage(self, image: TImage) -> None: ...
127
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
128
129
class ExpNegativeImageAdaptor[TImage, TOutputPixelType]:
130
"""Apply negative exponential function to pixel values."""
131
def New() -> ExpNegativeImageAdaptor[TImage, TOutputPixelType]: ...
132
def SetImage(self, image: TImage) -> None: ...
133
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
134
135
class Log10ImageAdaptor[TImage, TOutputPixelType]:
136
"""Apply base-10 logarithm to pixel values."""
137
def New() -> Log10ImageAdaptor[TImage, TOutputPixelType]: ...
138
def SetImage(self, image: TImage) -> None: ...
139
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
140
141
class LogImageAdaptor[TImage, TOutputPixelType]:
142
"""Apply natural logarithm to pixel values."""
143
def New() -> LogImageAdaptor[TImage, TOutputPixelType]: ...
144
def SetImage(self, image: TImage) -> None: ...
145
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
146
147
class SinImageAdaptor[TImage, TOutputPixelType]:
148
"""Apply sine function to pixel values."""
149
def New() -> SinImageAdaptor[TImage, TOutputPixelType]: ...
150
def SetImage(self, image: TImage) -> None: ...
151
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
152
153
class CosImageAdaptor[TImage, TOutputPixelType]:
154
"""Apply cosine function to pixel values."""
155
def New() -> CosImageAdaptor[TImage, TOutputPixelType]: ...
156
def SetImage(self, image: TImage) -> None: ...
157
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
158
159
class TanImageAdaptor[TImage, TOutputPixelType]:
160
"""Apply tangent function to pixel values."""
161
def New() -> TanImageAdaptor[TImage, TOutputPixelType]: ...
162
def SetImage(self, image: TImage) -> None: ...
163
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
164
165
class SqrtImageAdaptor[TImage, TOutputPixelType]:
166
"""Apply square root function to pixel values."""
167
def New() -> SqrtImageAdaptor[TImage, TOutputPixelType]: ...
168
def SetImage(self, image: TImage) -> None: ...
169
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
170
171
class SquareImageAdaptor[TImage, TOutputPixelType]:
172
"""Apply square function to pixel values."""
173
def New() -> SquareImageAdaptor[TImage, TOutputPixelType]: ...
174
def SetImage(self, image: TImage) -> None: ...
175
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
176
```
177
178
### Arithmetic Adaptors
179
180
Adaptors for basic arithmetic operations with constants.
181
182
```python { .api }
183
class AddConstantToImageAdaptor[TImage, TOutputPixelType]:
184
"""Add a constant value to pixel values."""
185
def New() -> AddConstantToImageAdaptor[TImage, TOutputPixelType]: ...
186
def SetImage(self, image: TImage) -> None: ...
187
def SetConstant(self, constant: TOutputPixelType) -> None: ...
188
def GetConstant(self) -> TOutputPixelType: ...
189
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
190
191
class MultiplyByConstantImageAdaptor[TImage, TOutputPixelType]:
192
"""Multiply pixel values by a constant."""
193
def New() -> MultiplyByConstantImageAdaptor[TImage, TOutputPixelType]: ...
194
def SetImage(self, image: TImage) -> None: ...
195
def SetConstant(self, constant: TOutputPixelType) -> None: ...
196
def GetConstant(self) -> TOutputPixelType: ...
197
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
198
199
class AbsImageAdaptor[TImage, TOutputPixelType]:
200
"""Compute absolute value of pixel values."""
201
def New() -> AbsImageAdaptor[TImage, TOutputPixelType]: ...
202
def SetImage(self, image: TImage) -> None: ...
203
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
204
```
205
206
### Tensor and Matrix Adaptors
207
208
Adaptors for working with tensor and matrix-valued images.
209
210
```python { .api }
211
class SymmetricEigenAnalysisImageAdaptor[TImage, TOutputImage]:
212
"""Compute eigenanalysis of symmetric tensor images."""
213
def New() -> SymmetricEigenAnalysisImageAdaptor[TImage, TOutputImage]: ...
214
def SetImage(self, image: TImage) -> None: ...
215
def SetOrderEigenMagnitudes(self, order: bool) -> None: ...
216
def GetOrderEigenMagnitudes(self) -> bool: ...
217
def GetPixel(self, index: Index[ImageDimension]) -> OutputPixelType: ...
218
219
class TensorRelativeAnisotropyImageAdaptor[TImage, TOutputPixelType]:
220
"""Compute relative anisotropy from tensor images."""
221
def New() -> TensorRelativeAnisotropyImageAdaptor[TImage, TOutputPixelType]: ...
222
def SetImage(self, image: TImage) -> None: ...
223
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
224
225
class TensorFractionalAnisotropyImageAdaptor[TImage, TOutputPixelType]:
226
"""Compute fractional anisotropy from tensor images."""
227
def New() -> TensorFractionalAnisotropyImageAdaptor[TImage, TOutputPixelType]: ...
228
def SetImage(self, image: TImage) -> None: ...
229
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
230
```
231
232
### Vector and Point Adaptors
233
234
Adaptors for extracting components from vector and point images.
235
236
```python { .api }
237
class VectorComponentImageAdaptor[TImage, TOutputPixelType]:
238
"""Extract specific component from vector images."""
239
def New() -> VectorComponentImageAdaptor[TImage, TOutputPixelType]: ...
240
def SetImage(self, image: TImage) -> None: ...
241
def SetExtractComponentIndex(self, index: int) -> None: ...
242
def GetExtractComponentIndex(self) -> int: ...
243
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
244
245
class VectorMagnitudeImageAdaptor[TImage, TOutputPixelType]:
246
"""Compute magnitude of vector images."""
247
def New() -> VectorMagnitudeImageAdaptor[TImage, TOutputPixelType]: ...
248
def SetImage(self, image: TImage) -> None: ...
249
def GetPixel(self, index: Index[ImageDimension]) -> TOutputPixelType: ...
250
251
class PointImageAdaptor[TImage, TAccessor]:
252
"""Adaptor for point-based images."""
253
def New() -> PointImageAdaptor[TImage, TAccessor]: ...
254
def SetImage(self, image: TImage) -> None: ...
255
def GetPixel(self, index: Index[ImageDimension]) -> ExternalType: ...
256
def SetPixel(self, index: Index[ImageDimension], value: ExternalType) -> None: ...
257
```
258
259
## Usage Examples
260
261
### Color Space Conversion
262
263
```python
264
import itk
265
import numpy as np
266
267
# Create an RGB image
268
RGBPixelType = itk.RGBPixel[itk.UC]
269
RGBImageType = itk.Image[RGBPixelType, 2]
270
rgb_image = RGBImageType.New()
271
272
# Set up image region
273
size = itk.Size[2]([100, 100])
274
region = itk.ImageRegion[2]()
275
region.SetSize(size)
276
rgb_image.SetRegions(region)
277
rgb_image.Allocate()
278
279
# Fill with a color gradient
280
for x in range(100):
281
for y in range(100):
282
idx = itk.Index[2]([x, y])
283
pixel = RGBPixelType()
284
pixel.SetRed(int(x * 255 / 99))
285
pixel.SetGreen(int(y * 255 / 99))
286
pixel.SetBlue(128)
287
rgb_image.SetPixel(idx, pixel)
288
289
# Create luminance adaptor
290
LuminanceAdaptorType = itk.RGBToLuminanceImageAdaptor[RGBImageType]
291
luminance_adaptor = LuminanceAdaptorType.New()
292
luminance_adaptor.SetImage(rgb_image)
293
294
# Access luminance values
295
test_indices = [
296
itk.Index[2]([25, 25]),
297
itk.Index[2]([75, 25]),
298
itk.Index[2]([25, 75]),
299
itk.Index[2]([75, 75])
300
]
301
302
for idx in test_indices:
303
rgb_pixel = rgb_image.GetPixel(idx)
304
luminance = luminance_adaptor.GetPixel(idx)
305
306
print(f"Index {idx}:")
307
print(f" RGB: ({rgb_pixel.GetRed()}, {rgb_pixel.GetGreen()}, {rgb_pixel.GetBlue()})")
308
print(f" Luminance: {luminance}")
309
print()
310
311
# Create vector adaptor from RGB
312
VectorAdaptorType = itk.RGBToVectorImageAdaptor[RGBImageType]
313
vector_adaptor = VectorAdaptorType.New()
314
vector_adaptor.SetImage(rgb_image)
315
316
# Access as vector
317
vector_pixel = vector_adaptor.GetPixel(itk.Index[2]([50, 50]))
318
print(f"RGB as vector: [{vector_pixel[0]}, {vector_pixel[1]}, {vector_pixel[2]}]")
319
```
320
321
### Component Extraction
322
323
```python
324
import itk
325
326
# Create a vector image
327
VectorType = itk.Vector[itk.F, 3]
328
VectorImageType = itk.Image[VectorType, 2]
329
vector_image = VectorImageType.New()
330
331
# Set up region
332
size = itk.Size[2]([50, 50])
333
region = itk.ImageRegion[2]()
334
region.SetSize(size)
335
vector_image.SetRegions(region)
336
vector_image.Allocate()
337
338
# Fill with vector data
339
for x in range(50):
340
for y in range(50):
341
idx = itk.Index[2]([x, y])
342
vector = VectorType()
343
vector.SetElement(0, float(x))
344
vector.SetElement(1, float(y))
345
vector.SetElement(2, float(x + y))
346
vector_image.SetPixel(idx, vector)
347
348
# Create component extractors
349
NthElementAdaptorType = itk.NthElementImageAdaptor[VectorImageType, itk.F]
350
351
# Extract X component (element 0)
352
x_adaptor = NthElementAdaptorType.New()
353
x_adaptor.SetImage(vector_image)
354
x_adaptor.SelectNthElement(0)
355
356
# Extract Y component (element 1)
357
y_adaptor = NthElementAdaptorType.New()
358
y_adaptor.SetImage(vector_image)
359
y_adaptor.SelectNthElement(1)
360
361
# Extract Z component (element 2)
362
z_adaptor = NthElementAdaptorType.New()
363
z_adaptor.SetImage(vector_image)
364
z_adaptor.SelectNthElement(2)
365
366
# Test extraction
367
test_idx = itk.Index[2]([25, 30])
368
original_vector = vector_image.GetPixel(test_idx)
369
x_component = x_adaptor.GetPixel(test_idx)
370
y_component = y_adaptor.GetPixel(test_idx)
371
z_component = z_adaptor.GetPixel(test_idx)
372
373
print(f"Original vector: [{original_vector[0]}, {original_vector[1]}, {original_vector[2]}]")
374
print(f"Extracted components: X={x_component}, Y={y_component}, Z={z_component}")
375
376
# Create magnitude adaptor
377
MagnitudeAdaptorType = itk.VectorMagnitudeImageAdaptor[VectorImageType, itk.F]
378
magnitude_adaptor = MagnitudeAdaptorType.New()
379
magnitude_adaptor.SetImage(vector_image)
380
381
magnitude = magnitude_adaptor.GetPixel(test_idx)
382
expected_magnitude = np.sqrt(25**2 + 30**2 + 55**2)
383
print(f"Vector magnitude: {magnitude:.3f} (expected: {expected_magnitude:.3f})")
384
```
385
386
### Complex Image Processing
387
388
```python
389
import itk
390
import numpy as np
391
392
# Create a complex image
393
ComplexType = itk.complex[itk.F]
394
ComplexImageType = itk.Image[ComplexType, 2]
395
complex_image = ComplexImageType.New()
396
397
# Set up region
398
size = itk.Size[2]([50, 50])
399
region = itk.ImageRegion[2]()
400
region.SetSize(size)
401
complex_image.SetRegions(region)
402
complex_image.Allocate()
403
404
# Fill with complex data (e.g., a complex exponential)
405
for x in range(50):
406
for y in range(50):
407
idx = itk.Index[2]([x, y])
408
409
# Create a spiral pattern in complex plane
410
r = np.sqrt((x-25)**2 + (y-25)**2) / 25.0
411
theta = np.arctan2(y-25, x-25)
412
413
complex_val = ComplexType(r * np.cos(theta * 3), r * np.sin(theta * 3))
414
complex_image.SetPixel(idx, complex_val)
415
416
# Create complex component adaptors
417
RealAdaptorType = itk.ComplexToRealImageAdaptor[ComplexImageType]
418
ImagAdaptorType = itk.ComplexToImaginaryImageAdaptor[ComplexImageType]
419
ModulusAdaptorType = itk.ComplexToModulusImageAdaptor[ComplexImageType]
420
PhaseAdaptorType = itk.ComplexToPhaseImageAdaptor[ComplexImageType]
421
422
real_adaptor = RealAdaptorType.New()
423
real_adaptor.SetImage(complex_image)
424
425
imag_adaptor = ImagAdaptorType.New()
426
imag_adaptor.SetImage(complex_image)
427
428
modulus_adaptor = ModulusAdaptorType.New()
429
modulus_adaptor.SetImage(complex_image)
430
431
phase_adaptor = PhaseAdaptorType.New()
432
phase_adaptor.SetImage(complex_image)
433
434
# Test complex extraction
435
test_indices = [
436
itk.Index[2]([35, 25]), # Right of center
437
itk.Index[2]([25, 35]), # Above center
438
itk.Index[2]([15, 25]) # Left of center
439
]
440
441
for idx in test_indices:
442
complex_pixel = complex_image.GetPixel(idx)
443
real_part = real_adaptor.GetPixel(idx)
444
imag_part = imag_adaptor.GetPixel(idx)
445
modulus = modulus_adaptor.GetPixel(idx)
446
phase = phase_adaptor.GetPixel(idx)
447
448
print(f"Index {idx}:")
449
print(f" Complex: {complex_pixel.real():.3f} + {complex_pixel.imag():.3f}i")
450
print(f" Real: {real_part:.3f}")
451
print(f" Imaginary: {imag_part:.3f}")
452
print(f" Modulus: {modulus:.3f}")
453
print(f" Phase: {phase:.3f} radians")
454
print()
455
```
456
457
### Mathematical Function Adaptors
458
459
```python
460
import itk
461
import numpy as np
462
463
# Create a test image
464
ImageType = itk.Image[itk.F, 2]
465
image = ImageType.New()
466
467
size = itk.Size[2]([50, 50])
468
region = itk.ImageRegion[2]()
469
region.SetSize(size)
470
image.SetRegions(region)
471
image.Allocate()
472
473
# Fill with values suitable for various mathematical functions
474
for x in range(50):
475
for y in range(50):
476
idx = itk.Index[2]([x, y])
477
value = float(x + y) / 10.0 # Values from 0 to ~10
478
image.SetPixel(idx, value)
479
480
# Create various mathematical adaptors
481
ExpAdaptorType = itk.ExpImageAdaptor[ImageType, itk.F]
482
LogAdaptorType = itk.LogImageAdaptor[ImageType, itk.F]
483
SinAdaptorType = itk.SinImageAdaptor[ImageType, itk.F]
484
SqrtAdaptorType = itk.SqrtImageAdaptor[ImageType, itk.F]
485
486
exp_adaptor = ExpAdaptorType.New()
487
exp_adaptor.SetImage(image)
488
489
log_adaptor = LogAdaptorType.New()
490
log_adaptor.SetImage(image)
491
492
sin_adaptor = SinAdaptorType.New()
493
sin_adaptor.SetImage(image)
494
495
sqrt_adaptor = SqrtAdaptorType.New()
496
sqrt_adaptor.SetImage(image)
497
498
# Test mathematical functions
499
test_idx = itk.Index[2]([10, 20]) # This gives value = 3.0
500
original_value = image.GetPixel(test_idx)
501
502
exp_value = exp_adaptor.GetPixel(test_idx)
503
log_value = log_adaptor.GetPixel(test_idx)
504
sin_value = sin_adaptor.GetPixel(test_idx)
505
sqrt_value = sqrt_adaptor.GetPixel(test_idx)
506
507
print(f"Original value: {original_value}")
508
print(f"Exponential: {exp_value:.3f} (expected: {np.exp(original_value):.3f})")
509
print(f"Logarithm: {log_value:.3f} (expected: {np.log(original_value):.3f})")
510
print(f"Sine: {sin_value:.3f} (expected: {np.sin(original_value):.3f})")
511
print(f"Square root: {sqrt_value:.3f} (expected: {np.sqrt(original_value):.3f})")
512
```
513
514
### Arithmetic Operations with Adaptors
515
516
```python
517
import itk
518
519
# Create test image
520
ImageType = itk.Image[itk.F, 2]
521
image = ImageType.New()
522
523
size = itk.Size[2]([30, 30])
524
region = itk.ImageRegion[2]()
525
region.SetSize(size)
526
image.SetRegions(region)
527
image.Allocate()
528
529
# Fill with a simple pattern
530
for x in range(30):
531
for y in range(30):
532
idx = itk.Index[2]([x, y])
533
value = float(x * y) / 10.0
534
image.SetPixel(idx, value)
535
536
# Create arithmetic adaptors
537
AddConstantType = itk.AddConstantToImageAdaptor[ImageType, itk.F]
538
MultiplyConstantType = itk.MultiplyByConstantImageAdaptor[ImageType, itk.F]
539
540
add_adaptor = AddConstantType.New()
541
add_adaptor.SetImage(image)
542
add_adaptor.SetConstant(5.0)
543
544
multiply_adaptor = MultiplyConstantType.New()
545
multiply_adaptor.SetImage(image)
546
multiply_adaptor.SetConstant(2.0)
547
548
# Test arithmetic operations
549
test_indices = [
550
itk.Index[2]([5, 6]), # value = 3.0
551
itk.Index[2]([10, 8]), # value = 8.0
552
itk.Index[2]([15, 4]) # value = 6.0
553
]
554
555
for idx in test_indices:
556
original = image.GetPixel(idx)
557
added = add_adaptor.GetPixel(idx)
558
multiplied = multiply_adaptor.GetPixel(idx)
559
560
print(f"Index {idx}:")
561
print(f" Original: {original}")
562
print(f" Plus 5: {added} (expected: {original + 5.0})")
563
print(f" Times 2: {multiplied} (expected: {original * 2.0})")
564
print()
565
566
# Chain adaptors (multiply then add)
567
ChainedAddType = itk.AddConstantToImageAdaptor[MultiplyConstantType, itk.F]
568
chained_adaptor = ChainedAddType.New()
569
chained_adaptor.SetImage(multiply_adaptor) # Use multiply_adaptor as input
570
chained_adaptor.SetConstant(10.0)
571
572
# Test chained operation: (original * 2) + 10
573
test_idx = itk.Index[2]([10, 8])
574
original = image.GetPixel(test_idx)
575
chained_result = chained_adaptor.GetPixel(test_idx)
576
expected = (original * 2.0) + 10.0
577
578
print(f"Chained operation at {test_idx}:")
579
print(f"Original: {original}")
580
print(f"(Original * 2) + 10: {chained_result} (expected: {expected})")
581
```
582
583
### Working with Tensor Images
584
585
```python
586
import itk
587
import numpy as np
588
589
# Create a symmetric tensor image (e.g., for DTI data)
590
TensorType = itk.SymmetricSecondRankTensor[itk.D, 3]
591
TensorImageType = itk.Image[TensorType, 3]
592
tensor_image = TensorImageType.New()
593
594
# Set up a small 3D region
595
size = itk.Size[3]([10, 10, 5])
596
region = itk.ImageRegion[3]()
597
region.SetSize(size)
598
tensor_image.SetRegions(region)
599
tensor_image.Allocate()
600
601
# Fill with synthetic tensor data
602
for x in range(10):
603
for y in range(10):
604
for z in range(5):
605
idx = itk.Index[3]([x, y, z])
606
607
# Create a simple tensor with some anisotropy
608
tensor = TensorType()
609
tensor.SetElement(0, 0, 1.0 + 0.1 * x) # XX component
610
tensor.SetElement(1, 1, 0.8 + 0.1 * y) # YY component
611
tensor.SetElement(2, 2, 0.6 + 0.1 * z) # ZZ component
612
tensor.SetElement(0, 1, 0.1) # XY component
613
tensor.SetElement(0, 2, 0.05) # XZ component
614
tensor.SetElement(1, 2, 0.05) # YZ component
615
616
tensor_image.SetPixel(idx, tensor)
617
618
# Create tensor analysis adaptors
619
FAAdaptorType = itk.TensorFractionalAnisotropyImageAdaptor[TensorImageType, itk.D]
620
RAAdaptorType = itk.TensorRelativeAnisotropyImageAdaptor[TensorImageType, itk.D]
621
622
fa_adaptor = FAAdaptorType.New()
623
fa_adaptor.SetImage(tensor_image)
624
625
ra_adaptor = RAAdaptorType.New()
626
ra_adaptor.SetImage(tensor_image)
627
628
# Test tensor analysis
629
test_idx = itk.Index[3]([5, 5, 2])
630
tensor = tensor_image.GetPixel(test_idx)
631
fa_value = fa_adaptor.GetPixel(test_idx)
632
ra_value = ra_adaptor.GetPixel(test_idx)
633
634
print(f"Tensor at {test_idx}:")
635
print(f" Fractional Anisotropy: {fa_value:.3f}")
636
print(f" Relative Anisotropy: {ra_value:.3f}")
637
638
# Get tensor trace (should equal sum of diagonal elements)
639
trace = tensor.GetTrace()
640
expected_trace = tensor.GetElement(0,0) + tensor.GetElement(1,1) + tensor.GetElement(2,2)
641
print(f" Trace: {trace:.3f} (expected: {expected_trace:.3f})")
642
```