| Total Complexity | 4 |
| Total Lines | 53 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
| 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) |
||
| 53 |