careamics 0.1.0rc3__py3-none-any.whl → 0.1.0rc5__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.
Potentially problematic release.
This version of careamics might be problematic. Click here for more details.
- careamics/__init__.py +8 -6
- careamics/careamist.py +30 -29
- careamics/config/__init__.py +12 -9
- careamics/config/algorithm_model.py +5 -5
- careamics/config/architectures/unet_model.py +1 -0
- careamics/config/callback_model.py +1 -0
- careamics/config/configuration_example.py +87 -0
- careamics/config/configuration_factory.py +285 -78
- careamics/config/configuration_model.py +22 -23
- careamics/config/data_model.py +62 -160
- careamics/config/inference_model.py +20 -21
- careamics/config/references/algorithm_descriptions.py +1 -0
- careamics/config/references/references.py +1 -0
- careamics/config/support/supported_extraction_strategies.py +1 -0
- careamics/config/support/supported_optimizers.py +3 -3
- careamics/config/training_model.py +2 -1
- careamics/config/transformations/n2v_manipulate_model.py +2 -1
- careamics/config/transformations/nd_flip_model.py +7 -12
- careamics/config/transformations/normalize_model.py +2 -1
- careamics/config/transformations/transform_model.py +1 -0
- careamics/config/transformations/xy_random_rotate90_model.py +7 -9
- careamics/config/validators/validator_utils.py +1 -0
- careamics/conftest.py +1 -0
- careamics/dataset/dataset_utils/__init__.py +0 -1
- careamics/dataset/dataset_utils/dataset_utils.py +1 -0
- careamics/dataset/in_memory_dataset.py +17 -48
- careamics/dataset/iterable_dataset.py +16 -71
- careamics/dataset/patching/__init__.py +0 -7
- careamics/dataset/patching/patching.py +1 -0
- careamics/dataset/patching/sequential_patching.py +6 -6
- careamics/dataset/patching/tiled_patching.py +10 -6
- careamics/lightning_datamodule.py +123 -49
- careamics/lightning_module.py +7 -7
- careamics/lightning_prediction_datamodule.py +59 -48
- careamics/losses/__init__.py +0 -1
- careamics/losses/loss_factory.py +1 -0
- careamics/model_io/__init__.py +0 -1
- careamics/model_io/bioimage/_readme_factory.py +2 -1
- careamics/model_io/bioimage/bioimage_utils.py +1 -0
- careamics/model_io/bioimage/model_description.py +4 -3
- careamics/model_io/bmz_io.py +8 -7
- careamics/model_io/model_io_utils.py +4 -4
- careamics/models/layers.py +1 -0
- careamics/models/model_factory.py +1 -0
- careamics/models/unet.py +91 -17
- careamics/prediction/stitch_prediction.py +1 -0
- careamics/transforms/__init__.py +2 -23
- careamics/transforms/compose.py +98 -0
- careamics/transforms/n2v_manipulate.py +18 -23
- careamics/transforms/nd_flip.py +38 -64
- careamics/transforms/normalize.py +45 -34
- careamics/transforms/pixel_manipulation.py +2 -2
- careamics/transforms/transform.py +33 -0
- careamics/transforms/tta.py +2 -2
- careamics/transforms/xy_random_rotate90.py +41 -68
- careamics/utils/__init__.py +0 -1
- careamics/utils/context.py +1 -0
- careamics/utils/logging.py +1 -0
- careamics/utils/metrics.py +1 -0
- careamics/utils/torch_utils.py +1 -0
- {careamics-0.1.0rc3.dist-info → careamics-0.1.0rc5.dist-info}/METADATA +16 -61
- careamics-0.1.0rc5.dist-info/RECORD +111 -0
- careamics/dataset/patching/patch_transform.py +0 -44
- careamics-0.1.0rc3.dist-info/RECORD +0 -109
- {careamics-0.1.0rc3.dist-info → careamics-0.1.0rc5.dist-info}/WHEEL +0 -0
- {careamics-0.1.0rc3.dist-info → careamics-0.1.0rc5.dist-info}/licenses/LICENSE +0 -0
careamics/transforms/nd_flip.py
CHANGED
|
@@ -1,93 +1,67 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Optional, Tuple
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
from albumentations import DualTransform
|
|
5
4
|
|
|
5
|
+
from careamics.transforms.transform import Transform
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
class NDFlip(Transform):
|
|
8
9
|
"""Flip ND arrays on a single axis.
|
|
9
10
|
|
|
10
11
|
This transform ignores singleton axes and randomly flips one of the other
|
|
11
|
-
|
|
12
|
+
last two axes.
|
|
12
13
|
|
|
13
|
-
This transform expects (Z)
|
|
14
|
+
This transform expects C(Z)YX dimensions.
|
|
14
15
|
"""
|
|
15
16
|
|
|
16
|
-
def __init__(self,
|
|
17
|
+
def __init__(self, seed: Optional[int] = None):
|
|
17
18
|
"""Constructor.
|
|
18
19
|
|
|
19
20
|
Parameters
|
|
20
21
|
----------
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
is_3D : bool, optional
|
|
24
|
-
Whether the data is 3D, by default False
|
|
25
|
-
flip_z : bool, optional
|
|
26
|
-
Whether to flip Z dimension, by default True
|
|
22
|
+
seed : Optional[int], optional
|
|
23
|
+
Random seed, by default None
|
|
27
24
|
"""
|
|
28
|
-
super().__init__(p=p)
|
|
29
|
-
|
|
30
|
-
self.is_3D = is_3D
|
|
31
|
-
self.flip_z = flip_z
|
|
32
|
-
|
|
33
25
|
# "flippable" axes
|
|
34
|
-
|
|
35
|
-
self.axis_indices = [0, 1, 2] if flip_z else [1, 2]
|
|
36
|
-
else:
|
|
37
|
-
self.axis_indices = [0, 1]
|
|
26
|
+
self.axis_indices = [-2, -1]
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Returns
|
|
43
|
-
-------
|
|
44
|
-
Dict[str, int]
|
|
45
|
-
Transform parameters.
|
|
46
|
-
"""
|
|
47
|
-
return {"flip_axis": np.random.choice(self.axis_indices)}
|
|
28
|
+
# numpy random generator
|
|
29
|
+
self.rng = np.random.default_rng(seed=seed)
|
|
48
30
|
|
|
49
|
-
def
|
|
50
|
-
|
|
31
|
+
def __call__(
|
|
32
|
+
self, patch: np.ndarray, target: Optional[np.ndarray] = None
|
|
33
|
+
) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
34
|
+
"""Apply the transform to the source patch and the target (optional).
|
|
51
35
|
|
|
52
36
|
Parameters
|
|
53
37
|
----------
|
|
54
38
|
patch : np.ndarray
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
Patch, 2D or 3D, shape C(Z)YX.
|
|
40
|
+
target : Optional[np.ndarray], optional
|
|
41
|
+
Target for the patch, by default None
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
Tuple[np.ndarray, Optional[np.ndarray]]
|
|
46
|
+
Transformed patch and target.
|
|
58
47
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
# choose an axis to flip
|
|
49
|
+
axis = self.rng.choice(self.axis_indices)
|
|
50
|
+
|
|
51
|
+
patch_transformed = self._apply(patch, axis)
|
|
52
|
+
target_transformed = self._apply(target, axis) if target is not None else None
|
|
64
53
|
|
|
65
|
-
return
|
|
54
|
+
return patch_transformed, target_transformed
|
|
66
55
|
|
|
67
|
-
def
|
|
68
|
-
|
|
69
|
-
) -> np.ndarray:
|
|
70
|
-
"""Apply the transform to the mask.
|
|
56
|
+
def _apply(self, patch: np.ndarray, axis: int) -> np.ndarray:
|
|
57
|
+
"""Apply the transform to the image.
|
|
71
58
|
|
|
72
59
|
Parameters
|
|
73
60
|
----------
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
raise ValueError(
|
|
79
|
-
"Incompatible mask shape and dimensionality. ZYXC patch shape "
|
|
80
|
-
"expected, but got YXC shape."
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
return np.ascontiguousarray(np.flip(mask, axis=flip_axis))
|
|
84
|
-
|
|
85
|
-
def get_transform_init_args_names(self, **kwargs: Any) -> Tuple[str, ...]:
|
|
86
|
-
"""Get the transform arguments names.
|
|
87
|
-
|
|
88
|
-
Returns
|
|
89
|
-
-------
|
|
90
|
-
Tuple[str, ...]
|
|
91
|
-
Transform arguments names.
|
|
61
|
+
patch : np.ndarray
|
|
62
|
+
Image or image patch, 2D or 3D, shape C(Z)YX.
|
|
63
|
+
axis : int
|
|
64
|
+
Axis to flip.
|
|
92
65
|
"""
|
|
93
|
-
|
|
66
|
+
# TODO why ascontiguousarray?
|
|
67
|
+
return np.ascontiguousarray(np.flip(patch, axis=axis))
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Optional, Tuple
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
from albumentations import DualTransform
|
|
5
4
|
|
|
5
|
+
from careamics.transforms.transform import Transform
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
class Normalize(Transform):
|
|
8
9
|
"""
|
|
9
10
|
Normalize an image or image patch.
|
|
10
11
|
|
|
11
|
-
Normalization is a zero mean and unit variance. This transform expects (Z)
|
|
12
|
+
Normalization is a zero mean and unit variance. This transform expects C(Z)YX
|
|
12
13
|
dimensions.
|
|
13
14
|
|
|
14
15
|
Not that an epsilon value of 1e-6 is added to the standard deviation to avoid
|
|
@@ -20,8 +21,6 @@ class Normalize(DualTransform):
|
|
|
20
21
|
Mean value.
|
|
21
22
|
std : float
|
|
22
23
|
Standard deviation value.
|
|
23
|
-
eps : float
|
|
24
|
-
Epsilon value to avoid division by zero.
|
|
25
24
|
"""
|
|
26
25
|
|
|
27
26
|
def __init__(
|
|
@@ -29,48 +28,42 @@ class Normalize(DualTransform):
|
|
|
29
28
|
mean: float,
|
|
30
29
|
std: float,
|
|
31
30
|
):
|
|
32
|
-
super().__init__(always_apply=True, p=1)
|
|
33
|
-
|
|
34
31
|
self.mean = mean
|
|
35
32
|
self.std = std
|
|
36
33
|
self.eps = 1e-6
|
|
37
34
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
def __call__(
|
|
36
|
+
self, patch: np.ndarray, target: Optional[np.ndarray] = None
|
|
37
|
+
) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
38
|
+
"""Apply the transform to the source patch and the target (optional).
|
|
41
39
|
|
|
42
40
|
Parameters
|
|
43
41
|
----------
|
|
44
42
|
patch : np.ndarray
|
|
45
|
-
|
|
43
|
+
Patch, 2D or 3D, shape C(Z)YX.
|
|
44
|
+
target : Optional[np.ndarray], optional
|
|
45
|
+
Target for the patch, by default None
|
|
46
46
|
|
|
47
47
|
Returns
|
|
48
48
|
-------
|
|
49
|
-
np.ndarray
|
|
50
|
-
|
|
49
|
+
Tuple[np.ndarray, Optional[np.ndarray]]
|
|
50
|
+
Transformed patch and target.
|
|
51
51
|
"""
|
|
52
|
-
|
|
52
|
+
norm_patch = self._apply(patch)
|
|
53
|
+
norm_target = self._apply(target) if target is not None else None
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
"""
|
|
56
|
-
Apply the transform to the mask.
|
|
55
|
+
return norm_patch, norm_target
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Parameters
|
|
61
|
-
----------
|
|
62
|
-
mask : np.ndarray
|
|
63
|
-
Mask or mask patch, 2D or 3D, shape (y, x, c) or (z, y, x, c).
|
|
64
|
-
"""
|
|
65
|
-
return mask
|
|
57
|
+
def _apply(self, patch: np.ndarray) -> np.ndarray:
|
|
58
|
+
return ((patch - self.mean) / (self.std + self.eps)).astype(np.float32)
|
|
66
59
|
|
|
67
60
|
|
|
68
|
-
class Denormalize
|
|
61
|
+
class Denormalize:
|
|
69
62
|
"""
|
|
70
63
|
Denormalize an image or image patch.
|
|
71
64
|
|
|
72
65
|
Denormalization is performed expecting a zero mean and unit variance input. This
|
|
73
|
-
transform expects (Z)
|
|
66
|
+
transform expects C(Z)YX dimensions.
|
|
74
67
|
|
|
75
68
|
Not that an epsilon value of 1e-6 is added to the standard deviation to avoid
|
|
76
69
|
division by zero during the normalization step, which is taken into account during
|
|
@@ -82,8 +75,6 @@ class Denormalize(DualTransform):
|
|
|
82
75
|
Mean value.
|
|
83
76
|
std : float
|
|
84
77
|
Standard deviation value.
|
|
85
|
-
eps : float
|
|
86
|
-
Epsilon value to avoid division by zero.
|
|
87
78
|
"""
|
|
88
79
|
|
|
89
80
|
def __init__(
|
|
@@ -91,19 +82,39 @@ class Denormalize(DualTransform):
|
|
|
91
82
|
mean: float,
|
|
92
83
|
std: float,
|
|
93
84
|
):
|
|
94
|
-
super().__init__(always_apply=True, p=1)
|
|
95
|
-
|
|
96
85
|
self.mean = mean
|
|
97
86
|
self.std = std
|
|
98
87
|
self.eps = 1e-6
|
|
99
88
|
|
|
100
|
-
def
|
|
89
|
+
def __call__(
|
|
90
|
+
self, patch: np.ndarray, target: Optional[np.ndarray] = None
|
|
91
|
+
) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
92
|
+
"""Apply the transform to the source patch and the target (optional).
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
patch : np.ndarray
|
|
97
|
+
Patch, 2D or 3D, shape C(Z)YX.
|
|
98
|
+
target : Optional[np.ndarray], optional
|
|
99
|
+
Target for the patch, by default None
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
Tuple[np.ndarray, Optional[np.ndarray]]
|
|
104
|
+
Transformed patch and target.
|
|
105
|
+
"""
|
|
106
|
+
norm_patch = self._apply(patch)
|
|
107
|
+
norm_target = self._apply(target) if target is not None else None
|
|
108
|
+
|
|
109
|
+
return norm_patch, norm_target
|
|
110
|
+
|
|
111
|
+
def _apply(self, patch: np.ndarray) -> np.ndarray:
|
|
101
112
|
"""
|
|
102
113
|
Apply the transform to the image.
|
|
103
114
|
|
|
104
115
|
Parameters
|
|
105
116
|
----------
|
|
106
117
|
patch : np.ndarray
|
|
107
|
-
Image or image patch, 2D or 3D, shape (
|
|
118
|
+
Image or image patch, 2D or 3D, shape C(Z)YX.
|
|
108
119
|
"""
|
|
109
120
|
return patch * (self.std + self.eps) + self.mean
|
|
@@ -4,6 +4,7 @@ Pixel manipulation methods.
|
|
|
4
4
|
Pixel manipulation is used in N2V and similar algorithm to replace the value of
|
|
5
5
|
masked pixels.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
from typing import Optional, Tuple, Union
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
@@ -246,8 +247,7 @@ def uniform_manipulate(
|
|
|
246
247
|
subpatch_size : int
|
|
247
248
|
Size of the subpatch the new pixel value is sampled from, by default 11.
|
|
248
249
|
remove_center : bool
|
|
249
|
-
Whether to remove the center pixel from the subpatch, by default False.
|
|
250
|
-
uniform with/without central pixel in the documentation. #TODO add link
|
|
250
|
+
Whether to remove the center pixel from the subpatch, by default False.
|
|
251
251
|
struct_params: Optional[StructMaskParameters]
|
|
252
252
|
Parameters for the structN2V mask (axis and span).
|
|
253
253
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""A general parent class for transforms."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Tuple
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Transform:
|
|
9
|
+
"""A general parent class for transforms."""
|
|
10
|
+
|
|
11
|
+
def __call__(
|
|
12
|
+
self, patch: np.ndarray, target: Optional[np.ndarray] = None
|
|
13
|
+
) -> Tuple[np.ndarray, ...]:
|
|
14
|
+
"""Apply the transform to the input data.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
patch : np.ndarray
|
|
19
|
+
The input data to transform.
|
|
20
|
+
target : Optional[np.ndarray], optional
|
|
21
|
+
The target data to transform, by default None
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
Tuple[np.ndarray, ...]
|
|
26
|
+
The output of the transformations.
|
|
27
|
+
|
|
28
|
+
Raises
|
|
29
|
+
------
|
|
30
|
+
NotImplementedError
|
|
31
|
+
This method should be implemented in the child class.
|
|
32
|
+
"""
|
|
33
|
+
raise NotImplementedError
|
careamics/transforms/tta.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Test-time augmentations."""
|
|
2
|
+
|
|
2
3
|
from typing import List
|
|
3
4
|
|
|
4
|
-
import numpy as np
|
|
5
5
|
from torch import Tensor, flip, mean, rot90, stack
|
|
6
6
|
|
|
7
7
|
|
|
@@ -48,7 +48,7 @@ class ImageRestorationTTA:
|
|
|
48
48
|
augmented_flip.append(flip(x_, dims=(-3, -1)))
|
|
49
49
|
return augmented_flip
|
|
50
50
|
|
|
51
|
-
def backward(self, x: List[Tensor]) ->
|
|
51
|
+
def backward(self, x: List[Tensor]) -> Tensor:
|
|
52
52
|
"""Undo the test-time augmentation.
|
|
53
53
|
|
|
54
54
|
Parameters
|
|
@@ -1,95 +1,68 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Optional, Tuple
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
from albumentations import DualTransform
|
|
5
4
|
|
|
5
|
+
from careamics.transforms.transform import Transform
|
|
6
6
|
|
|
7
|
-
class XYRandomRotate90(DualTransform):
|
|
8
|
-
"""Applies random 90 degree rotations to the YX axis.
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
class XYRandomRotate90(Transform):
|
|
9
|
+
"""Applies random 90 degree rotations to the YX axis.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
----------
|
|
14
|
-
p : int, optional
|
|
15
|
-
Probability to apply the transform, by default 0.5
|
|
16
|
-
is_3D : bool, optional
|
|
17
|
-
Whether the patches are 3D, by default False
|
|
11
|
+
This transform expects C(Z)YX dimensions.
|
|
18
12
|
"""
|
|
19
13
|
|
|
20
|
-
def __init__(self,
|
|
14
|
+
def __init__(self, seed: Optional[int] = None):
|
|
21
15
|
"""Constructor.
|
|
22
16
|
|
|
23
17
|
Parameters
|
|
24
18
|
----------
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
is_3D : bool, optional
|
|
28
|
-
Whether the patches are 3D, by default False
|
|
19
|
+
seed : Optional[int], optional
|
|
20
|
+
Random seed, by default None
|
|
29
21
|
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.is_3D = is_3D
|
|
22
|
+
# numpy random generator
|
|
23
|
+
self.rng = np.random.default_rng(seed=seed)
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
self.axes = (0, 1)
|
|
25
|
+
def __call__(
|
|
26
|
+
self, patch: np.ndarray, target: Optional[np.ndarray] = None
|
|
27
|
+
) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
28
|
+
"""Apply the transform to the source patch and the target (optional).
|
|
39
29
|
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
patch : np.ndarray
|
|
33
|
+
Patch, 2D or 3D, shape C(Z)YX.
|
|
34
|
+
target : Optional[np.ndarray], optional
|
|
35
|
+
Target for the patch, by default None
|
|
42
36
|
|
|
43
37
|
Returns
|
|
44
38
|
-------
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
Tuple[np.ndarray, Optional[np.ndarray]]
|
|
40
|
+
Transformed patch and target.
|
|
47
41
|
"""
|
|
48
|
-
|
|
42
|
+
# number of rotations
|
|
43
|
+
n_rot = self.rng.integers(1, 4)
|
|
49
44
|
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
axes = (-2, -1)
|
|
46
|
+
patch_transformed = self._apply(patch, n_rot, axes)
|
|
47
|
+
target_transformed = (
|
|
48
|
+
self._apply(target, n_rot, axes) if target is not None else None
|
|
49
|
+
)
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
----------
|
|
55
|
-
patch : np.ndarray
|
|
56
|
-
Image or image patch, 2D or 3D, shape (y, x, c) or (z, y, x, c).
|
|
57
|
-
flip_axis : int
|
|
58
|
-
Axis along which to flip the patch.
|
|
59
|
-
"""
|
|
60
|
-
if len(patch.shape) == 3 and self.is_3D:
|
|
61
|
-
raise ValueError(
|
|
62
|
-
"Incompatible patch shape and dimensionality. ZYXC patch shape "
|
|
63
|
-
"expected, but got YXC shape."
|
|
64
|
-
)
|
|
51
|
+
return patch_transformed, target_transformed
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def apply_to_mask(
|
|
69
|
-
self, mask: np.ndarray, n_rotations: int, **kwargs: Any
|
|
53
|
+
def _apply(
|
|
54
|
+
self, patch: np.ndarray, n_rot: int, axes: Tuple[int, int]
|
|
70
55
|
) -> np.ndarray:
|
|
71
|
-
"""Apply the transform to the
|
|
56
|
+
"""Apply the transform to the image.
|
|
72
57
|
|
|
73
58
|
Parameters
|
|
74
59
|
----------
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"expected, but got YXC shape."
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
return np.ascontiguousarray(np.rot90(mask, k=n_rotations, axes=self.axes))
|
|
85
|
-
|
|
86
|
-
def get_transform_init_args_names(self) -> Tuple[str, str]:
|
|
87
|
-
"""
|
|
88
|
-
Get the transform arguments.
|
|
89
|
-
|
|
90
|
-
Returns
|
|
91
|
-
-------
|
|
92
|
-
Tuple[str]
|
|
93
|
-
Transform arguments.
|
|
60
|
+
patch : np.ndarray
|
|
61
|
+
Image or image patch, 2D or 3D, shape C(Z)YX.
|
|
62
|
+
n_rot : int
|
|
63
|
+
Number of 90 degree rotations.
|
|
64
|
+
axes : Tuple[int, int]
|
|
65
|
+
Axes along which to rotate the patch.
|
|
94
66
|
"""
|
|
95
|
-
|
|
67
|
+
# TODO why ascontiguousarray?
|
|
68
|
+
return np.ascontiguousarray(np.rot90(patch, k=n_rot, axes=axes))
|
careamics/utils/__init__.py
CHANGED
careamics/utils/context.py
CHANGED
careamics/utils/logging.py
CHANGED
careamics/utils/metrics.py
CHANGED
careamics/utils/torch_utils.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: careamics
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0rc5
|
|
4
4
|
Summary: Toolbox for running N2V and friends.
|
|
5
5
|
Project-URL: homepage, https://careamics.github.io/
|
|
6
6
|
Project-URL: repository, https://github.com/CAREamics/careamics
|
|
@@ -16,7 +16,6 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Typing :: Typed
|
|
18
18
|
Requires-Python: >=3.8
|
|
19
|
-
Requires-Dist: albumentations
|
|
20
19
|
Requires-Dist: bioimageio-core>=0.6.0
|
|
21
20
|
Requires-Dist: psutil
|
|
22
21
|
Requires-Dist: pydantic>=2.5
|
|
@@ -48,7 +47,7 @@ Description-Content-Type: text/markdown
|
|
|
48
47
|
</a>
|
|
49
48
|
</p>
|
|
50
49
|
|
|
51
|
-
# CAREamics
|
|
50
|
+
# CAREamics
|
|
52
51
|
|
|
53
52
|
[](https://github.com/CAREamics/careamics/blob/main/LICENSE)
|
|
54
53
|
[](https://pypi.org/project/careamics)
|
|
@@ -56,67 +55,23 @@ Description-Content-Type: text/markdown
|
|
|
56
55
|
[](https://github.com/CAREamics/careamics/actions/workflows/ci.yml)
|
|
57
56
|
[](https://codecov.io/gh/CAREamics/careamics)
|
|
58
57
|
|
|
59
|
-
## Installation
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
For more details on the options please follow the installation [guide](https://careamics.github.io/careamics/).
|
|
59
|
+
CAREamics is a PyTorch library aimed at simplifying the use of Noise2Void and its many
|
|
60
|
+
variants and cousins (CARE, Noise2Noise, N2V2, P(P)N2V, HDN, muSplit etc.).
|
|
65
61
|
|
|
66
|
-
##
|
|
62
|
+
## Why CAREamics?
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
1. Using the [yaml config](examples/n2v_2D_reference.yml) file
|
|
64
|
+
Noise2Void is a widely used denoising algorithm, and is readily available from the `n2v`
|
|
65
|
+
python package. However, n2v is based on TensorFlow and Keras and we found it
|
|
66
|
+
increasingly hard to maintain. In addition, more recent methods (PPN2V, DivNoising,
|
|
67
|
+
HDN) are all implemented in PyTorch, but are lacking the extra features that would make
|
|
68
|
+
them usable by the community.
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
The aim of CAREamics is to provide a PyTorch library reuniting all the latest methods
|
|
71
|
+
in one package, while providing a simple and consistent API. The library relies on
|
|
72
|
+
PyTorch Lightning as a back-end. In addition, we will provide extensive documentation and
|
|
73
|
+
tutorials on how to best apply these methods in a scientific context.
|
|
79
74
|
|
|
80
|
-
|
|
81
|
-
loss: type of loss function, e.g. n2v for Noise2Void
|
|
82
|
-
model: model architecture, e.g. UNet
|
|
83
|
-
is_3D: True if 3D data, False if 2D data
|
|
84
|
-
|
|
85
|
-
training:
|
|
86
|
-
num_epochs: Number of training epochs
|
|
87
|
-
patch_size: Size of the patches, List of 2 or 3 elements
|
|
88
|
-
batch_size: Batch size for training
|
|
89
|
-
|
|
90
|
-
extraction_strategy: Controls how the patches are extracted from the data
|
|
91
|
-
|
|
92
|
-
data:
|
|
93
|
-
data_format: File extension, e.g. tif
|
|
94
|
-
axes: Defines the shape of the input data
|
|
95
|
-
```
|
|
96
|
-
Full description of the configuration parameters is in the [documentation](https://careamics.github.io/careamics/).
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```python
|
|
100
|
-
engine = Engine(config_path="config.yml")
|
|
101
|
-
|
|
102
|
-
```
|
|
103
|
-
2. Using the path to the pretrained model
|
|
104
|
-
It's also possible to initialize the Engine using the model checkpoint, saved during the training or downloaded from the [BioImage Model Zoo](https://bioimage.io/#/).
|
|
105
|
-
Checkpoint must contain model_state_dict.
|
|
106
|
-
Read more abount saving and loading models in the [documentation](https://careamics.github.io/careamics/).
|
|
107
|
-
|
|
108
|
-
Once Engine is initialized, we can start training, providing the relative paths to train and validation data
|
|
109
|
-
|
|
110
|
-
```python
|
|
111
|
-
engine.train(train_path=train_path, val_path=val_path)
|
|
112
|
-
```
|
|
113
|
-
Training will run for the specified number of epochs and save the model checkpoint in the working directory.
|
|
114
|
-
|
|
115
|
-
Prediction could be done directly after the training or by loading the pretrained model checkpoint.
|
|
116
|
-
|
|
117
|
-
```python
|
|
118
|
-
predictions = engine.predict(pred_path=predict_path)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
For more examples please take a look at the [notebooks](examples).
|
|
75
|
+
## Installation and use
|
|
122
76
|
|
|
77
|
+
Check out the [documentation](https://careamics.github.io/) for installation instructions and guides!
|