ngio 0.3.5__py3-none-any.whl → 0.4.0__py3-none-any.whl

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 (73) hide show
  1. ngio/__init__.py +7 -2
  2. ngio/common/__init__.py +5 -52
  3. ngio/common/_dimensions.py +270 -55
  4. ngio/common/_masking_roi.py +38 -10
  5. ngio/common/_pyramid.py +51 -30
  6. ngio/common/_roi.py +269 -82
  7. ngio/common/_synt_images_utils.py +101 -0
  8. ngio/common/_zoom.py +49 -19
  9. ngio/experimental/__init__.py +5 -0
  10. ngio/experimental/iterators/__init__.py +15 -0
  11. ngio/experimental/iterators/_abstract_iterator.py +390 -0
  12. ngio/experimental/iterators/_feature.py +189 -0
  13. ngio/experimental/iterators/_image_processing.py +130 -0
  14. ngio/experimental/iterators/_mappers.py +48 -0
  15. ngio/experimental/iterators/_rois_utils.py +127 -0
  16. ngio/experimental/iterators/_segmentation.py +235 -0
  17. ngio/hcs/_plate.py +41 -36
  18. ngio/images/__init__.py +22 -1
  19. ngio/images/_abstract_image.py +403 -176
  20. ngio/images/_create.py +31 -15
  21. ngio/images/_create_synt_container.py +138 -0
  22. ngio/images/_image.py +452 -63
  23. ngio/images/_label.py +56 -30
  24. ngio/images/_masked_image.py +387 -129
  25. ngio/images/_ome_zarr_container.py +237 -67
  26. ngio/{common → images}/_table_ops.py +41 -41
  27. ngio/io_pipes/__init__.py +75 -0
  28. ngio/io_pipes/_io_pipes.py +361 -0
  29. ngio/io_pipes/_io_pipes_masked.py +488 -0
  30. ngio/io_pipes/_io_pipes_roi.py +152 -0
  31. ngio/io_pipes/_io_pipes_types.py +56 -0
  32. ngio/io_pipes/_match_shape.py +376 -0
  33. ngio/io_pipes/_ops_axes.py +344 -0
  34. ngio/io_pipes/_ops_slices.py +446 -0
  35. ngio/io_pipes/_ops_slices_utils.py +196 -0
  36. ngio/io_pipes/_ops_transforms.py +104 -0
  37. ngio/io_pipes/_zoom_transform.py +175 -0
  38. ngio/ome_zarr_meta/__init__.py +4 -2
  39. ngio/ome_zarr_meta/ngio_specs/__init__.py +4 -10
  40. ngio/ome_zarr_meta/ngio_specs/_axes.py +186 -175
  41. ngio/ome_zarr_meta/ngio_specs/_channels.py +55 -18
  42. ngio/ome_zarr_meta/ngio_specs/_dataset.py +48 -122
  43. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +3 -3
  44. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +38 -87
  45. ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +17 -1
  46. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +34 -31
  47. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
  48. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  49. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
  50. ngio/resources/__init__.py +55 -0
  51. ngio/resources/resource_model.py +36 -0
  52. ngio/tables/backends/_abstract_backend.py +5 -6
  53. ngio/tables/backends/_anndata.py +1 -1
  54. ngio/tables/backends/_anndata_utils.py +3 -3
  55. ngio/tables/backends/_non_zarr_backends.py +1 -1
  56. ngio/tables/backends/_table_backends.py +0 -1
  57. ngio/tables/backends/_utils.py +3 -3
  58. ngio/tables/v1/_roi_table.py +165 -70
  59. ngio/transforms/__init__.py +5 -0
  60. ngio/transforms/_zoom.py +19 -0
  61. ngio/utils/__init__.py +2 -3
  62. ngio/utils/_datasets.py +5 -0
  63. ngio/utils/_logger.py +19 -0
  64. ngio/utils/_zarr_utils.py +6 -6
  65. {ngio-0.3.5.dist-info → ngio-0.4.0.dist-info}/METADATA +16 -14
  66. ngio-0.4.0.dist-info/RECORD +85 -0
  67. ngio/common/_array_pipe.py +0 -288
  68. ngio/common/_axes_transforms.py +0 -64
  69. ngio/common/_common_types.py +0 -5
  70. ngio/common/_slicer.py +0 -96
  71. ngio-0.3.5.dist-info/RECORD +0 -61
  72. {ngio-0.3.5.dist-info → ngio-0.4.0.dist-info}/WHEEL +0 -0
  73. {ngio-0.3.5.dist-info → ngio-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,189 @@
1
+ from collections.abc import Sequence
2
+ from typing import TypeAlias
3
+
4
+ import dask.array as da
5
+ import numpy as np
6
+
7
+ from ngio.common import Roi, RoiPixels
8
+ from ngio.experimental.iterators._abstract_iterator import AbstractIteratorBuilder
9
+ from ngio.images import Image, Label
10
+ from ngio.images._image import (
11
+ ChannelSlicingInputType,
12
+ add_channel_selection_to_slicing_dict,
13
+ )
14
+ from ngio.io_pipes import (
15
+ DaskRoiGetter,
16
+ DataGetter,
17
+ NumpyRoiGetter,
18
+ TransformProtocol,
19
+ )
20
+
21
+ NumpyPipeType: TypeAlias = tuple[np.ndarray, np.ndarray, Roi | RoiPixels]
22
+ DaskPipeType: TypeAlias = tuple[da.Array, da.Array, Roi | RoiPixels]
23
+
24
+
25
+ class NumpyFeatureGetter(DataGetter[NumpyPipeType]):
26
+ def __init__(
27
+ self,
28
+ image_getter: NumpyRoiGetter,
29
+ label_getter: NumpyRoiGetter,
30
+ ) -> None:
31
+ self._image_getter = image_getter
32
+ self._label_getter = label_getter
33
+ super().__init__(
34
+ zarr_array=self._image_getter.zarr_array,
35
+ slicing_ops=self._image_getter.slicing_ops,
36
+ axes_ops=self._image_getter.axes_ops,
37
+ transforms=self._image_getter.transforms,
38
+ roi=self._image_getter.roi,
39
+ )
40
+
41
+ def get(self) -> NumpyPipeType:
42
+ return self._image_getter(), self._label_getter(), self.roi
43
+
44
+ @property
45
+ def image(self) -> np.ndarray:
46
+ return self._image_getter()
47
+
48
+ @property
49
+ def label(self) -> np.ndarray:
50
+ return self._label_getter()
51
+
52
+
53
+ class DaskFeatureGetter(DataGetter[DaskPipeType]):
54
+ def __init__(
55
+ self,
56
+ image_getter: DaskRoiGetter,
57
+ label_getter: DaskRoiGetter,
58
+ ) -> None:
59
+ self._image_getter = image_getter
60
+ self._label_getter = label_getter
61
+ super().__init__(
62
+ zarr_array=self._image_getter.zarr_array,
63
+ slicing_ops=self._image_getter.slicing_ops,
64
+ axes_ops=self._image_getter.axes_ops,
65
+ transforms=self._image_getter.transforms,
66
+ roi=self._image_getter.roi,
67
+ )
68
+
69
+ def get(self) -> DaskPipeType:
70
+ return self._image_getter(), self._label_getter(), self.roi
71
+
72
+ @property
73
+ def image(self) -> da.Array:
74
+ return self._image_getter()
75
+
76
+ @property
77
+ def label(self) -> da.Array:
78
+ return self._label_getter()
79
+
80
+
81
+ class FeatureExtractorIterator(AbstractIteratorBuilder[NumpyPipeType, DaskPipeType]):
82
+ """Base class for iterators over ROIs."""
83
+
84
+ def __init__(
85
+ self,
86
+ input_image: Image,
87
+ input_label: Label,
88
+ channel_selection: ChannelSlicingInputType = None,
89
+ axes_order: Sequence[str] | None = None,
90
+ input_transforms: Sequence[TransformProtocol] | None = None,
91
+ label_transforms: Sequence[TransformProtocol] | None = None,
92
+ ) -> None:
93
+ """Initialize the iterator with a ROI table and input/output images.
94
+
95
+ Args:
96
+ input_image (Image): The input image to be used as input for the
97
+ segmentation.
98
+ input_label (Label): The input label with the segmentation masks.
99
+ channel_selection (ChannelSlicingInputType): Optional
100
+ selection of channels to use for the segmentation.
101
+ axes_order (Sequence[str] | None): Optional axes order for the
102
+ segmentation.
103
+ input_transforms (Sequence[TransformProtocol] | None): Optional
104
+ transforms to apply to the input image.
105
+ label_transforms (Sequence[TransformProtocol] | None): Optional
106
+ transforms to apply to the output label.
107
+ """
108
+ self._input = input_image
109
+ self._input_label = input_label
110
+ self._ref_image = input_image
111
+ self._rois = input_image.build_image_roi_table(name=None).rois()
112
+
113
+ # Set iteration parameters
114
+ self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
115
+ image=self._input, channel_selection=channel_selection, slicing_dict={}
116
+ )
117
+ self._channel_selection = channel_selection
118
+ self._axes_order = axes_order
119
+ self._input_transforms = input_transforms
120
+ self._label_transforms = label_transforms
121
+
122
+ self._input.require_axes_match(self._input_label)
123
+ self._input.require_rescalable(self._input_label)
124
+
125
+ def get_init_kwargs(self) -> dict:
126
+ """Return the initialization arguments for the iterator."""
127
+ return {
128
+ "input_image": self._input,
129
+ "input_label": self._input_label,
130
+ "channel_selection": self._channel_selection,
131
+ "axes_order": self._axes_order,
132
+ "input_transforms": self._input_transforms,
133
+ "label_transforms": self._label_transforms,
134
+ }
135
+
136
+ def build_numpy_getter(self, roi: Roi) -> NumpyFeatureGetter:
137
+ data_getter = NumpyRoiGetter(
138
+ zarr_array=self._input.zarr_array,
139
+ dimensions=self._input.dimensions,
140
+ axes_order=self._axes_order,
141
+ transforms=self._input_transforms,
142
+ roi=roi,
143
+ slicing_dict=self._input_slicing_kwargs,
144
+ )
145
+ label_getter = NumpyRoiGetter(
146
+ zarr_array=self._input_label.zarr_array,
147
+ dimensions=self._input_label.dimensions,
148
+ axes_order=self._axes_order,
149
+ transforms=self._label_transforms,
150
+ roi=roi,
151
+ remove_channel_selection=True,
152
+ )
153
+ return NumpyFeatureGetter(data_getter, label_getter)
154
+
155
+ def build_dask_getter(self, roi: Roi) -> DaskFeatureGetter:
156
+ data_getter = DaskRoiGetter(
157
+ zarr_array=self._input.zarr_array,
158
+ dimensions=self._input.dimensions,
159
+ axes_order=self._axes_order,
160
+ transforms=self._input_transforms,
161
+ roi=roi,
162
+ slicing_dict=self._input_slicing_kwargs,
163
+ )
164
+ label_getter = DaskRoiGetter(
165
+ zarr_array=self._input_label.zarr_array,
166
+ dimensions=self._input_label.dimensions,
167
+ axes_order=self._axes_order,
168
+ transforms=self._label_transforms,
169
+ roi=roi,
170
+ remove_channel_selection=True,
171
+ )
172
+ return DaskFeatureGetter(data_getter, label_getter)
173
+
174
+ def build_numpy_setter(self, roi: Roi) -> None:
175
+ return None
176
+
177
+ def build_dask_setter(self, roi: Roi) -> None:
178
+ return None
179
+
180
+ def post_consolidate(self):
181
+ pass
182
+
183
+ def iter_as_numpy(self): # type: ignore[override]
184
+ """Create an iterator over the pixels of the ROIs."""
185
+ return self.iter(lazy=False, data_mode="numpy", iterator_mode="readonly")
186
+
187
+ def iter_as_dask(self): # type: ignore[override]
188
+ """Create an iterator over the pixels of the ROIs."""
189
+ return self.iter(lazy=False, data_mode="dask", iterator_mode="readonly")
@@ -0,0 +1,130 @@
1
+ from collections.abc import Sequence
2
+
3
+ import dask.array as da
4
+ import numpy as np
5
+
6
+ from ngio.common import Roi
7
+ from ngio.experimental.iterators._abstract_iterator import AbstractIteratorBuilder
8
+ from ngio.images import Image
9
+ from ngio.images._image import (
10
+ ChannelSlicingInputType,
11
+ add_channel_selection_to_slicing_dict,
12
+ )
13
+ from ngio.io_pipes import (
14
+ DaskRoiGetter,
15
+ DaskRoiSetter,
16
+ NumpyRoiGetter,
17
+ NumpyRoiSetter,
18
+ TransformProtocol,
19
+ )
20
+ from ngio.io_pipes._io_pipes_types import DataGetterProtocol, DataSetterProtocol
21
+
22
+
23
+ class ImageProcessingIterator(AbstractIteratorBuilder[np.ndarray, da.Array]):
24
+ """Base class for iterators over ROIs."""
25
+
26
+ def __init__(
27
+ self,
28
+ input_image: Image,
29
+ output_image: Image,
30
+ input_channel_selection: ChannelSlicingInputType = None,
31
+ output_channel_selection: ChannelSlicingInputType = None,
32
+ axes_order: Sequence[str] | None = None,
33
+ input_transforms: Sequence[TransformProtocol] | None = None,
34
+ output_transforms: Sequence[TransformProtocol] | None = None,
35
+ ) -> None:
36
+ """Initialize the iterator with a ROI table and input/output images.
37
+
38
+ Args:
39
+ input_image (Image): The input image to be used as input for the
40
+ segmentation.
41
+ output_image (Image): The image where the ROIs will be written.
42
+ input_channel_selection (ChannelSlicingInputType): Optional
43
+ selection of channels to use for the input image.
44
+ output_channel_selection (ChannelSlicingInputType): Optional
45
+ selection of channels to use for the output image.
46
+ axes_order (Sequence[str] | None): Optional axes order for the
47
+ segmentation.
48
+ input_transforms (Sequence[TransformProtocol] | None): Optional
49
+ transforms to apply to the input image.
50
+ output_transforms (Sequence[TransformProtocol] | None): Optional
51
+ transforms to apply to the output label.
52
+ """
53
+ self._input = input_image
54
+ self._output = output_image
55
+ self._ref_image = input_image
56
+ self._rois = input_image.build_image_roi_table(name=None).rois()
57
+
58
+ # Set iteration parameters
59
+ self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
60
+ image=self._input,
61
+ channel_selection=input_channel_selection,
62
+ slicing_dict={},
63
+ )
64
+ self._output_slicing_kwargs = add_channel_selection_to_slicing_dict(
65
+ image=self._output,
66
+ channel_selection=output_channel_selection,
67
+ slicing_dict={},
68
+ )
69
+ self._input_channel_selection = input_channel_selection
70
+ self._output_channel_selection = output_channel_selection
71
+ self._axes_order = axes_order
72
+ self._input_transforms = input_transforms
73
+ self._output_transforms = output_transforms
74
+
75
+ self._input.require_dimensions_match(self._output, allow_singleton=True)
76
+
77
+ def get_init_kwargs(self) -> dict:
78
+ """Return the initialization arguments for the iterator."""
79
+ return {
80
+ "input_image": self._input,
81
+ "output_image": self._output,
82
+ "input_channel_selection": self._input_channel_selection,
83
+ "output_channel_selection": self._output_channel_selection,
84
+ "axes_order": self._axes_order,
85
+ "input_transforms": self._input_transforms,
86
+ "output_transforms": self._output_transforms,
87
+ }
88
+
89
+ def build_numpy_getter(self, roi: Roi) -> DataGetterProtocol[np.ndarray]:
90
+ return NumpyRoiGetter(
91
+ zarr_array=self._input.zarr_array,
92
+ dimensions=self._input.dimensions,
93
+ roi=roi,
94
+ axes_order=self._axes_order,
95
+ transforms=self._input_transforms,
96
+ slicing_dict=self._input_slicing_kwargs,
97
+ )
98
+
99
+ def build_numpy_setter(self, roi: Roi) -> DataSetterProtocol[np.ndarray]:
100
+ return NumpyRoiSetter(
101
+ zarr_array=self._output.zarr_array,
102
+ dimensions=self._output.dimensions,
103
+ roi=roi,
104
+ axes_order=self._axes_order,
105
+ transforms=self._output_transforms,
106
+ slicing_dict=self._output_slicing_kwargs,
107
+ )
108
+
109
+ def build_dask_getter(self, roi: Roi) -> DataGetterProtocol[da.Array]:
110
+ return DaskRoiGetter(
111
+ zarr_array=self._input.zarr_array,
112
+ dimensions=self._input.dimensions,
113
+ roi=roi,
114
+ axes_order=self._axes_order,
115
+ transforms=self._input_transforms,
116
+ slicing_dict=self._input_slicing_kwargs,
117
+ )
118
+
119
+ def build_dask_setter(self, roi: Roi) -> DataSetterProtocol[da.Array]:
120
+ return DaskRoiSetter(
121
+ zarr_array=self._output.zarr_array,
122
+ dimensions=self._output.dimensions,
123
+ roi=roi,
124
+ axes_order=self._axes_order,
125
+ transforms=self._output_transforms,
126
+ slicing_dict=self._output_slicing_kwargs,
127
+ )
128
+
129
+ def post_consolidate(self):
130
+ self._output.consolidate()
@@ -0,0 +1,48 @@
1
+ """Mappers for iterators.
2
+
3
+ Mappers are classes that can be passed to the `map` method of iterators to
4
+ transform the items yielded by the iterator.
5
+
6
+ """
7
+
8
+ from collections.abc import Callable, Iterable
9
+ from typing import Generic, Protocol, TypeVar
10
+
11
+ from ngio.io_pipes._io_pipes_types import DataGetterProtocol, DataSetterProtocol
12
+ from ngio.utils import NgioValueError
13
+
14
+ T = TypeVar("T")
15
+
16
+
17
+ class MapperProtocol(Protocol[T]):
18
+ """Protocol for mappers."""
19
+
20
+ def __call__(
21
+ self,
22
+ func: Callable[[T], T],
23
+ getters: Iterable[DataGetterProtocol[T]],
24
+ setters: Iterable[DataSetterProtocol[T] | None],
25
+ ) -> None:
26
+ """Map an item to another item."""
27
+ ...
28
+
29
+
30
+ class BasicMapper(Generic[T]):
31
+ """A basic mapper that simply applies a function to the data."""
32
+
33
+ def __call__(
34
+ self,
35
+ func: Callable[[T], T],
36
+ getters: Iterable[DataGetterProtocol[T]],
37
+ setters: Iterable[DataSetterProtocol[T] | None],
38
+ ) -> None:
39
+ """Map an item to another item."""
40
+ for getter, setter in zip(getters, setters, strict=True):
41
+ data = getter()
42
+ data = func(data)
43
+ if setter is None:
44
+ raise NgioValueError(
45
+ "Error in BasicMapper: setter is None, "
46
+ "this iterator is read-only, mapping is not possible."
47
+ )
48
+ setter(data)
@@ -0,0 +1,127 @@
1
+ from ngio import Roi, RoiPixels
2
+ from ngio.images._abstract_image import AbstractImage
3
+
4
+
5
+ def rois_product(rois_a: list[Roi], rois_b: list[Roi]) -> list[Roi]:
6
+ """Compute the product of two sets of ROIs."""
7
+ rois_product = []
8
+ for roi_a in rois_a:
9
+ for roi_b in rois_b:
10
+ intersection = roi_a.intersection(roi_b)
11
+ if intersection:
12
+ rois_product.append(intersection)
13
+ return rois_product
14
+
15
+
16
+ def grid(
17
+ rois: list[Roi],
18
+ ref_image: AbstractImage,
19
+ size_x: int | None = None,
20
+ size_y: int | None = None,
21
+ size_z: int | None = None,
22
+ size_t: int | None = None,
23
+ stride_x: int | None = None,
24
+ stride_y: int | None = None,
25
+ stride_z: int | None = None,
26
+ stride_t: int | None = None,
27
+ base_name: str | None = None,
28
+ ) -> list[Roi]:
29
+ """This method is a placeholder for creating a regular grid of ROIs."""
30
+ t_dim = ref_image.dimensions.get("t", default=1)
31
+ z_dim = ref_image.dimensions.get("z", default=1)
32
+ y_dim = ref_image.dimensions.get("y", default=1)
33
+ x_dim = ref_image.dimensions.get("x", default=1)
34
+
35
+ size_t = size_t if size_t is not None else t_dim
36
+ size_z = size_z if size_z is not None else z_dim
37
+ size_y = size_y if size_y is not None else y_dim
38
+ size_x = size_x if size_x is not None else x_dim
39
+
40
+ stride_t = stride_t if stride_t is not None else size_t
41
+ stride_z = stride_z if stride_z is not None else size_z
42
+ stride_y = stride_y if stride_y is not None else size_y
43
+ stride_x = stride_x if stride_x is not None else size_x
44
+
45
+ # Here we would create a grid of ROIs based on the specified parameters.
46
+ new_rois = []
47
+ for t in range(0, t_dim, stride_t):
48
+ for z in range(0, z_dim, stride_z):
49
+ for y in range(0, y_dim, stride_y):
50
+ for x in range(0, x_dim, stride_x):
51
+ roi = RoiPixels(
52
+ name=base_name,
53
+ x=x,
54
+ y=y,
55
+ z=z,
56
+ t=t,
57
+ x_length=size_x,
58
+ y_length=size_y,
59
+ z_length=size_z,
60
+ t_length=size_t,
61
+ )
62
+ new_rois.append(roi.to_roi(pixel_size=ref_image.pixel_size))
63
+
64
+ return rois_product(rois, new_rois)
65
+
66
+
67
+ def by_yx(rois: list[Roi], ref_image: AbstractImage) -> list[Roi]:
68
+ """Return a new iterator that iterates over ROIs by YX coordinates."""
69
+ return grid(
70
+ rois=rois,
71
+ ref_image=ref_image,
72
+ size_z=1,
73
+ stride_z=1,
74
+ size_t=1,
75
+ stride_t=1,
76
+ )
77
+
78
+
79
+ def by_zyx(rois: list[Roi], ref_image: AbstractImage, strict: bool = True) -> list[Roi]:
80
+ """Return a new iterator that iterates over ROIs by ZYX coordinates."""
81
+ if strict and not ref_image.is_3d:
82
+ raise ValueError(
83
+ "Reference Input image must be 3D to iterate by ZXY coordinates. "
84
+ f"Current dimensions: {ref_image.dimensions}"
85
+ )
86
+ return grid(
87
+ rois=rois,
88
+ ref_image=ref_image,
89
+ size_t=1,
90
+ stride_t=1,
91
+ )
92
+
93
+
94
+ def by_chunks(
95
+ rois: list[Roi],
96
+ ref_image: AbstractImage,
97
+ overlap_xy: int = 0,
98
+ overlap_z: int = 0,
99
+ overlap_t: int = 0,
100
+ ) -> list[Roi]:
101
+ """This method is a placeholder for chunked processing."""
102
+ chunk_size = ref_image.chunks
103
+ t_axis = ref_image.axes_handler.get_index("t")
104
+ z_axis = ref_image.axes_handler.get_index("z")
105
+ y_axis = ref_image.axes_handler.get_index("y")
106
+ x_axis = ref_image.axes_handler.get_index("x")
107
+
108
+ size_x = chunk_size[x_axis] if x_axis is not None else None
109
+ size_y = chunk_size[y_axis] if y_axis is not None else None
110
+ size_z = chunk_size[z_axis] if z_axis is not None else None
111
+ size_t = chunk_size[t_axis] if t_axis is not None else None
112
+ stride_x = size_x - overlap_xy if size_x is not None else None
113
+ stride_y = size_y - overlap_xy if size_y is not None else None
114
+ stride_z = size_z - overlap_z if size_z is not None else None
115
+ stride_t = size_t - overlap_t if size_t is not None else None
116
+ return grid(
117
+ rois=rois,
118
+ ref_image=ref_image,
119
+ size_x=size_x,
120
+ size_y=size_y,
121
+ size_z=size_z,
122
+ size_t=size_t,
123
+ stride_x=stride_x,
124
+ stride_y=stride_y,
125
+ stride_z=stride_z,
126
+ stride_t=stride_t,
127
+ )