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 |