Skip to content

Commit 3927182

Browse files
committed
update spacing inverse
Signed-off-by: Wenqi Li <wenqil@nvidia.com>
1 parent 1bf2ccd commit 3927182

File tree

5 files changed

+18
-8
lines changed

5 files changed

+18
-8
lines changed

.github/workflows/pythonapp.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ jobs:
285285
- name: Run quick tests (GPU)
286286
run: |
287287
nvidia-smi
288-
export LAUNCH_DELAY=$(python -c "import numpy; print(numpy.random.randint(30) * 5)")
288+
export LAUNCH_DELAY=$(python -c "import numpy; print(numpy.random.randint(30) * 10)")
289289
echo "Sleep $LAUNCH_DELAY"
290290
sleep $LAUNCH_DELAY
291291
export CUDA_VISIBLE_DEVICES=$(coverage run -m tests.utils)

docs/source/installation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ for the latest features:
5959

6060
### Option 1 (as a part of your system-wide module):
6161
```bash
62-
pip install git+https://github.com/Project-MONAI/MONAI#egg=MONAI
62+
pip install git+https://github.com/Project-MONAI/MONAI#egg=monai
6363
```
6464
or, to build with MONAI Cpp/CUDA extensions:
6565
```bash
66-
BUILD_MONAI=1 pip install git+https://github.com/Project-MONAI/MONAI#egg=MONAI
66+
BUILD_MONAI=1 pip install git+https://github.com/Project-MONAI/MONAI#egg=monai
6767
```
6868
this command will download and install the current master branch of [MONAI from
6969
GitHub](https://github.com/Project-MONAI/MONAI).

monai/transforms/spatial/array.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def __call__(
129129
padding_mode: Optional[Union[GridSamplePadMode, str]] = None,
130130
align_corners: Optional[bool] = None,
131131
dtype: DtypeLike = None,
132+
output_spatial_shape: Optional[np.ndarray] = None,
132133
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
133134
"""
134135
Args:
@@ -145,6 +146,9 @@ def __call__(
145146
dtype: data type for resampling computation. Defaults to ``self.dtype``.
146147
If None, use the data type of input data. To be compatible with other modules,
147148
the output data type is always ``np.float32``.
149+
output_spatial_shape: specify the shape of the output data_array. This is typically useful for
150+
the inverse of `Spacingd` where sometimes we could not compute the exact shape due to the quantization
151+
error with the affines.
148152
149153
Raises:
150154
ValueError: When ``data_array`` has no spatial dimensions.
@@ -195,7 +199,7 @@ def __call__(
195199
# AffineTransform requires a batch dim
196200
torch.as_tensor(np.ascontiguousarray(data_array).astype(_dtype)).unsqueeze(0),
197201
torch.as_tensor(np.ascontiguousarray(transform).astype(_dtype)),
198-
spatial_size=output_shape,
202+
spatial_size=output_shape if output_spatial_shape is None else output_spatial_shape,
199203
)
200204
output_data = np.asarray(output_data.squeeze(0).detach().cpu().numpy(), dtype=np.float32) # type: ignore
201205
new_affine = to_affine_nd(affine, new_affine)

monai/transforms/spatial/dictionary.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ def __call__(
201201
meta_data = d[meta_data_key]
202202
# resample array of each corresponding key
203203
# using affine fetched from d[affine_key]
204+
original_spatial_shape = d[key].shape[1:]
204205
d[key], old_affine, new_affine = self.spacing_transform(
205206
data_array=np.asarray(d[key]),
206207
affine=meta_data["affine"],
@@ -219,6 +220,7 @@ def __call__(
219220
"padding_mode": padding_mode.value if isinstance(padding_mode, Enum) else padding_mode,
220221
"align_corners": align_corners if align_corners is not None else "none",
221222
},
223+
orig_size=original_spatial_shape,
222224
)
223225
# set the 'affine' key
224226
meta_data["affine"] = new_affine
@@ -239,6 +241,7 @@ def inverse(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.ndar
239241
mode = transform[InverseKeys.EXTRA_INFO]["mode"]
240242
padding_mode = transform[InverseKeys.EXTRA_INFO]["padding_mode"]
241243
align_corners = transform[InverseKeys.EXTRA_INFO]["align_corners"]
244+
orig_size = transform[InverseKeys.ORIG_SIZE]
242245
orig_pixdim = np.sqrt(np.sum(np.square(old_affine), 0))[:-1]
243246
inverse_transform = Spacing(orig_pixdim, diagonal=self.spacing_transform.diagonal)
244247
# Apply inverse
@@ -249,6 +252,7 @@ def inverse(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.ndar
249252
padding_mode=padding_mode,
250253
align_corners=False if align_corners == "none" else align_corners,
251254
dtype=dtype,
255+
output_spatial_shape=orig_size,
252256
)
253257
meta_data["affine"] = new_affine
254258
# Remove the applied transform
@@ -1482,7 +1486,7 @@ def inverse(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.ndar
14821486
align_corners=None if align_corners == "none" else align_corners,
14831487
)
14841488
# Size might be out by 1 voxel so pad
1485-
d[key] = SpatialPad(transform[InverseKeys.ORIG_SIZE])(d[key])
1489+
d[key] = SpatialPad(transform[InverseKeys.ORIG_SIZE], mode="edge")(d[key])
14861490
# Remove the applied transform
14871491
self.pop_transform(d, key)
14881492

@@ -1607,7 +1611,7 @@ def inverse(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.ndar
16071611
align_corners=None if align_corners == "none" else align_corners,
16081612
)
16091613
# Size might be out by 1 voxel so pad
1610-
d[key] = SpatialPad(transform[InverseKeys.ORIG_SIZE])(d[key])
1614+
d[key] = SpatialPad(transform[InverseKeys.ORIG_SIZE], mode="edge")(d[key])
16111615
# Remove the applied transform
16121616
self.pop_transform(d, key)
16131617

tests/test_handler_transform_inverter.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
CastToTyped,
2525
Compose,
2626
LoadImaged,
27+
Orientationd,
2728
RandAffined,
2829
RandAxisFlipd,
2930
RandFlipd,
@@ -49,7 +50,8 @@ def test_invert(self):
4950
[
5051
LoadImaged(KEYS),
5152
AddChanneld(KEYS),
52-
Spacingd(KEYS, pixdim=(1.1, 1.01, 0.9), mode=["bilinear", "nearest"], dtype=np.float32),
53+
Orientationd(KEYS, "RPS"),
54+
Spacingd(KEYS, pixdim=(1.2, 1.01, 0.9), mode=["bilinear", "nearest"], dtype=np.float32),
5355
ScaleIntensityd("image", minv=1, maxv=10),
5456
RandFlipd(KEYS, prob=0.5, spatial_axis=[1, 2]),
5557
RandAxisFlipd(KEYS, prob=0.5),
@@ -105,7 +107,7 @@ def _train_func(engine, batch):
105107
original_name = data[-1]["label"]
106108
self.assertEqual(reverted_name, original_name)
107109
print("invert diff", reverted.size - n_good)
108-
self.assertTrue((reverted.size - n_good) in (0, 981), "diff. in two possible values")
110+
self.assertTrue((reverted.size - n_good) in (25300, 1812), "diff. in two possible values")
109111

110112

111113
if __name__ == "__main__":

0 commit comments

Comments
 (0)