stouputils 1.14.0__py3-none-any.whl → 1.14.2__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.
- stouputils/__init__.pyi +15 -0
- stouputils/_deprecated.pyi +12 -0
- stouputils/all_doctests.pyi +46 -0
- stouputils/applications/__init__.pyi +2 -0
- stouputils/applications/automatic_docs.py +3 -0
- stouputils/applications/automatic_docs.pyi +106 -0
- stouputils/applications/upscaler/__init__.pyi +3 -0
- stouputils/applications/upscaler/config.pyi +18 -0
- stouputils/applications/upscaler/image.pyi +109 -0
- stouputils/applications/upscaler/video.pyi +60 -0
- stouputils/archive.pyi +67 -0
- stouputils/backup.pyi +109 -0
- stouputils/collections.pyi +86 -0
- stouputils/continuous_delivery/__init__.pyi +5 -0
- stouputils/continuous_delivery/cd_utils.pyi +129 -0
- stouputils/continuous_delivery/github.pyi +162 -0
- stouputils/continuous_delivery/pypi.pyi +52 -0
- stouputils/continuous_delivery/pyproject.pyi +67 -0
- stouputils/continuous_delivery/stubs.pyi +39 -0
- stouputils/ctx.pyi +211 -0
- stouputils/data_science/config/get.py +51 -51
- stouputils/data_science/data_processing/image/__init__.py +66 -66
- stouputils/data_science/data_processing/image/auto_contrast.py +79 -79
- stouputils/data_science/data_processing/image/axis_flip.py +58 -58
- stouputils/data_science/data_processing/image/bias_field_correction.py +74 -74
- stouputils/data_science/data_processing/image/binary_threshold.py +73 -73
- stouputils/data_science/data_processing/image/blur.py +59 -59
- stouputils/data_science/data_processing/image/brightness.py +54 -54
- stouputils/data_science/data_processing/image/canny.py +110 -110
- stouputils/data_science/data_processing/image/clahe.py +92 -92
- stouputils/data_science/data_processing/image/common.py +30 -30
- stouputils/data_science/data_processing/image/contrast.py +53 -53
- stouputils/data_science/data_processing/image/curvature_flow_filter.py +74 -74
- stouputils/data_science/data_processing/image/denoise.py +378 -378
- stouputils/data_science/data_processing/image/histogram_equalization.py +123 -123
- stouputils/data_science/data_processing/image/invert.py +64 -64
- stouputils/data_science/data_processing/image/laplacian.py +60 -60
- stouputils/data_science/data_processing/image/median_blur.py +52 -52
- stouputils/data_science/data_processing/image/noise.py +59 -59
- stouputils/data_science/data_processing/image/normalize.py +65 -65
- stouputils/data_science/data_processing/image/random_erase.py +66 -66
- stouputils/data_science/data_processing/image/resize.py +69 -69
- stouputils/data_science/data_processing/image/rotation.py +80 -80
- stouputils/data_science/data_processing/image/salt_pepper.py +68 -68
- stouputils/data_science/data_processing/image/sharpening.py +55 -55
- stouputils/data_science/data_processing/image/shearing.py +64 -64
- stouputils/data_science/data_processing/image/threshold.py +64 -64
- stouputils/data_science/data_processing/image/translation.py +71 -71
- stouputils/data_science/data_processing/image/zoom.py +83 -83
- stouputils/data_science/data_processing/image_augmentation.py +118 -118
- stouputils/data_science/data_processing/image_preprocess.py +183 -183
- stouputils/data_science/data_processing/prosthesis_detection.py +359 -359
- stouputils/data_science/data_processing/technique.py +481 -481
- stouputils/data_science/dataset/__init__.py +45 -45
- stouputils/data_science/dataset/dataset.py +292 -292
- stouputils/data_science/dataset/dataset_loader.py +135 -135
- stouputils/data_science/dataset/grouping_strategy.py +296 -296
- stouputils/data_science/dataset/image_loader.py +100 -100
- stouputils/data_science/dataset/xy_tuple.py +696 -696
- stouputils/data_science/metric_dictionnary.py +106 -106
- stouputils/data_science/mlflow_utils.py +206 -206
- stouputils/data_science/models/abstract_model.py +149 -149
- stouputils/data_science/models/all.py +85 -85
- stouputils/data_science/models/keras/all.py +38 -38
- stouputils/data_science/models/keras/convnext.py +62 -62
- stouputils/data_science/models/keras/densenet.py +50 -50
- stouputils/data_science/models/keras/efficientnet.py +60 -60
- stouputils/data_science/models/keras/mobilenet.py +56 -56
- stouputils/data_science/models/keras/resnet.py +52 -52
- stouputils/data_science/models/keras/squeezenet.py +233 -233
- stouputils/data_science/models/keras/vgg.py +42 -42
- stouputils/data_science/models/keras/xception.py +38 -38
- stouputils/data_science/models/keras_utils/callbacks/__init__.py +20 -20
- stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +219 -219
- stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +148 -148
- stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +31 -31
- stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +249 -249
- stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +66 -66
- stouputils/data_science/models/keras_utils/losses/__init__.py +12 -12
- stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +56 -56
- stouputils/data_science/models/keras_utils/visualizations.py +416 -416
- stouputils/data_science/models/sandbox.py +116 -116
- stouputils/data_science/range_tuple.py +234 -234
- stouputils/data_science/utils.py +285 -285
- stouputils/decorators.pyi +242 -0
- stouputils/image.pyi +172 -0
- stouputils/installer/__init__.py +18 -18
- stouputils/installer/__init__.pyi +5 -0
- stouputils/installer/common.pyi +39 -0
- stouputils/installer/downloader.pyi +24 -0
- stouputils/installer/linux.py +144 -144
- stouputils/installer/linux.pyi +39 -0
- stouputils/installer/main.py +223 -223
- stouputils/installer/main.pyi +57 -0
- stouputils/installer/windows.py +136 -136
- stouputils/installer/windows.pyi +31 -0
- stouputils/io.pyi +213 -0
- stouputils/parallel.py +12 -10
- stouputils/parallel.pyi +211 -0
- stouputils/print.pyi +136 -0
- stouputils/py.typed +1 -1
- stouputils/stouputils/parallel.pyi +4 -4
- stouputils/version_pkg.pyi +15 -0
- {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/METADATA +1 -1
- stouputils-1.14.2.dist-info/RECORD +171 -0
- stouputils-1.14.0.dist-info/RECORD +0 -140
- {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/WHEEL +0 -0
- {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/entry_points.txt +0 -0
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
# pyright: reportUnusedImport=false
|
|
3
|
-
# ruff: noqa: F401
|
|
4
|
-
|
|
5
|
-
# Imports
|
|
6
|
-
from .common import Any, NDArray, check_image, cv2, np
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Functions
|
|
10
|
-
def clahe_image(
|
|
11
|
-
image: NDArray[Any],
|
|
12
|
-
clip_limit: float = 2.0,
|
|
13
|
-
tile_grid_size: int = 8,
|
|
14
|
-
ignore_dtype: bool = False,
|
|
15
|
-
) -> NDArray[Any]:
|
|
16
|
-
""" Apply Contrast Limited Adaptive Histogram Equalization (CLAHE) to an image.
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
image (NDArray[Any]): Image to apply CLAHE to
|
|
20
|
-
clip_limit (float): Threshold for contrast limiting (1.0-4.0 recommended)
|
|
21
|
-
tile_grid_size (int): Size of grid for histogram equalization (2-16 recommended)
|
|
22
|
-
ignore_dtype (bool): Ignore the dtype check
|
|
23
|
-
Returns:
|
|
24
|
-
NDArray[Any]: Image with CLAHE applied
|
|
25
|
-
|
|
26
|
-
>>> ## Basic tests
|
|
27
|
-
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
28
|
-
>>> clahed = clahe_image(image.astype(np.uint8), 2.0, 1)
|
|
29
|
-
>>> clahed.tolist()
|
|
30
|
-
[[28, 57, 85], [113, 142, 170], [198, 227, 255]]
|
|
31
|
-
>>> clahed.shape == image.shape
|
|
32
|
-
True
|
|
33
|
-
|
|
34
|
-
>>> img = np.full((10,10), 128, dtype=np.uint8)
|
|
35
|
-
>>> img[2:8, 2:8] = 200 # Create a bright region
|
|
36
|
-
>>> clahed = clahe_image(img, 2.0, 4)
|
|
37
|
-
>>> bool(np.mean(clahed) > np.mean(img)) # Should enhance contrast
|
|
38
|
-
True
|
|
39
|
-
>>> bool(np.std(clahed) > np.std(img)) # Should enhance contrast
|
|
40
|
-
True
|
|
41
|
-
|
|
42
|
-
>>> rgb = np.full((10,10,3), 128, dtype=np.uint8)
|
|
43
|
-
>>> rgb[2:8, 2:8, :] = 50 # Create a dark region
|
|
44
|
-
>>> clahed_rgb = clahe_image(rgb, 2.0, 4)
|
|
45
|
-
>>> bool(np.mean(clahed_rgb) > np.mean(rgb)) # Should enhance contrast
|
|
46
|
-
True
|
|
47
|
-
>>> bool(np.std(clahed_rgb) > np.std(rgb)) # Should enhance contrast
|
|
48
|
-
True
|
|
49
|
-
>>> clahed_rgb.shape == rgb.shape
|
|
50
|
-
True
|
|
51
|
-
|
|
52
|
-
>>> ## Test invalid inputs
|
|
53
|
-
>>> clahe_image("not an image", 2.0, 8)
|
|
54
|
-
Traceback (most recent call last):
|
|
55
|
-
...
|
|
56
|
-
AssertionError: Image must be a numpy array
|
|
57
|
-
|
|
58
|
-
>>> clahe_image(image.astype(np.uint8), "2.0", 8)
|
|
59
|
-
Traceback (most recent call last):
|
|
60
|
-
...
|
|
61
|
-
AssertionError: clip_limit must be a number, got <class 'str'>
|
|
62
|
-
|
|
63
|
-
>>> clahe_image(image.astype(np.uint8), 2.0, -1)
|
|
64
|
-
Traceback (most recent call last):
|
|
65
|
-
...
|
|
66
|
-
AssertionError: tile_grid_size must be positive, got -1
|
|
67
|
-
"""
|
|
68
|
-
# Check input data
|
|
69
|
-
check_image(image, ignore_dtype=ignore_dtype)
|
|
70
|
-
assert isinstance(clip_limit, float | int), f"clip_limit must be a number, got {type(clip_limit)}"
|
|
71
|
-
assert isinstance(tile_grid_size, int), f"tile_grid_size must be an integer, got {type(tile_grid_size)}"
|
|
72
|
-
assert tile_grid_size > 0, f"tile_grid_size must be positive, got {tile_grid_size}"
|
|
73
|
-
|
|
74
|
-
# Create CLAHE object
|
|
75
|
-
clahe: cv2.CLAHE = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(tile_grid_size, tile_grid_size))
|
|
76
|
-
|
|
77
|
-
# Handle different image types
|
|
78
|
-
if len(image.shape) == 2:
|
|
79
|
-
# Grayscale image
|
|
80
|
-
return clahe.apply(image)
|
|
81
|
-
else:
|
|
82
|
-
# Color image - convert to LAB color space
|
|
83
|
-
lab: NDArray[Any] = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
|
|
84
|
-
channel_l, channel_a, channel_b = cv2.split(lab)
|
|
85
|
-
|
|
86
|
-
# Apply CLAHE to L channel
|
|
87
|
-
cl: NDArray[Any] = clahe.apply(channel_l)
|
|
88
|
-
|
|
89
|
-
# Merge channels and convert back to BGR
|
|
90
|
-
limg: NDArray[Any] = cv2.merge((cl, channel_a, channel_b))
|
|
91
|
-
return cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
|
|
92
|
-
|
|
1
|
+
|
|
2
|
+
# pyright: reportUnusedImport=false
|
|
3
|
+
# ruff: noqa: F401
|
|
4
|
+
|
|
5
|
+
# Imports
|
|
6
|
+
from .common import Any, NDArray, check_image, cv2, np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Functions
|
|
10
|
+
def clahe_image(
|
|
11
|
+
image: NDArray[Any],
|
|
12
|
+
clip_limit: float = 2.0,
|
|
13
|
+
tile_grid_size: int = 8,
|
|
14
|
+
ignore_dtype: bool = False,
|
|
15
|
+
) -> NDArray[Any]:
|
|
16
|
+
""" Apply Contrast Limited Adaptive Histogram Equalization (CLAHE) to an image.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
image (NDArray[Any]): Image to apply CLAHE to
|
|
20
|
+
clip_limit (float): Threshold for contrast limiting (1.0-4.0 recommended)
|
|
21
|
+
tile_grid_size (int): Size of grid for histogram equalization (2-16 recommended)
|
|
22
|
+
ignore_dtype (bool): Ignore the dtype check
|
|
23
|
+
Returns:
|
|
24
|
+
NDArray[Any]: Image with CLAHE applied
|
|
25
|
+
|
|
26
|
+
>>> ## Basic tests
|
|
27
|
+
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
28
|
+
>>> clahed = clahe_image(image.astype(np.uint8), 2.0, 1)
|
|
29
|
+
>>> clahed.tolist()
|
|
30
|
+
[[28, 57, 85], [113, 142, 170], [198, 227, 255]]
|
|
31
|
+
>>> clahed.shape == image.shape
|
|
32
|
+
True
|
|
33
|
+
|
|
34
|
+
>>> img = np.full((10,10), 128, dtype=np.uint8)
|
|
35
|
+
>>> img[2:8, 2:8] = 200 # Create a bright region
|
|
36
|
+
>>> clahed = clahe_image(img, 2.0, 4)
|
|
37
|
+
>>> bool(np.mean(clahed) > np.mean(img)) # Should enhance contrast
|
|
38
|
+
True
|
|
39
|
+
>>> bool(np.std(clahed) > np.std(img)) # Should enhance contrast
|
|
40
|
+
True
|
|
41
|
+
|
|
42
|
+
>>> rgb = np.full((10,10,3), 128, dtype=np.uint8)
|
|
43
|
+
>>> rgb[2:8, 2:8, :] = 50 # Create a dark region
|
|
44
|
+
>>> clahed_rgb = clahe_image(rgb, 2.0, 4)
|
|
45
|
+
>>> bool(np.mean(clahed_rgb) > np.mean(rgb)) # Should enhance contrast
|
|
46
|
+
True
|
|
47
|
+
>>> bool(np.std(clahed_rgb) > np.std(rgb)) # Should enhance contrast
|
|
48
|
+
True
|
|
49
|
+
>>> clahed_rgb.shape == rgb.shape
|
|
50
|
+
True
|
|
51
|
+
|
|
52
|
+
>>> ## Test invalid inputs
|
|
53
|
+
>>> clahe_image("not an image", 2.0, 8)
|
|
54
|
+
Traceback (most recent call last):
|
|
55
|
+
...
|
|
56
|
+
AssertionError: Image must be a numpy array
|
|
57
|
+
|
|
58
|
+
>>> clahe_image(image.astype(np.uint8), "2.0", 8)
|
|
59
|
+
Traceback (most recent call last):
|
|
60
|
+
...
|
|
61
|
+
AssertionError: clip_limit must be a number, got <class 'str'>
|
|
62
|
+
|
|
63
|
+
>>> clahe_image(image.astype(np.uint8), 2.0, -1)
|
|
64
|
+
Traceback (most recent call last):
|
|
65
|
+
...
|
|
66
|
+
AssertionError: tile_grid_size must be positive, got -1
|
|
67
|
+
"""
|
|
68
|
+
# Check input data
|
|
69
|
+
check_image(image, ignore_dtype=ignore_dtype)
|
|
70
|
+
assert isinstance(clip_limit, float | int), f"clip_limit must be a number, got {type(clip_limit)}"
|
|
71
|
+
assert isinstance(tile_grid_size, int), f"tile_grid_size must be an integer, got {type(tile_grid_size)}"
|
|
72
|
+
assert tile_grid_size > 0, f"tile_grid_size must be positive, got {tile_grid_size}"
|
|
73
|
+
|
|
74
|
+
# Create CLAHE object
|
|
75
|
+
clahe: cv2.CLAHE = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(tile_grid_size, tile_grid_size))
|
|
76
|
+
|
|
77
|
+
# Handle different image types
|
|
78
|
+
if len(image.shape) == 2:
|
|
79
|
+
# Grayscale image
|
|
80
|
+
return clahe.apply(image)
|
|
81
|
+
else:
|
|
82
|
+
# Color image - convert to LAB color space
|
|
83
|
+
lab: NDArray[Any] = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
|
|
84
|
+
channel_l, channel_a, channel_b = cv2.split(lab)
|
|
85
|
+
|
|
86
|
+
# Apply CLAHE to L channel
|
|
87
|
+
cl: NDArray[Any] = clahe.apply(channel_l)
|
|
88
|
+
|
|
89
|
+
# Merge channels and convert back to BGR
|
|
90
|
+
limg: NDArray[Any] = cv2.merge((cl, channel_a, channel_b))
|
|
91
|
+
return cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
|
|
92
|
+
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
# pyright: reportUnusedImport=false
|
|
4
|
-
# ruff: noqa: F401
|
|
5
|
-
|
|
6
|
-
# Imports
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
import cv2
|
|
10
|
-
import numpy as np
|
|
11
|
-
from numpy.typing import NDArray
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Functions
|
|
15
|
-
def check_image(image: NDArray[Any], ignore_dtype: bool = False) -> None:
|
|
16
|
-
""" Check if the image is valid
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
image (NDArray[Any]): Image to check
|
|
20
|
-
ignore_dtype (bool): Ignore the dtype check
|
|
21
|
-
"""
|
|
22
|
-
# Check input data
|
|
23
|
-
assert isinstance(image, np.ndarray), "Image must be a numpy array"
|
|
24
|
-
assert len(image.shape) >= 2, "Image must have at least 2 dimensions"
|
|
25
|
-
|
|
26
|
-
# Check dtype
|
|
27
|
-
if not ignore_dtype:
|
|
28
|
-
dtypes: list[type] = [np.uint8, np.int16, np.float32, np.float64]
|
|
29
|
-
assert image.dtype in dtypes, f"Image must be of type {dtypes}"
|
|
30
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# pyright: reportUnusedImport=false
|
|
4
|
+
# ruff: noqa: F401
|
|
5
|
+
|
|
6
|
+
# Imports
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import cv2
|
|
10
|
+
import numpy as np
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Functions
|
|
15
|
+
def check_image(image: NDArray[Any], ignore_dtype: bool = False) -> None:
|
|
16
|
+
""" Check if the image is valid
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
image (NDArray[Any]): Image to check
|
|
20
|
+
ignore_dtype (bool): Ignore the dtype check
|
|
21
|
+
"""
|
|
22
|
+
# Check input data
|
|
23
|
+
assert isinstance(image, np.ndarray), "Image must be a numpy array"
|
|
24
|
+
assert len(image.shape) >= 2, "Image must have at least 2 dimensions"
|
|
25
|
+
|
|
26
|
+
# Check dtype
|
|
27
|
+
if not ignore_dtype:
|
|
28
|
+
dtypes: list[type] = [np.uint8, np.int16, np.float32, np.float64]
|
|
29
|
+
assert image.dtype in dtypes, f"Image must be of type {dtypes}"
|
|
30
|
+
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
# Imports
|
|
3
|
-
from .common import Any, NDArray, check_image, cv2, np
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# Functions
|
|
7
|
-
def contrast_image(image: NDArray[Any], factor: float, ignore_dtype: bool = False) -> NDArray[Any]:
|
|
8
|
-
""" Adjust the contrast of an image.
|
|
9
|
-
|
|
10
|
-
Args:
|
|
11
|
-
image (NDArray[Any]): Image to adjust contrast
|
|
12
|
-
factor (float): Contrast adjustment factor
|
|
13
|
-
ignore_dtype (bool): Ignore the dtype check
|
|
14
|
-
Returns:
|
|
15
|
-
NDArray[Any]: Image with adjusted contrast
|
|
16
|
-
|
|
17
|
-
>>> ## Basic tests
|
|
18
|
-
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
19
|
-
>>> contrasted = contrast_image(image.astype(np.uint8), 1.5)
|
|
20
|
-
>>> contrasted.shape == image.shape
|
|
21
|
-
True
|
|
22
|
-
|
|
23
|
-
>>> img = np.array([[50, 100, 150]], dtype=np.uint8)
|
|
24
|
-
>>> high = contrast_image(img, 2.0)
|
|
25
|
-
>>> low = contrast_image(img, 0.5)
|
|
26
|
-
>>> bool(high.std() > img.std() > low.std()) # Higher contrast = higher std
|
|
27
|
-
True
|
|
28
|
-
|
|
29
|
-
>>> rgb = np.full((3,3,3), 128, dtype=np.uint8)
|
|
30
|
-
>>> rgb[1,1] = [50, 100, 150]
|
|
31
|
-
>>> cont_rgb = contrast_image(rgb, 1.5)
|
|
32
|
-
>>> cont_rgb.shape == (3,3,3)
|
|
33
|
-
True
|
|
34
|
-
|
|
35
|
-
>>> ## Test invalid inputs
|
|
36
|
-
>>> contrast_image("not an image", 1.5)
|
|
37
|
-
Traceback (most recent call last):
|
|
38
|
-
...
|
|
39
|
-
AssertionError: Image must be a numpy array
|
|
40
|
-
|
|
41
|
-
>>> contrast_image(image.astype(np.uint8), "1.5")
|
|
42
|
-
Traceback (most recent call last):
|
|
43
|
-
...
|
|
44
|
-
AssertionError: factor must be a number, got <class 'str'>
|
|
45
|
-
"""
|
|
46
|
-
# Check input data
|
|
47
|
-
check_image(image, ignore_dtype=ignore_dtype)
|
|
48
|
-
assert isinstance(factor, float | int), f"factor must be a number, got {type(factor)}"
|
|
49
|
-
|
|
50
|
-
# Apply contrast adjustment
|
|
51
|
-
mean: float = float(np.mean(image))
|
|
52
|
-
return cv2.addWeighted(image, factor, image, 0, mean * (1 - factor))
|
|
53
|
-
|
|
1
|
+
|
|
2
|
+
# Imports
|
|
3
|
+
from .common import Any, NDArray, check_image, cv2, np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Functions
|
|
7
|
+
def contrast_image(image: NDArray[Any], factor: float, ignore_dtype: bool = False) -> NDArray[Any]:
|
|
8
|
+
""" Adjust the contrast of an image.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
image (NDArray[Any]): Image to adjust contrast
|
|
12
|
+
factor (float): Contrast adjustment factor
|
|
13
|
+
ignore_dtype (bool): Ignore the dtype check
|
|
14
|
+
Returns:
|
|
15
|
+
NDArray[Any]: Image with adjusted contrast
|
|
16
|
+
|
|
17
|
+
>>> ## Basic tests
|
|
18
|
+
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
19
|
+
>>> contrasted = contrast_image(image.astype(np.uint8), 1.5)
|
|
20
|
+
>>> contrasted.shape == image.shape
|
|
21
|
+
True
|
|
22
|
+
|
|
23
|
+
>>> img = np.array([[50, 100, 150]], dtype=np.uint8)
|
|
24
|
+
>>> high = contrast_image(img, 2.0)
|
|
25
|
+
>>> low = contrast_image(img, 0.5)
|
|
26
|
+
>>> bool(high.std() > img.std() > low.std()) # Higher contrast = higher std
|
|
27
|
+
True
|
|
28
|
+
|
|
29
|
+
>>> rgb = np.full((3,3,3), 128, dtype=np.uint8)
|
|
30
|
+
>>> rgb[1,1] = [50, 100, 150]
|
|
31
|
+
>>> cont_rgb = contrast_image(rgb, 1.5)
|
|
32
|
+
>>> cont_rgb.shape == (3,3,3)
|
|
33
|
+
True
|
|
34
|
+
|
|
35
|
+
>>> ## Test invalid inputs
|
|
36
|
+
>>> contrast_image("not an image", 1.5)
|
|
37
|
+
Traceback (most recent call last):
|
|
38
|
+
...
|
|
39
|
+
AssertionError: Image must be a numpy array
|
|
40
|
+
|
|
41
|
+
>>> contrast_image(image.astype(np.uint8), "1.5")
|
|
42
|
+
Traceback (most recent call last):
|
|
43
|
+
...
|
|
44
|
+
AssertionError: factor must be a number, got <class 'str'>
|
|
45
|
+
"""
|
|
46
|
+
# Check input data
|
|
47
|
+
check_image(image, ignore_dtype=ignore_dtype)
|
|
48
|
+
assert isinstance(factor, float | int), f"factor must be a number, got {type(factor)}"
|
|
49
|
+
|
|
50
|
+
# Apply contrast adjustment
|
|
51
|
+
mean: float = float(np.mean(image))
|
|
52
|
+
return cv2.addWeighted(image, factor, image, 0, mean * (1 - factor))
|
|
53
|
+
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
|
|
2
|
-
# pyright: reportUnknownMemberType=false
|
|
3
|
-
# pyright: reportUnknownArgumentType=false
|
|
4
|
-
# pyright: reportUnknownVariableType=false
|
|
5
|
-
# pyright: reportUnusedImport=false
|
|
6
|
-
# ruff: noqa: F401
|
|
7
|
-
|
|
8
|
-
# Imports
|
|
9
|
-
import SimpleITK as Sitk
|
|
10
|
-
|
|
11
|
-
from .common import Any, NDArray, check_image, np
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Functions
|
|
15
|
-
def curvature_flow_filter_image(
|
|
16
|
-
image: NDArray[Any],
|
|
17
|
-
time_step: float = 0.05,
|
|
18
|
-
number_of_iterations: int = 5,
|
|
19
|
-
ignore_dtype: bool = False,
|
|
20
|
-
) -> NDArray[Any]:
|
|
21
|
-
""" Apply a curvature flow filter to an image.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
image (NDArray[Any]): Image to apply the curvature flow filter
|
|
25
|
-
time_step (float): Time step for the curvature flow filter
|
|
26
|
-
number_of_iterations (int): Number of iterations for the curvature flow filter
|
|
27
|
-
ignore_dtype (bool): Ignore the dtype check
|
|
28
|
-
Returns:
|
|
29
|
-
NDArray[Any]: Image with the curvature flow filter applied
|
|
30
|
-
|
|
31
|
-
>>> ## Basic tests
|
|
32
|
-
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
|
|
33
|
-
>>> filtered = curvature_flow_filter_image(image, 0.05, 5)
|
|
34
|
-
>>> filtered.tolist()[0][0]
|
|
35
|
-
1.2910538407309702
|
|
36
|
-
>>> filtered.shape == image.shape
|
|
37
|
-
True
|
|
38
|
-
>>> filtered.dtype == image.dtype
|
|
39
|
-
False
|
|
40
|
-
|
|
41
|
-
>>> rgb = np.full((3,3,3), 128, dtype=np.uint8)
|
|
42
|
-
>>> rgb[1,1] = [50, 100, 150]
|
|
43
|
-
>>> filtered_rgb = curvature_flow_filter_image(rgb, 0.05, 5)
|
|
44
|
-
>>> filtered_rgb.shape == (3,3,3)
|
|
45
|
-
True
|
|
46
|
-
|
|
47
|
-
>>> ## Test invalid inputs
|
|
48
|
-
>>> curvature_flow_filter_image("not an image")
|
|
49
|
-
Traceback (most recent call last):
|
|
50
|
-
...
|
|
51
|
-
AssertionError: Image must be a numpy array
|
|
52
|
-
|
|
53
|
-
>>> curvature_flow_filter_image(image, time_step="not a float")
|
|
54
|
-
Traceback (most recent call last):
|
|
55
|
-
...
|
|
56
|
-
AssertionError: time_step must be a float
|
|
57
|
-
|
|
58
|
-
>>> curvature_flow_filter_image(image, number_of_iterations="not an integer")
|
|
59
|
-
Traceback (most recent call last):
|
|
60
|
-
...
|
|
61
|
-
AssertionError: number_of_iterations must be an integer
|
|
62
|
-
"""
|
|
63
|
-
# Check input data
|
|
64
|
-
check_image(image, ignore_dtype=ignore_dtype)
|
|
65
|
-
assert isinstance(time_step, float), "time_step must be a float"
|
|
66
|
-
assert isinstance(number_of_iterations, int), "number_of_iterations must be an integer"
|
|
67
|
-
assert time_step > 0, "time_step must be greater than 0"
|
|
68
|
-
assert number_of_iterations > 0, "number_of_iterations must be greater than 0"
|
|
69
|
-
|
|
70
|
-
# Apply the curvature flow filter
|
|
71
|
-
image_Sitk: Sitk.Image = Sitk.GetImageFromArray(image)
|
|
72
|
-
image_Sitk = Sitk.CurvatureFlow(image_Sitk, timeStep=time_step, numberOfIterations=number_of_iterations)
|
|
73
|
-
return Sitk.GetArrayFromImage(image_Sitk)
|
|
74
|
-
|
|
1
|
+
|
|
2
|
+
# pyright: reportUnknownMemberType=false
|
|
3
|
+
# pyright: reportUnknownArgumentType=false
|
|
4
|
+
# pyright: reportUnknownVariableType=false
|
|
5
|
+
# pyright: reportUnusedImport=false
|
|
6
|
+
# ruff: noqa: F401
|
|
7
|
+
|
|
8
|
+
# Imports
|
|
9
|
+
import SimpleITK as Sitk
|
|
10
|
+
|
|
11
|
+
from .common import Any, NDArray, check_image, np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Functions
|
|
15
|
+
def curvature_flow_filter_image(
|
|
16
|
+
image: NDArray[Any],
|
|
17
|
+
time_step: float = 0.05,
|
|
18
|
+
number_of_iterations: int = 5,
|
|
19
|
+
ignore_dtype: bool = False,
|
|
20
|
+
) -> NDArray[Any]:
|
|
21
|
+
""" Apply a curvature flow filter to an image.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
image (NDArray[Any]): Image to apply the curvature flow filter
|
|
25
|
+
time_step (float): Time step for the curvature flow filter
|
|
26
|
+
number_of_iterations (int): Number of iterations for the curvature flow filter
|
|
27
|
+
ignore_dtype (bool): Ignore the dtype check
|
|
28
|
+
Returns:
|
|
29
|
+
NDArray[Any]: Image with the curvature flow filter applied
|
|
30
|
+
|
|
31
|
+
>>> ## Basic tests
|
|
32
|
+
>>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
|
|
33
|
+
>>> filtered = curvature_flow_filter_image(image, 0.05, 5)
|
|
34
|
+
>>> filtered.tolist()[0][0]
|
|
35
|
+
1.2910538407309702
|
|
36
|
+
>>> filtered.shape == image.shape
|
|
37
|
+
True
|
|
38
|
+
>>> filtered.dtype == image.dtype
|
|
39
|
+
False
|
|
40
|
+
|
|
41
|
+
>>> rgb = np.full((3,3,3), 128, dtype=np.uint8)
|
|
42
|
+
>>> rgb[1,1] = [50, 100, 150]
|
|
43
|
+
>>> filtered_rgb = curvature_flow_filter_image(rgb, 0.05, 5)
|
|
44
|
+
>>> filtered_rgb.shape == (3,3,3)
|
|
45
|
+
True
|
|
46
|
+
|
|
47
|
+
>>> ## Test invalid inputs
|
|
48
|
+
>>> curvature_flow_filter_image("not an image")
|
|
49
|
+
Traceback (most recent call last):
|
|
50
|
+
...
|
|
51
|
+
AssertionError: Image must be a numpy array
|
|
52
|
+
|
|
53
|
+
>>> curvature_flow_filter_image(image, time_step="not a float")
|
|
54
|
+
Traceback (most recent call last):
|
|
55
|
+
...
|
|
56
|
+
AssertionError: time_step must be a float
|
|
57
|
+
|
|
58
|
+
>>> curvature_flow_filter_image(image, number_of_iterations="not an integer")
|
|
59
|
+
Traceback (most recent call last):
|
|
60
|
+
...
|
|
61
|
+
AssertionError: number_of_iterations must be an integer
|
|
62
|
+
"""
|
|
63
|
+
# Check input data
|
|
64
|
+
check_image(image, ignore_dtype=ignore_dtype)
|
|
65
|
+
assert isinstance(time_step, float), "time_step must be a float"
|
|
66
|
+
assert isinstance(number_of_iterations, int), "number_of_iterations must be an integer"
|
|
67
|
+
assert time_step > 0, "time_step must be greater than 0"
|
|
68
|
+
assert number_of_iterations > 0, "number_of_iterations must be greater than 0"
|
|
69
|
+
|
|
70
|
+
# Apply the curvature flow filter
|
|
71
|
+
image_Sitk: Sitk.Image = Sitk.GetImageFromArray(image)
|
|
72
|
+
image_Sitk = Sitk.CurvatureFlow(image_Sitk, timeStep=time_step, numberOfIterations=number_of_iterations)
|
|
73
|
+
return Sitk.GetArrayFromImage(image_Sitk)
|
|
74
|
+
|