Generate a smooth field array by defining a smaller randomized field and then reinterpolating to the desired size. This exploits interpolation to create a smoothly varying field used for other applications. An initial randomized field is defined with `rand_size` dimensions with `pad` n
| 33 | |
| 34 | |
| 35 | class SmoothField(Randomizable): |
| 36 | """ |
| 37 | Generate a smooth field array by defining a smaller randomized field and then reinterpolating to the desired size. |
| 38 | |
| 39 | This exploits interpolation to create a smoothly varying field used for other applications. An initial randomized |
| 40 | field is defined with `rand_size` dimensions with `pad` number of values padding it along each dimension using |
| 41 | `pad_val` as the value. If `spatial_size` is given this is interpolated to that size, otherwise if None the random |
| 42 | array is produced uninterpolated. The output is always a Pytorch tensor allocated on the specified device. |
| 43 | |
| 44 | Args: |
| 45 | rand_size: size of the randomized field to start from |
| 46 | pad: number of pixels/voxels along the edges of the field to pad with `pad_val` |
| 47 | pad_val: value with which to pad field edges |
| 48 | low: low value for randomized field |
| 49 | high: high value for randomized field |
| 50 | channels: number of channels of final output |
| 51 | spatial_size: final output size of the array, None to produce original uninterpolated field |
| 52 | mode: interpolation mode for resizing the field |
| 53 | align_corners: if True align the corners when upsampling field |
| 54 | device: Pytorch device to define field on |
| 55 | """ |
| 56 | |
| 57 | backend = [TransformBackends.TORCH] |
| 58 | |
| 59 | def __init__( |
| 60 | self, |
| 61 | rand_size: Sequence[int], |
| 62 | pad: int = 0, |
| 63 | pad_val: float = 0, |
| 64 | low: float = -1.0, |
| 65 | high: float = 1.0, |
| 66 | channels: int = 1, |
| 67 | spatial_size: Sequence[int] | None = None, |
| 68 | mode: str = InterpolateMode.AREA, |
| 69 | align_corners: bool | None = None, |
| 70 | device: torch.device | None = None, |
| 71 | ): |
| 72 | self.rand_size = tuple(rand_size) |
| 73 | self.pad = pad |
| 74 | self.low = low |
| 75 | self.high = high |
| 76 | self.channels = channels |
| 77 | self.mode = mode |
| 78 | self.align_corners = align_corners |
| 79 | self.device = device |
| 80 | |
| 81 | self.spatial_size: Sequence[int] | None = None |
| 82 | self.spatial_zoom: Sequence[float] | None = None |
| 83 | |
| 84 | if low >= high: |
| 85 | raise ValueError("Value for `low` must be less than `high` otherwise field will be zeros") |
| 86 | |
| 87 | self.total_rand_size = tuple(rs + self.pad * 2 for rs in self.rand_size) |
| 88 | |
| 89 | self.field = torch.ones((1, self.channels) + self.total_rand_size, device=self.device) * pad_val |
| 90 | |
| 91 | self.crand_size = (self.channels,) + self.rand_size |
| 92 |