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.
Files changed (108) hide show
  1. stouputils/__init__.pyi +15 -0
  2. stouputils/_deprecated.pyi +12 -0
  3. stouputils/all_doctests.pyi +46 -0
  4. stouputils/applications/__init__.pyi +2 -0
  5. stouputils/applications/automatic_docs.py +3 -0
  6. stouputils/applications/automatic_docs.pyi +106 -0
  7. stouputils/applications/upscaler/__init__.pyi +3 -0
  8. stouputils/applications/upscaler/config.pyi +18 -0
  9. stouputils/applications/upscaler/image.pyi +109 -0
  10. stouputils/applications/upscaler/video.pyi +60 -0
  11. stouputils/archive.pyi +67 -0
  12. stouputils/backup.pyi +109 -0
  13. stouputils/collections.pyi +86 -0
  14. stouputils/continuous_delivery/__init__.pyi +5 -0
  15. stouputils/continuous_delivery/cd_utils.pyi +129 -0
  16. stouputils/continuous_delivery/github.pyi +162 -0
  17. stouputils/continuous_delivery/pypi.pyi +52 -0
  18. stouputils/continuous_delivery/pyproject.pyi +67 -0
  19. stouputils/continuous_delivery/stubs.pyi +39 -0
  20. stouputils/ctx.pyi +211 -0
  21. stouputils/data_science/config/get.py +51 -51
  22. stouputils/data_science/data_processing/image/__init__.py +66 -66
  23. stouputils/data_science/data_processing/image/auto_contrast.py +79 -79
  24. stouputils/data_science/data_processing/image/axis_flip.py +58 -58
  25. stouputils/data_science/data_processing/image/bias_field_correction.py +74 -74
  26. stouputils/data_science/data_processing/image/binary_threshold.py +73 -73
  27. stouputils/data_science/data_processing/image/blur.py +59 -59
  28. stouputils/data_science/data_processing/image/brightness.py +54 -54
  29. stouputils/data_science/data_processing/image/canny.py +110 -110
  30. stouputils/data_science/data_processing/image/clahe.py +92 -92
  31. stouputils/data_science/data_processing/image/common.py +30 -30
  32. stouputils/data_science/data_processing/image/contrast.py +53 -53
  33. stouputils/data_science/data_processing/image/curvature_flow_filter.py +74 -74
  34. stouputils/data_science/data_processing/image/denoise.py +378 -378
  35. stouputils/data_science/data_processing/image/histogram_equalization.py +123 -123
  36. stouputils/data_science/data_processing/image/invert.py +64 -64
  37. stouputils/data_science/data_processing/image/laplacian.py +60 -60
  38. stouputils/data_science/data_processing/image/median_blur.py +52 -52
  39. stouputils/data_science/data_processing/image/noise.py +59 -59
  40. stouputils/data_science/data_processing/image/normalize.py +65 -65
  41. stouputils/data_science/data_processing/image/random_erase.py +66 -66
  42. stouputils/data_science/data_processing/image/resize.py +69 -69
  43. stouputils/data_science/data_processing/image/rotation.py +80 -80
  44. stouputils/data_science/data_processing/image/salt_pepper.py +68 -68
  45. stouputils/data_science/data_processing/image/sharpening.py +55 -55
  46. stouputils/data_science/data_processing/image/shearing.py +64 -64
  47. stouputils/data_science/data_processing/image/threshold.py +64 -64
  48. stouputils/data_science/data_processing/image/translation.py +71 -71
  49. stouputils/data_science/data_processing/image/zoom.py +83 -83
  50. stouputils/data_science/data_processing/image_augmentation.py +118 -118
  51. stouputils/data_science/data_processing/image_preprocess.py +183 -183
  52. stouputils/data_science/data_processing/prosthesis_detection.py +359 -359
  53. stouputils/data_science/data_processing/technique.py +481 -481
  54. stouputils/data_science/dataset/__init__.py +45 -45
  55. stouputils/data_science/dataset/dataset.py +292 -292
  56. stouputils/data_science/dataset/dataset_loader.py +135 -135
  57. stouputils/data_science/dataset/grouping_strategy.py +296 -296
  58. stouputils/data_science/dataset/image_loader.py +100 -100
  59. stouputils/data_science/dataset/xy_tuple.py +696 -696
  60. stouputils/data_science/metric_dictionnary.py +106 -106
  61. stouputils/data_science/mlflow_utils.py +206 -206
  62. stouputils/data_science/models/abstract_model.py +149 -149
  63. stouputils/data_science/models/all.py +85 -85
  64. stouputils/data_science/models/keras/all.py +38 -38
  65. stouputils/data_science/models/keras/convnext.py +62 -62
  66. stouputils/data_science/models/keras/densenet.py +50 -50
  67. stouputils/data_science/models/keras/efficientnet.py +60 -60
  68. stouputils/data_science/models/keras/mobilenet.py +56 -56
  69. stouputils/data_science/models/keras/resnet.py +52 -52
  70. stouputils/data_science/models/keras/squeezenet.py +233 -233
  71. stouputils/data_science/models/keras/vgg.py +42 -42
  72. stouputils/data_science/models/keras/xception.py +38 -38
  73. stouputils/data_science/models/keras_utils/callbacks/__init__.py +20 -20
  74. stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +219 -219
  75. stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +148 -148
  76. stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +31 -31
  77. stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +249 -249
  78. stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +66 -66
  79. stouputils/data_science/models/keras_utils/losses/__init__.py +12 -12
  80. stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +56 -56
  81. stouputils/data_science/models/keras_utils/visualizations.py +416 -416
  82. stouputils/data_science/models/sandbox.py +116 -116
  83. stouputils/data_science/range_tuple.py +234 -234
  84. stouputils/data_science/utils.py +285 -285
  85. stouputils/decorators.pyi +242 -0
  86. stouputils/image.pyi +172 -0
  87. stouputils/installer/__init__.py +18 -18
  88. stouputils/installer/__init__.pyi +5 -0
  89. stouputils/installer/common.pyi +39 -0
  90. stouputils/installer/downloader.pyi +24 -0
  91. stouputils/installer/linux.py +144 -144
  92. stouputils/installer/linux.pyi +39 -0
  93. stouputils/installer/main.py +223 -223
  94. stouputils/installer/main.pyi +57 -0
  95. stouputils/installer/windows.py +136 -136
  96. stouputils/installer/windows.pyi +31 -0
  97. stouputils/io.pyi +213 -0
  98. stouputils/parallel.py +12 -10
  99. stouputils/parallel.pyi +211 -0
  100. stouputils/print.pyi +136 -0
  101. stouputils/py.typed +1 -1
  102. stouputils/stouputils/parallel.pyi +4 -4
  103. stouputils/version_pkg.pyi +15 -0
  104. {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/METADATA +1 -1
  105. stouputils-1.14.2.dist-info/RECORD +171 -0
  106. stouputils-1.14.0.dist-info/RECORD +0 -140
  107. {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/WHEEL +0 -0
  108. {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
+