Skip to content

Commit c119b5b

Browse files
committed
Add zone plate test image
1 parent 9d1b3b2 commit c119b5b

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

src/torchio/datasets/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .rsna_miccai import RSNAMICCAI
2121
from .rsna_spine_fracture import RSNACervicalSpineFracture
2222
from .slicer import Slicer
23+
from .zone_plate import ZonePlate
2324

2425
__all__ = [
2526
'FPG',
@@ -44,4 +45,5 @@
4445
'FractureMNIST3D',
4546
'VesselMNIST3D',
4647
'SynapseMNIST3D',
48+
'ZonePlate',
4749
]

src/torchio/datasets/zone_plate.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import numpy as np
2+
3+
from ..data import ScalarImage
4+
from ..data.subject import Subject
5+
6+
7+
class ZonePlate(Subject):
8+
"""Synthetic data generated from a zone plate.
9+
10+
The zone plate is a circular diffraction grating that produces concentric
11+
rings of light and dark bands. This dataset is useful for testing image
12+
processing algorithms, particularly those related to frequency analysis and
13+
interpolation.
14+
15+
See equation 10.63 in `Practical Handbook on Image Processing for
16+
Scientific Applications <https://www.routledge.com/Practical-Handbook-on-Image-Processing-for-Scientific-and-Technical-Applications/Jahne/p/book/9780849319006?srsltid=AfmBOoptrtzILIlMx9FYqvx6UrGbevfD66x2k242iprFdn_CfyOWXjjH>`_
17+
by Bernd Jähne.
18+
19+
Args:
20+
size: The size of the generated image along all dimensions.
21+
"""
22+
23+
def __init__(self, size: int = 501):
24+
if size < 3:
25+
raise ValueError('Size must be at least 3.')
26+
self.size = size
27+
image = self._generate_image(size)
28+
super().__init__(image=image)
29+
30+
@staticmethod
31+
def _generate_image(size: int) -> ScalarImage:
32+
if size % 2 == 1:
33+
fin = (size - 1) // 2
34+
ini = -fin
35+
else:
36+
fin = size // 2
37+
ini = -fin + 1
38+
x = np.arange(ini, fin)
39+
y = np.arange(ini, fin)
40+
z = np.arange(ini, fin)
41+
X, Y, Z = np.meshgrid(x, y, z)
42+
r = np.sqrt(X**2 + Y**2 + Z**2)
43+
km = 0.8 * np.pi
44+
rm = ini
45+
w = rm / 10
46+
term1 = np.sin((km * r**2) / (2 * rm))
47+
term2 = 0.5 * np.tanh((rm - r) / w) + 0.5
48+
g = term1 * term2
49+
affine = np.eye(4)
50+
origin = np.array([ini, ini, ini])
51+
affine[:3, 3] = origin
52+
return ScalarImage(tensor=g[np.newaxis], affine=affine)

0 commit comments

Comments
 (0)