batchgenerators 0.25.4__tar.gz → 0.25.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/PKG-INFO +1 -1
  2. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/utils.py +8 -0
  3. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators.egg-info/PKG-INFO +1 -1
  4. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/pyproject.toml +1 -1
  5. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_seg_resampling.py +35 -0
  6. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/LICENSE +0 -0
  7. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/README.md +0 -0
  8. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/__init__.py +0 -0
  9. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/__init__.py +0 -0
  10. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/color_augmentations.py +0 -0
  11. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/crop_and_pad_augmentations.py +0 -0
  12. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/noise_augmentations.py +0 -0
  13. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/normalizations.py +0 -0
  14. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/resample_augmentations.py +0 -0
  15. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/augmentations/spatial_transformations.py +0 -0
  16. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/__init__.py +0 -0
  17. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/data_loader.py +0 -0
  18. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/dataset.py +0 -0
  19. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/multi_threaded_augmenter.py +0 -0
  20. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/nondet_multi_threaded_augmenter.py +0 -0
  21. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/dataloading/single_threaded_augmenter.py +0 -0
  22. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/datasets/__init__.py +0 -0
  23. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/datasets/cifar.py +0 -0
  24. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/__init__.py +0 -0
  25. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/brats2017/__init__.py +0 -0
  26. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/brats2017/brats2017_dataloader_2D.py +0 -0
  27. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/brats2017/brats2017_dataloader_3D.py +0 -0
  28. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/brats2017/brats2017_preprocessing.py +0 -0
  29. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/brats2017/config.py +0 -0
  30. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/cifar10.py +0 -0
  31. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/examples/multithreaded_dataloading.py +0 -0
  32. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/__init__.py +0 -0
  33. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/abstract_transforms.py +0 -0
  34. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/channel_selection_transforms.py +0 -0
  35. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/color_transforms.py +0 -0
  36. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/crop_and_pad_transforms.py +0 -0
  37. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/local_transforms.py +0 -0
  38. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/noise_transforms.py +0 -0
  39. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/resample_transforms.py +0 -0
  40. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/sample_normalization_transforms.py +0 -0
  41. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/spatial_transforms.py +0 -0
  42. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/transforms/utility_transforms.py +0 -0
  43. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/utilities/__init__.py +0 -0
  44. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/utilities/custom_types.py +0 -0
  45. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/utilities/data_splitting.py +0 -0
  46. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators/utilities/file_and_folder_operations.py +0 -0
  47. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators.egg-info/SOURCES.txt +0 -0
  48. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators.egg-info/dependency_links.txt +0 -0
  49. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators.egg-info/requires.txt +0 -0
  50. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/batchgenerators.egg-info/top_level.txt +0 -0
  51. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/setup.cfg +0 -0
  52. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/setup.py +0 -0
  53. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_DataLoader.py +0 -0
  54. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_augment_zoom.py +0 -0
  55. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_axis_mirroring.py +0 -0
  56. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_color_augmentations.py +0 -0
  57. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_crop.py +0 -0
  58. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_multithreaded_augmenter.py +0 -0
  59. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_normalizations.py +0 -0
  60. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_random_crop.py +0 -0
  61. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_resample_augmentations.py +0 -0
  62. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_sanity.py +0 -0
  63. {batchgenerators-0.25.4 → batchgenerators-0.25.5}/tests/test_spatial_transformations.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batchgenerators
3
- Version: 0.25.4
3
+ Version: 0.25.5
4
4
  Summary: Data augmentation toolkit
5
5
  Author-email: "Division of Medical Image Computing, German Cancer Research Center AND Applied Computer Vision Lab, Helmholtz Imaging Platform" <f.isensee@dkfz-heidelberg.de>
6
6
  License: Apache License
@@ -207,6 +207,10 @@ def _resample_seg_by_argmax(labels, score_fn, nearest_fn, out_shape, dtype, seg_
207
207
  if seg_tiebreak not in SEG_TIEBREAKS:
208
208
  raise ValueError('unknown seg_tiebreak: %s. Must be one of %s' % (seg_tiebreak, str(SEG_TIEBREAKS)))
209
209
  out_shape = tuple(out_shape)
210
+ if len(labels) == 0:
211
+ # an empty input: there is nothing to sample, so every output voxel is outside the image. Returning here
212
+ # also keeps the nearest neighbour sample below from being asked of an empty array, which fails.
213
+ return np.full(out_shape, 0 if empty_value is None else empty_value, dtype=dtype)
210
214
  if len(labels) == 1 and empty_value is None:
211
215
  # nothing to interpolate, and this also keeps the loop below from having to handle a missing `best`
212
216
  return np.full(out_shape, labels[0], dtype=dtype)
@@ -764,6 +768,10 @@ def resize_segmentation(segmentation, new_shape, order=3, *, seg_tiebreak='neare
764
768
  '''
765
769
  tpe = segmentation.dtype
766
770
  assert len(segmentation.shape) == len(new_shape), "new shape must have same dimensionality as segmentation"
771
+ if segmentation.size == 0:
772
+ # skimage cannot resize an empty array (scipy's zoom divides 0 by 0), at any order. Zeros of new_shape is
773
+ # what orders >= 1 returned before the argmax, from their zero-initialized result.
774
+ return np.zeros(new_shape, dtype=tpe)
767
775
  if order == 0:
768
776
  return resize(segmentation.astype(float), new_shape, order, mode="edge", clip=True, anti_aliasing=False).astype(tpe)
769
777
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batchgenerators
3
- Version: 0.25.4
3
+ Version: 0.25.5
4
4
  Summary: Data augmentation toolkit
5
5
  Author-email: "Division of Medical Image Computing, German Cancer Research Center AND Applied Computer Vision Lab, Helmholtz Imaging Platform" <f.isensee@dkfz-heidelberg.de>
6
6
  License: Apache License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "batchgenerators"
7
- version = "0.25.4"
7
+ version = "0.25.5"
8
8
  description = "Data augmentation toolkit"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -141,6 +141,26 @@ class TestResizeSegmentation(unittest.TestCase):
141
141
  with self.assertRaises(ValueError):
142
142
  resize_segmentation(seg, (4, 4), order=1, seg_tiebreak='bogus')
143
143
 
144
+ def test_empty_input_gives_zeros(self):
145
+ """
146
+ An empty segmentation came back as zeros of new_shape (the zero-initialized result) at orders >= 1. The
147
+ argmax broke that: it takes the nearest neighbour sample up front, which skimage cannot compute for an
148
+ empty array (scipy's zoom divides 0 by 0), and 'lowest'/'highest' indexed an empty label list. Order 0
149
+ failed the same way even before.
150
+ """
151
+ for order in (0, 1, 3):
152
+ for tiebreak in ('nearest', 'lowest', 'highest'):
153
+ for in_shape, out_shape in (((0, 4, 4), (0, 8, 8)), ((0, 4, 4), (2, 8, 8)), ((0, 5), (0, 10))):
154
+ out = resize_segmentation(np.zeros(in_shape, dtype=np.int16), out_shape, order=order,
155
+ seg_tiebreak=tiebreak)
156
+ msg = f'{in_shape} -> {out_shape}, order {order}, {tiebreak}'
157
+ self.assertEqual(out.shape, out_shape, msg)
158
+ self.assertEqual(out.dtype, np.int16, msg)
159
+ self.assertFalse(out.any(), msg)
160
+ out = resize_segmentation(np.ones((4, 4, 4), dtype=np.int16), (0, 8, 8), order=order,
161
+ seg_tiebreak=tiebreak)
162
+ self.assertEqual(out.shape, (0, 8, 8))
163
+
144
164
 
145
165
  class TestInterpolateImg(unittest.TestCase):
146
166
  """interpolate_img is the same rule on the augment_spatial path, and had the same two problems."""
@@ -195,6 +215,21 @@ class TestInterpolateImg(unittest.TestCase):
195
215
  # padding modes with no 'outside' must be left alone
196
216
  self.assertTrue((interpolate_img(img, coords, order=1, mode='nearest', is_seg=True) == 2).all())
197
217
 
218
+ def test_empty_input_gives_the_outside_value(self):
219
+ """With no image to sample from every point is outside it: cval for 'constant', 0 otherwise."""
220
+ img = np.zeros((0, 4), dtype=np.uint8)
221
+ coords = self._coords([0.5, 1.5], [0.5, 2.5])
222
+ for order in (1, 3):
223
+ for tiebreak in ('nearest', 'lowest', 'highest'):
224
+ out = interpolate_img(img, coords, order=order, mode='nearest', is_seg=True, seg_tiebreak=tiebreak)
225
+ self.assertEqual(out.shape, (2, 2))
226
+ self.assertEqual(out.dtype, np.uint8)
227
+ self.assertFalse(out.any(), f'order {order}, {tiebreak}')
228
+ for cval in (0., 7.):
229
+ out = interpolate_img(img, coords, order=order, mode='constant', cval=cval, is_seg=True,
230
+ seg_tiebreak=tiebreak)
231
+ self.assertTrue((out == cval).all(), f'order {order}, {tiebreak}, cval {cval}')
232
+
198
233
  def test_order_zero_and_non_seg_are_untouched(self):
199
234
  img = np.arange(16, dtype=np.uint8).reshape(4, 4)
200
235
  coords = self._coords([0.5, 2.5], [0.5, 2.5])