or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-structures.mdfiltering.mdfinite-difference.mdgpu-computing.mdimage-adaptors.mdimage-functions.mdindex.mdio.mdmesh.mdnumpy-integration.mdregistration.mdsegmentation.mdspatial-objects.mdtransforms.md

image-adaptors.mddocs/

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

```