senoquant 1.0.0b1__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 (148) hide show
  1. senoquant/__init__.py +6 -0
  2. senoquant/_reader.py +7 -0
  3. senoquant/_widget.py +33 -0
  4. senoquant/napari.yaml +83 -0
  5. senoquant/reader/__init__.py +5 -0
  6. senoquant/reader/core.py +369 -0
  7. senoquant/tabs/__init__.py +15 -0
  8. senoquant/tabs/batch/__init__.py +10 -0
  9. senoquant/tabs/batch/backend.py +641 -0
  10. senoquant/tabs/batch/config.py +270 -0
  11. senoquant/tabs/batch/frontend.py +1283 -0
  12. senoquant/tabs/batch/io.py +326 -0
  13. senoquant/tabs/batch/layers.py +86 -0
  14. senoquant/tabs/quantification/__init__.py +1 -0
  15. senoquant/tabs/quantification/backend.py +228 -0
  16. senoquant/tabs/quantification/features/__init__.py +80 -0
  17. senoquant/tabs/quantification/features/base.py +142 -0
  18. senoquant/tabs/quantification/features/marker/__init__.py +5 -0
  19. senoquant/tabs/quantification/features/marker/config.py +69 -0
  20. senoquant/tabs/quantification/features/marker/dialog.py +437 -0
  21. senoquant/tabs/quantification/features/marker/export.py +879 -0
  22. senoquant/tabs/quantification/features/marker/feature.py +119 -0
  23. senoquant/tabs/quantification/features/marker/morphology.py +285 -0
  24. senoquant/tabs/quantification/features/marker/rows.py +654 -0
  25. senoquant/tabs/quantification/features/marker/thresholding.py +46 -0
  26. senoquant/tabs/quantification/features/roi.py +346 -0
  27. senoquant/tabs/quantification/features/spots/__init__.py +5 -0
  28. senoquant/tabs/quantification/features/spots/config.py +62 -0
  29. senoquant/tabs/quantification/features/spots/dialog.py +477 -0
  30. senoquant/tabs/quantification/features/spots/export.py +1292 -0
  31. senoquant/tabs/quantification/features/spots/feature.py +112 -0
  32. senoquant/tabs/quantification/features/spots/morphology.py +279 -0
  33. senoquant/tabs/quantification/features/spots/rows.py +241 -0
  34. senoquant/tabs/quantification/frontend.py +815 -0
  35. senoquant/tabs/segmentation/__init__.py +1 -0
  36. senoquant/tabs/segmentation/backend.py +131 -0
  37. senoquant/tabs/segmentation/frontend.py +1009 -0
  38. senoquant/tabs/segmentation/models/__init__.py +5 -0
  39. senoquant/tabs/segmentation/models/base.py +146 -0
  40. senoquant/tabs/segmentation/models/cpsam/details.json +65 -0
  41. senoquant/tabs/segmentation/models/cpsam/model.py +150 -0
  42. senoquant/tabs/segmentation/models/default_2d/details.json +69 -0
  43. senoquant/tabs/segmentation/models/default_2d/model.py +664 -0
  44. senoquant/tabs/segmentation/models/default_3d/details.json +69 -0
  45. senoquant/tabs/segmentation/models/default_3d/model.py +682 -0
  46. senoquant/tabs/segmentation/models/hf.py +71 -0
  47. senoquant/tabs/segmentation/models/nuclear_dilation/__init__.py +1 -0
  48. senoquant/tabs/segmentation/models/nuclear_dilation/details.json +26 -0
  49. senoquant/tabs/segmentation/models/nuclear_dilation/model.py +96 -0
  50. senoquant/tabs/segmentation/models/perinuclear_rings/__init__.py +1 -0
  51. senoquant/tabs/segmentation/models/perinuclear_rings/details.json +34 -0
  52. senoquant/tabs/segmentation/models/perinuclear_rings/model.py +132 -0
  53. senoquant/tabs/segmentation/stardist_onnx_utils/__init__.py +2 -0
  54. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/__init__.py +3 -0
  55. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/data/__init__.py +6 -0
  56. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/data/generate.py +470 -0
  57. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/data/prepare.py +273 -0
  58. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/data/rawdata.py +112 -0
  59. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/data/transform.py +384 -0
  60. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/__init__.py +0 -0
  61. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/blocks.py +184 -0
  62. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/losses.py +79 -0
  63. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/nets.py +165 -0
  64. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/predict.py +467 -0
  65. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/probability.py +67 -0
  66. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/internals/train.py +148 -0
  67. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/io/__init__.py +163 -0
  68. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/__init__.py +52 -0
  69. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/base_model.py +329 -0
  70. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/care_isotropic.py +160 -0
  71. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/care_projection.py +178 -0
  72. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/care_standard.py +446 -0
  73. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/care_upsampling.py +54 -0
  74. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/config.py +254 -0
  75. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/models/pretrained.py +119 -0
  76. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/scripts/__init__.py +0 -0
  77. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/scripts/care_predict.py +180 -0
  78. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/utils/__init__.py +5 -0
  79. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/utils/plot_utils.py +159 -0
  80. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/utils/six.py +18 -0
  81. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/utils/tf.py +644 -0
  82. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/utils/utils.py +272 -0
  83. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/csbdeep/version.py +1 -0
  84. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/docs/source/conf.py +368 -0
  85. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/setup.py +68 -0
  86. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/tests/test_datagen.py +169 -0
  87. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/tests/test_models.py +462 -0
  88. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/tests/test_utils.py +166 -0
  89. senoquant/tabs/segmentation/stardist_onnx_utils/_csbdeep/tools/create_zip_contents.py +34 -0
  90. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/__init__.py +30 -0
  91. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/big.py +624 -0
  92. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/bioimageio_utils.py +494 -0
  93. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/data/__init__.py +39 -0
  94. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/geometry/__init__.py +10 -0
  95. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/geometry/geom2d.py +215 -0
  96. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/geometry/geom3d.py +349 -0
  97. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/matching.py +483 -0
  98. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/models/__init__.py +28 -0
  99. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/models/base.py +1217 -0
  100. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/models/model2d.py +594 -0
  101. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/models/model3d.py +696 -0
  102. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/nms.py +384 -0
  103. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/plot/__init__.py +2 -0
  104. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/plot/plot.py +74 -0
  105. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/plot/render.py +298 -0
  106. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/rays3d.py +373 -0
  107. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/sample_patches.py +65 -0
  108. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/scripts/__init__.py +0 -0
  109. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/scripts/predict2d.py +90 -0
  110. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/scripts/predict3d.py +93 -0
  111. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/utils.py +408 -0
  112. senoquant/tabs/segmentation/stardist_onnx_utils/_stardist/version.py +1 -0
  113. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/__init__.py +45 -0
  114. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/convert/__init__.py +17 -0
  115. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/convert/cli.py +55 -0
  116. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/convert/core.py +285 -0
  117. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/__init__.py +15 -0
  118. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/cli.py +36 -0
  119. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/divisibility.py +193 -0
  120. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/probe.py +100 -0
  121. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/receptive_field.py +182 -0
  122. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/rf_cli.py +48 -0
  123. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/inspect/valid_sizes.py +278 -0
  124. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/post/__init__.py +8 -0
  125. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/post/core.py +157 -0
  126. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/pre/__init__.py +17 -0
  127. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/pre/core.py +226 -0
  128. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/predict/__init__.py +5 -0
  129. senoquant/tabs/segmentation/stardist_onnx_utils/onnx_framework/predict/core.py +401 -0
  130. senoquant/tabs/settings/__init__.py +1 -0
  131. senoquant/tabs/settings/backend.py +29 -0
  132. senoquant/tabs/settings/frontend.py +19 -0
  133. senoquant/tabs/spots/__init__.py +1 -0
  134. senoquant/tabs/spots/backend.py +139 -0
  135. senoquant/tabs/spots/frontend.py +800 -0
  136. senoquant/tabs/spots/models/__init__.py +5 -0
  137. senoquant/tabs/spots/models/base.py +94 -0
  138. senoquant/tabs/spots/models/rmp/details.json +61 -0
  139. senoquant/tabs/spots/models/rmp/model.py +499 -0
  140. senoquant/tabs/spots/models/udwt/details.json +103 -0
  141. senoquant/tabs/spots/models/udwt/model.py +482 -0
  142. senoquant/utils.py +25 -0
  143. senoquant-1.0.0b1.dist-info/METADATA +193 -0
  144. senoquant-1.0.0b1.dist-info/RECORD +148 -0
  145. senoquant-1.0.0b1.dist-info/WHEEL +5 -0
  146. senoquant-1.0.0b1.dist-info/entry_points.txt +2 -0
  147. senoquant-1.0.0b1.dist-info/licenses/LICENSE +28 -0
  148. senoquant-1.0.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,273 @@
1
+ from __future__ import print_function, unicode_literals, absolute_import, division
2
+ from six.moves import range, zip, map, reduce, filter
3
+
4
+
5
+ from ..utils import _raise, consume, normalize_mi_ma, axes_dict, axes_check_and_normalize, move_image_axes
6
+ import warnings
7
+ import numpy as np
8
+
9
+
10
+ from six import add_metaclass
11
+ from abc import ABCMeta, abstractmethod, abstractproperty
12
+
13
+
14
+
15
+ @add_metaclass(ABCMeta)
16
+ class Normalizer():
17
+ """Abstract base class for normalization methods."""
18
+
19
+ @abstractmethod
20
+ def before(self, x, axes):
21
+ """Normalization of the raw input image (method stub).
22
+
23
+ Parameters
24
+ ----------
25
+ x : :class:`numpy.ndarray`
26
+ Raw input image.
27
+ axes : str
28
+ Axes of input image x
29
+
30
+ Returns
31
+ -------
32
+ :class:`numpy.ndarray`
33
+ Normalized input image with suitable values for neural network input.
34
+ """
35
+
36
+ @abstractmethod
37
+ def after(self, mean, scale, axes):
38
+ """Possible adjustment of predicted restored image (method stub).
39
+
40
+ Parameters
41
+ ----------
42
+ mean : :class:`numpy.ndarray`
43
+ Predicted restored image or per-pixel ``mean`` of Laplace distributions
44
+ for probabilistic model.
45
+ scale: :class:`numpy.ndarray` or None
46
+ Per-pixel ``scale`` of Laplace distributions for probabilistic model (``None`` otherwise.)
47
+ axes : str
48
+ Axes of ``mean`` and ``scale``
49
+
50
+ Returns
51
+ -------
52
+ :class:`numpy.ndarray`
53
+ Adjusted restored image(s).
54
+ """
55
+
56
+ def __call__(self, x, axes):
57
+ """Alias for :func:`before` to make this callable."""
58
+ return self.before(x, axes)
59
+
60
+ @abstractproperty
61
+ def do_after(self):
62
+ """bool : Flag to indicate whether :func:`after` should be called."""
63
+
64
+
65
+ class NoNormalizer(Normalizer):
66
+ """No normalization.
67
+
68
+ Parameters
69
+ ----------
70
+ do_after : bool
71
+ Flag to indicate whether to undo normalization.
72
+
73
+ Raises
74
+ ------
75
+ ValueError
76
+ If :func:`after` is called, but parameter `do_after` was set to ``False`` in the constructor.
77
+ """
78
+
79
+ def __init__(self, do_after=False):
80
+ self._do_after = do_after
81
+
82
+ def before(self, x, axes):
83
+ return x
84
+
85
+ def after(self, mean, scale, axes):
86
+ self.do_after or _raise(ValueError())
87
+ return mean, scale
88
+
89
+ @property
90
+ def do_after(self):
91
+ return self._do_after
92
+
93
+
94
+ class PercentileNormalizer(Normalizer):
95
+ """Percentile-based image normalization.
96
+
97
+ Parameters
98
+ ----------
99
+ pmin : float
100
+ Low percentile.
101
+ pmax : float
102
+ High percentile.
103
+ do_after : bool
104
+ Flag to indicate whether to undo normalization (original data type will not be restored).
105
+ dtype : type
106
+ Data type after normalization.
107
+ kwargs : dict
108
+ Keyword arguments for :func:`csbdeep.utils.normalize_mi_ma`.
109
+ """
110
+
111
+ def __init__(self, pmin=2, pmax=99.8, do_after=True, dtype=np.float32, **kwargs):
112
+ """TODO."""
113
+ (np.isscalar(pmin) and np.isscalar(pmax) and 0 <= pmin < pmax <= 100) or _raise(ValueError())
114
+ self.pmin = pmin
115
+ self.pmax = pmax
116
+ self._do_after = do_after
117
+ self.dtype = dtype
118
+ self.kwargs = kwargs
119
+
120
+ def before(self, x, axes):
121
+ """Percentile-based normalization of raw input image.
122
+
123
+ See :func:`csbdeep.predict.Normalizer.before` for parameter descriptions.
124
+ Note that percentiles are computed individually for each channel (if present in `axes`).
125
+ """
126
+ self.axes_before = axes_check_and_normalize(axes,x.ndim)
127
+ axis = tuple(d for d,a in enumerate(self.axes_before) if a != 'C')
128
+ self.mi = np.percentile(x,self.pmin,axis=axis,keepdims=True).astype(self.dtype,copy=False)
129
+ self.ma = np.percentile(x,self.pmax,axis=axis,keepdims=True).astype(self.dtype,copy=False)
130
+ return normalize_mi_ma(x, self.mi, self.ma, dtype=self.dtype, **self.kwargs)
131
+
132
+ def after(self, mean, scale, axes):
133
+ """Undo percentile-based normalization to map restored image to similar range as input image.
134
+
135
+ See :func:`csbdeep.predict.Normalizer.after` for parameter descriptions.
136
+
137
+ Raises
138
+ ------
139
+ ValueError
140
+ If parameter `do_after` was set to ``False`` in the constructor.
141
+
142
+ """
143
+ self.do_after or _raise(ValueError())
144
+ self.axes_after = axes_check_and_normalize(axes,mean.ndim)
145
+ mi = move_image_axes(self.mi, self.axes_before, self.axes_after, True)
146
+ ma = move_image_axes(self.ma, self.axes_before, self.axes_after, True)
147
+ alpha = ma - mi
148
+ beta = mi
149
+ return (
150
+ ( alpha*mean+beta ).astype(self.dtype,copy=False),
151
+ ( alpha*scale ).astype(self.dtype,copy=False) if scale is not None else None
152
+ )
153
+
154
+ @property
155
+ def do_after(self):
156
+ """``do_after`` parameter from constructor."""
157
+ return self._do_after
158
+
159
+
160
+
161
+ @add_metaclass(ABCMeta)
162
+ class Resizer():
163
+ """Abstract base class for resizing methods."""
164
+
165
+ @abstractmethod
166
+ def before(self, x, axes, axes_div_by):
167
+ """Resizing of the raw input image (method stub).
168
+
169
+ Parameters
170
+ ----------
171
+ x : :class:`numpy.ndarray`
172
+ Raw input image.
173
+ axes : str
174
+ Axes of input image x
175
+ axes_div_by : iterable of int
176
+ Resized image must be evenly divisible by the provided values for each axis.
177
+
178
+ Returns
179
+ -------
180
+ :class:`numpy.ndarray`
181
+ Resized input image.
182
+ """
183
+
184
+ @abstractmethod
185
+ def after(self, x, axes):
186
+ """Resizing of the restored image (method stub).
187
+
188
+ Parameters
189
+ ----------
190
+ x : :class:`numpy.ndarray`
191
+ Restored image.
192
+ axes : str
193
+ Axes of restored image x
194
+
195
+ Returns
196
+ -------
197
+ :class:`numpy.ndarray`
198
+ Resized restored image.
199
+ """
200
+
201
+
202
+ class NoResizer(Resizer):
203
+ """No resizing.
204
+
205
+ Raises
206
+ ------
207
+ ValueError
208
+ In :func:`before`, if image resizing is necessary.
209
+ """
210
+
211
+ def before(self, x, axes, axes_div_by):
212
+ axes = axes_check_and_normalize(axes,x.ndim)
213
+ consume (
214
+ (s%div_n==0) or _raise(ValueError('%d (axis %s) is not divisible by %d.' % (s,a,div_n)))
215
+ for a, div_n, s in zip(axes, axes_div_by, x.shape)
216
+ )
217
+ return x
218
+
219
+ def after(self, x, axes):
220
+ return x
221
+
222
+
223
+ class PadAndCropResizer(Resizer):
224
+ """Resize image by padding and cropping.
225
+
226
+ If necessary, input image is padded before prediction
227
+ and restored image is cropped back to size of input image
228
+ after prediction.
229
+
230
+ Parameters
231
+ ----------
232
+ mode : str
233
+ Parameter ``mode`` of :func:`numpy.pad` that
234
+ controls how the image is padded.
235
+ kwargs : dict
236
+ Keyword arguments for :func:`numpy.pad`.
237
+ """
238
+
239
+ def __init__(self, mode='reflect', **kwargs):
240
+ """TODO."""
241
+ self.mode = mode
242
+ self.kwargs = kwargs
243
+
244
+ def before(self, x, axes, axes_div_by):
245
+ """Pad input image.
246
+
247
+ See :func:`csbdeep.predict.Resizer.before` for parameter descriptions.
248
+ """
249
+ axes = axes_check_and_normalize(axes,x.ndim)
250
+ def _split(v):
251
+ a = v // 2
252
+ return a, v-a
253
+ self.pad = {
254
+ a : _split((div_n-s%div_n)%div_n)
255
+ for a, div_n, s in zip(axes, axes_div_by, x.shape)
256
+ }
257
+ # print(self.pad)
258
+ x_pad = np.pad(x, tuple(self.pad[a] for a in axes), mode=self.mode, **self.kwargs)
259
+ return x_pad
260
+
261
+ def after(self, x, axes):
262
+ """Crop restored image to retain size of input image.
263
+
264
+ See :func:`csbdeep.predict.Resizer.after` for parameter descriptions.
265
+ """
266
+ axes = axes_check_and_normalize(axes,x.ndim)
267
+ all(a in self.pad for a in axes) or _raise(ValueError())
268
+ crop = tuple (
269
+ slice(p[0], -p[1] if p[1]>0 else None)
270
+ for p in (self.pad[a] for a in axes)
271
+ )
272
+ # print(crop)
273
+ return x[crop]
@@ -0,0 +1,112 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import print_function, unicode_literals, absolute_import, division
3
+ from six.moves import zip
4
+ from tifffile import imread
5
+ from collections import namedtuple
6
+ from itertools import chain
7
+
8
+ from ..utils import _raise, consume, axes_check_and_normalize
9
+ from ..utils.six import Path, FileNotFoundError
10
+
11
+
12
+
13
+ class RawData(namedtuple('RawData' ,('generator' ,'size' ,'description'))):
14
+ """:func:`collections.namedtuple` with three fields: `generator`, `size`, and `description`.
15
+
16
+ Parameters
17
+ ----------
18
+ generator : function
19
+ Function without arguments that returns a generator that yields tuples `(x,y,axes,mask)`,
20
+ where `x` is a source image (e.g., with low SNR) with `y` being the corresponding target image
21
+ (e.g., with high SNR); `mask` can either be `None` or a boolean array that denotes which
22
+ pixels are eligible to extracted in :func:`create_patches`. Note that `x`, `y`, and `mask`
23
+ must all be of type :class:`numpy.ndarray` and are assumed to have the same shape, where the
24
+ string `axes` indicates the order and presence of axes of all three arrays.
25
+ size : int
26
+ Number of tuples that the `generator` will yield.
27
+ description : str
28
+ Textual description of the raw data.
29
+ """
30
+
31
+ @staticmethod
32
+ def from_folder(basepath, source_dirs, target_dir, axes='CZYX', pattern='*.tif*'):
33
+ """Get pairs of corresponding TIFF images read from folders.
34
+
35
+ Two images correspond to each other if they have the same file name, but are located in different folders.
36
+
37
+ Parameters
38
+ ----------
39
+ basepath : str
40
+ Base folder that contains sub-folders with images.
41
+ source_dirs : list or tuple
42
+ List of folder names relative to `basepath` that contain the source images (e.g., with low SNR).
43
+ target_dir : str
44
+ Folder name relative to `basepath` that contains the target images (e.g., with high SNR).
45
+ axes : str
46
+ Semantics of axes of loaded images (assumed to be the same for all images).
47
+ pattern : str
48
+ Glob-style pattern to match the desired TIFF images.
49
+
50
+ Returns
51
+ -------
52
+ RawData
53
+ :obj:`RawData` object, whose `generator` is used to yield all matching TIFF pairs.
54
+ The generator will return a tuple `(x,y,axes,mask)`, where `x` is from
55
+ `source_dirs` and `y` is the corresponding image from the `target_dir`;
56
+ `mask` is set to `None`.
57
+
58
+ Raises
59
+ ------
60
+ FileNotFoundError
61
+ If an image found in a `source_dir` does not exist in `target_dir`.
62
+
63
+ Example
64
+ --------
65
+ >>> !tree data
66
+ data
67
+ ├── GT
68
+ │ ├── imageA.tif
69
+ │ ├── imageB.tif
70
+ │ └── imageC.tif
71
+ ├── source1
72
+ │ ├── imageA.tif
73
+ │ └── imageB.tif
74
+ └── source2
75
+ ├── imageA.tif
76
+ └── imageC.tif
77
+
78
+ >>> data = RawData.from_folder(basepath='data', source_dirs=['source1','source2'], target_dir='GT', axes='YX')
79
+ >>> n_images = data.size
80
+ >>> for source_x, target_y, axes, mask in data.generator():
81
+ ... pass
82
+
83
+ """
84
+ p = Path(basepath)
85
+ pairs = [(f, p/target_dir/f.name) for f in chain(*((p/source_dir).glob(pattern) for source_dir in source_dirs))]
86
+ len(pairs) > 0 or _raise(FileNotFoundError("Didn't find any images."))
87
+ consume(t.exists() or _raise(FileNotFoundError(t)) for s,t in pairs)
88
+ axes = axes_check_and_normalize(axes)
89
+ n_images = len(pairs)
90
+ description = "{p}: target='{o}', sources={s}, axes='{a}', pattern='{pt}'".format(p=basepath, s=list(source_dirs),
91
+ o=target_dir, a=axes, pt=pattern)
92
+
93
+ def _gen():
94
+ for fx, fy in pairs:
95
+ x, y = imread(str(fx)), imread(str(fy))
96
+ len(axes) >= x.ndim or _raise(ValueError())
97
+ yield x, y, axes[-x.ndim:], None
98
+
99
+ return RawData(_gen, n_images, description)
100
+
101
+
102
+
103
+ @staticmethod
104
+ def from_arrays(X, Y, axes='CZYX'):
105
+ """Get pairs of corresponding images from numpy arrays."""
106
+
107
+ def _gen():
108
+ for x, y in zip(X ,Y):
109
+ len(axes) >= x.ndim or _raise(ValueError())
110
+ yield x, y, axes[-x.ndim:], None
111
+
112
+ return RawData(_gen, len(X), "numpy array")