|
| 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