|
36 | 36 | class DenseFieldTransform(TransformBase): |
37 | 37 | """Represents dense field (voxel-wise) transforms.""" |
38 | 38 |
|
39 | | - __slots__ = ("_field", "_deltas", "_is_deltas") |
| 39 | + __slots__ = ("_field", "_deltas", "_is_deltas", "_filtered_field") |
40 | 40 |
|
41 | | - def __init__(self, field=None, is_deltas=True, reference=None): |
| 41 | + def __init__(self, field=None, is_deltas=True, reference=None, do_prefilter=True): |
42 | 42 | """ |
43 | 43 | Create a dense field transform. |
44 | 44 |
|
@@ -107,6 +107,17 @@ def __init__(self, field=None, is_deltas=True, reference=None): |
107 | 107 | else: |
108 | 108 | self._field = _data.copy() |
109 | 109 |
|
| 110 | + self._filtered_field = None |
| 111 | + if do_prefilter: |
| 112 | + # pre-cache filtered field to accelerate later mapping |
| 113 | + from scipy.ndimage import spline_filter |
| 114 | + for i in range(self.reference.ndim): |
| 115 | + filtered_field_i = spline_filter(self._field[..., i], order=3, output=np.float64, mode='constant') |
| 116 | + if self._filtered_field is None: |
| 117 | + self._filtered_field = np.repeat(filtered_field_i[..., np.newaxis], self.reference.ndim, axis=-1) |
| 118 | + else: |
| 119 | + self._filtered_field[..., i] = filtered_field_i |
| 120 | + |
110 | 121 | def __repr__(self): |
111 | 122 | """Beautify the python representation.""" |
112 | 123 | return f"<{self.__class__.__name__}[{self._field.shape[-1]}D] {self._field.shape[:3]}>" |
@@ -193,12 +204,12 @@ def map(self, x, inverse=False): |
193 | 204 | mapped_coords = np.vstack( |
194 | 205 | tuple( |
195 | 206 | map_coordinates( |
196 | | - self._field[..., i], |
| 207 | + self._field[..., i] if self._filtered_field is None else self._filtered_field[..., i], |
197 | 208 | ijk.T, |
198 | 209 | order=3, |
199 | 210 | mode="constant", |
200 | 211 | cval=np.nan, |
201 | | - prefilter=True, |
| 212 | + prefilter=self._filtered_field is None, |
202 | 213 | ) |
203 | 214 | for i in range(self.reference.ndim) |
204 | 215 | ) |
|
0 commit comments