dsa-helpers 1.0.3.dev0__tar.gz → 1.0.4.dev1__tar.gz
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.
- {dsa_helpers-1.0.3.dev0/dsa_helpers.egg-info → dsa_helpers-1.0.4.dev1}/PKG-INFO +4 -14
- dsa_helpers-1.0.4.dev1/README.md +13 -0
- dsa_helpers-1.0.4.dev1/dsa_helpers/image_utils.py +101 -0
- dsa_helpers-1.0.4.dev1/dsa_helpers/utils.py +35 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1/dsa_helpers.egg-info}/PKG-INFO +4 -14
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers.egg-info/SOURCES.txt +1 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/pyproject.toml +1 -1
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/tests/test.ipynb +22 -10
- dsa_helpers-1.0.3.dev0/README.md +0 -24
- dsa_helpers-1.0.3.dev0/dsa_helpers/utils.py +0 -78
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/.gitignore +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/.readthedocs.yaml +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/LICENSE +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/app.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/docs/requirements.txt +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/docs/source/conf.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/docs/source/index.rst +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/dash/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/dash/dash_paperdragon_utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/dash/header.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/dash/header_callbacks.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/girder_utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/imread.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/imwrite.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/callbacks.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/datasets/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/datasets/utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/evaluate.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/metrics.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/segformer_semantic_segmentation/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/segformer_semantic_segmentation/inference.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/transforms/__init__.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/transforms/segformer_transforms.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/mongo_utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/tile_utils.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/tiling.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers.egg-info/dependency_links.txt +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers.egg-info/requires.txt +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers.egg-info/top_level.txt +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/setup.cfg +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/tests/app/Dockerfile +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/tests/app/app.py +0 -0
- {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/tests/docker-compose.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: dsa_helpers
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4.dev1
|
|
4
4
|
Summary: Utility functions for working with the DSA girder client.
|
|
5
5
|
Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
|
|
6
6
|
Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
|
|
@@ -26,6 +26,7 @@ Requires-Dist: transformers[torch]
|
|
|
26
26
|
Requires-Dist: datasets
|
|
27
27
|
Requires-Dist: torchvision
|
|
28
28
|
Requires-Dist: large-image
|
|
29
|
+
Dynamic: license-file
|
|
29
30
|
|
|
30
31
|
# Digital Slide Archive (DSA) Helpers
|
|
31
32
|
Digital Slide Archive Python utility library.
|
|
@@ -39,15 +40,4 @@ This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
|
|
|
39
40
|
## Extra dependencies
|
|
40
41
|
If you are getting a large image error, then install large image using the instructions provided in their [GitHub page](https://github.com/girder/large_image#:~:text=pip%20install%20large%2Dimage%5Ball%5D%20%2D%2Dfind%2Dlinks%20https%3A//girder.github.io/large_image_wheels).
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
1. Install requirements for building and distributing package:
|
|
44
|
-
```
|
|
45
|
-
$ python3 -m pip install --upgrade build # for building package
|
|
46
|
-
$ python3 -m pip install --upgrade twine # for uploading to PyPI
|
|
47
|
-
```
|
|
48
|
-
2. When ready to build:
|
|
49
|
-
- Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
|
|
50
|
-
- Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
|
|
51
|
-
3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
|
|
52
|
-
4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
|
|
53
|
-
* You can specify specific files to upload, the line above pushes everything in dist directory.
|
|
43
|
+
A readthedocs for this library can be found [here](https://david-andrew-gutman-dsa-helpers.readthedocs-hosted.com/en/latest/index.html).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Digital Slide Archive (DSA) Helpers
|
|
2
|
+
Digital Slide Archive Python utility library.
|
|
3
|
+
|
|
4
|
+
This library is available for installation through [Python Package Index (PyPI)](https://pypi.org/).
|
|
5
|
+
|
|
6
|
+
This library was tested using Python version 3.11.8 and uses the dependencies described in requirements.txt.
|
|
7
|
+
|
|
8
|
+
This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
|
|
9
|
+
|
|
10
|
+
## Extra dependencies
|
|
11
|
+
If you are getting a large image error, then install large image using the instructions provided in their [GitHub page](https://github.com/girder/large_image#:~:text=pip%20install%20large%2Dimage%5Ball%5D%20%2D%2Dfind%2Dlinks%20https%3A//girder.github.io/large_image_wheels).
|
|
12
|
+
|
|
13
|
+
A readthedocs for this library can be found [here](https://david-andrew-gutman-dsa-helpers.readthedocs-hosted.com/en/latest/index.html).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Image utility functions for DSA Helpers.
|
|
2
|
+
|
|
3
|
+
This module provides various utility functions for image processing and
|
|
4
|
+
manipulation.
|
|
5
|
+
|
|
6
|
+
It includes functions for:
|
|
7
|
+
- Exctracting contours from binary masks, and formatting them into a
|
|
8
|
+
GeoDataFrame.
|
|
9
|
+
|
|
10
|
+
Note:
|
|
11
|
+
This module requires external dependencies such as OpenCV and
|
|
12
|
+
shapely.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import cv2 as cv
|
|
17
|
+
from .imread import imread
|
|
18
|
+
|
|
19
|
+
from shapely.affinity import translate
|
|
20
|
+
from shapely.geometry import Polygon
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def label_mask_to_polygons(
|
|
24
|
+
mask: str | np.ndarray,
|
|
25
|
+
x_offset: int = 0,
|
|
26
|
+
y_offset: int = 0,
|
|
27
|
+
exclude_labels: int | list[int] = 0,
|
|
28
|
+
min_area: int = 0,
|
|
29
|
+
) -> list[Polygon, int]:
|
|
30
|
+
"""
|
|
31
|
+
Extract contours from a label mask and convert them into shapely
|
|
32
|
+
polygons.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
mask (str | np.ndarray): Path to the mask image or the mask.
|
|
36
|
+
x_offset (int): Offset to add to x coordinates of polygons.
|
|
37
|
+
y_offset (int): Offset to add to y coordinates of polygons.
|
|
38
|
+
exclude_labels (int | list[int]): Label(s) to exclude from the
|
|
39
|
+
output.
|
|
40
|
+
min_area (int): Minimum area of polygons to include.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
list[Polygon, int]: List of polygons and their corresponding
|
|
44
|
+
labels.
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
# Convert exclude_labels to a list if it's an integer.
|
|
48
|
+
if isinstance(exclude_labels, int):
|
|
49
|
+
exclude_labels = [exclude_labels]
|
|
50
|
+
|
|
51
|
+
# Read the mask if it's a path.
|
|
52
|
+
if isinstance(mask, str):
|
|
53
|
+
mask = imread(mask, grayscale=True)
|
|
54
|
+
|
|
55
|
+
# Unique labels, excluding those specified in exclude_labels.
|
|
56
|
+
labels = [
|
|
57
|
+
label for label in np.unique(mask) if label not in exclude_labels
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
polygons = [] # track all polygons
|
|
61
|
+
|
|
62
|
+
# Loop through unique label index.
|
|
63
|
+
for label in labels:
|
|
64
|
+
# Filter to mask for this label.
|
|
65
|
+
label_mask = (mask == label).astype(np.uint8)
|
|
66
|
+
|
|
67
|
+
# Find contours.
|
|
68
|
+
contours, hierarchy = cv.findContours(
|
|
69
|
+
label_mask, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Process the contours.
|
|
73
|
+
polygons_dict = {}
|
|
74
|
+
|
|
75
|
+
for idx, (contour, h) in enumerate(zip(contours, hierarchy[0])):
|
|
76
|
+
# The contour should contain at least three points, otherwise it's
|
|
77
|
+
# not a polygon.
|
|
78
|
+
if len(contour) > 3:
|
|
79
|
+
# To include holes, group the polygons by their parent index.
|
|
80
|
+
if idx not in polygons_dict:
|
|
81
|
+
polygons_dict[idx] = {"holes": []}
|
|
82
|
+
|
|
83
|
+
if h[3] == -1:
|
|
84
|
+
# This does not have a parent so its a polygon.
|
|
85
|
+
polygons_dict[idx]["polygon"] = contour.reshape(-1, 2)
|
|
86
|
+
else:
|
|
87
|
+
# This has a parent so its a hole.
|
|
88
|
+
polygons_dict[h[3]]["holes"].append(contour.reshape(-1, 2))
|
|
89
|
+
|
|
90
|
+
# Convert to shapely polygon objects.
|
|
91
|
+
for data in polygons_dict.values():
|
|
92
|
+
polygon = Polygon(data["polygon"], holes=data["holes"])
|
|
93
|
+
|
|
94
|
+
# Shift the polygon by the offset.
|
|
95
|
+
polygon = translate(polygon, xoff=x_offset, yoff=y_offset)
|
|
96
|
+
|
|
97
|
+
# Include the polygon if it's greater than the minimum area.
|
|
98
|
+
if polygon.area >= min_area:
|
|
99
|
+
polygons.append([polygon, int(label)])
|
|
100
|
+
|
|
101
|
+
return polygons
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Utility functions for DSA Helpers.
|
|
2
|
+
|
|
3
|
+
This module provides various miscellaneous utility functions that are
|
|
4
|
+
not grouped into their own modules.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from shapely.geometry import Polygon
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def remove_small_holes(
|
|
11
|
+
polygon: Polygon, hole_area_threshold: float
|
|
12
|
+
) -> Polygon:
|
|
13
|
+
"""Remove small holes from a shapely polygon.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
polygon (shapely.geometry.Polygon): Polygon to remove holes
|
|
17
|
+
from.
|
|
18
|
+
hole_area_threshold (float): Minimum area of a hole to keep it.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
shapely.geometry.Polygon: Polygon with small holes removed.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
if not polygon.interiors: # if there are no holes, return as is
|
|
25
|
+
return polygon
|
|
26
|
+
|
|
27
|
+
# Filter out small holes
|
|
28
|
+
new_holes = [
|
|
29
|
+
hole
|
|
30
|
+
for hole in polygon.interiors
|
|
31
|
+
if Polygon(hole).area > hole_area_threshold
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# Create a new polygon with only large holes
|
|
35
|
+
return Polygon(polygon.exterior, new_holes)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: dsa_helpers
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4.dev1
|
|
4
4
|
Summary: Utility functions for working with the DSA girder client.
|
|
5
5
|
Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
|
|
6
6
|
Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
|
|
@@ -26,6 +26,7 @@ Requires-Dist: transformers[torch]
|
|
|
26
26
|
Requires-Dist: datasets
|
|
27
27
|
Requires-Dist: torchvision
|
|
28
28
|
Requires-Dist: large-image
|
|
29
|
+
Dynamic: license-file
|
|
29
30
|
|
|
30
31
|
# Digital Slide Archive (DSA) Helpers
|
|
31
32
|
Digital Slide Archive Python utility library.
|
|
@@ -39,15 +40,4 @@ This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
|
|
|
39
40
|
## Extra dependencies
|
|
40
41
|
If you are getting a large image error, then install large image using the instructions provided in their [GitHub page](https://github.com/girder/large_image#:~:text=pip%20install%20large%2Dimage%5Ball%5D%20%2D%2Dfind%2Dlinks%20https%3A//girder.github.io/large_image_wheels).
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
1. Install requirements for building and distributing package:
|
|
44
|
-
```
|
|
45
|
-
$ python3 -m pip install --upgrade build # for building package
|
|
46
|
-
$ python3 -m pip install --upgrade twine # for uploading to PyPI
|
|
47
|
-
```
|
|
48
|
-
2. When ready to build:
|
|
49
|
-
- Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
|
|
50
|
-
- Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
|
|
51
|
-
3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
|
|
52
|
-
4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
|
|
53
|
-
* You can specify specific files to upload, the line above pushes everything in dist directory.
|
|
43
|
+
A readthedocs for this library can be found [here](https://david-andrew-gutman-dsa-helpers.readthedocs-hosted.com/en/latest/index.html).
|
|
@@ -8,15 +8,6 @@
|
|
|
8
8
|
"Test different functions of the library."
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
|
-
{
|
|
12
|
-
"cell_type": "code",
|
|
13
|
-
"execution_count": 1,
|
|
14
|
-
"metadata": {},
|
|
15
|
-
"outputs": [],
|
|
16
|
-
"source": [
|
|
17
|
-
"import dsa_helpers.dash"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
11
|
{
|
|
21
12
|
"cell_type": "markdown",
|
|
22
13
|
"metadata": {},
|
|
@@ -101,7 +92,28 @@
|
|
|
101
92
|
"cell_type": "code",
|
|
102
93
|
"execution_count": null,
|
|
103
94
|
"metadata": {},
|
|
104
|
-
"outputs": [
|
|
95
|
+
"outputs": [
|
|
96
|
+
{
|
|
97
|
+
"name": "stdout",
|
|
98
|
+
"output_type": "stream",
|
|
99
|
+
"text": [
|
|
100
|
+
"Help on function imwrite in module dsa_helpers.imwrite:\n",
|
|
101
|
+
"\n",
|
|
102
|
+
"imwrite(fp: str, img: numpy.ndarray, grayscale: bool = False) -> None\n",
|
|
103
|
+
" Save an image to disk.\n",
|
|
104
|
+
"\n",
|
|
105
|
+
" Args:\n",
|
|
106
|
+
" img (np.ndarray): The image to save.\n",
|
|
107
|
+
" fp (str): The file path to save the image.\n",
|
|
108
|
+
" grayscale (bool, optional): Whether to save the image as grayscale.\n",
|
|
109
|
+
" Defaults to False.\n",
|
|
110
|
+
"\n",
|
|
111
|
+
" Raises:\n",
|
|
112
|
+
" ValueError: The image must be grayscale, RGB, or RGBA.\n",
|
|
113
|
+
"\n"
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
],
|
|
105
117
|
"source": []
|
|
106
118
|
}
|
|
107
119
|
],
|
dsa_helpers-1.0.3.dev0/README.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Digital Slide Archive (DSA) Helpers
|
|
2
|
-
Digital Slide Archive Python utility library.
|
|
3
|
-
|
|
4
|
-
This library is available for installation through [Python Package Index (PyPI)](https://pypi.org/).
|
|
5
|
-
|
|
6
|
-
This library was tested using Python version 3.11.8 and uses the dependencies described in requirements.txt.
|
|
7
|
-
|
|
8
|
-
This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
|
|
9
|
-
|
|
10
|
-
## Extra dependencies
|
|
11
|
-
If you are getting a large image error, then install large image using the instructions provided in their [GitHub page](https://github.com/girder/large_image#:~:text=pip%20install%20large%2Dimage%5Ball%5D%20%2D%2Dfind%2Dlinks%20https%3A//girder.github.io/large_image_wheels).
|
|
12
|
-
|
|
13
|
-
## Instructions for Development
|
|
14
|
-
1. Install requirements for building and distributing package:
|
|
15
|
-
```
|
|
16
|
-
$ python3 -m pip install --upgrade build # for building package
|
|
17
|
-
$ python3 -m pip install --upgrade twine # for uploading to PyPI
|
|
18
|
-
```
|
|
19
|
-
2. When ready to build:
|
|
20
|
-
- Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
|
|
21
|
-
- Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
|
|
22
|
-
3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
|
|
23
|
-
4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
|
|
24
|
-
* You can specify specific files to upload, the line above pushes everything in dist directory.
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
from . import imread
|
|
3
|
-
import cv2 as cv
|
|
4
|
-
|
|
5
|
-
from shapely.geometry import Polygon
|
|
6
|
-
from shapely.affinity import translate
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def mask_to_shapely(
|
|
10
|
-
mask: str | np.ndarray,
|
|
11
|
-
x_offset: int = 0,
|
|
12
|
-
y_offset: int = 0,
|
|
13
|
-
background_label: int | None = 0,
|
|
14
|
-
min_area: int = 0,
|
|
15
|
-
) -> list[Polygon, int]:
|
|
16
|
-
"""
|
|
17
|
-
Extract contours from a label mask and convert them into shapely
|
|
18
|
-
polygons.
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
mask (str | np.ndarray): Path to the mask image or the mask.
|
|
22
|
-
x_offset (int): Offset to add to x coordinates of polygons.
|
|
23
|
-
Default is 0.
|
|
24
|
-
y_offset (int): Offset to add to y coordinates of polygons.
|
|
25
|
-
Default is 0.
|
|
26
|
-
background_label (int | None): Label value of the background class,
|
|
27
|
-
which is ignored. Default is 0. If None then all labels are
|
|
28
|
-
considered.
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
list[Polygon, int]: List of polygons and their corresponding
|
|
32
|
-
labels.
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
if isinstance(mask, str):
|
|
36
|
-
mask = imread(mask, grayscale=True)
|
|
37
|
-
|
|
38
|
-
# Find unique labels (excluding background 0)
|
|
39
|
-
labels = [label for label in np.unique(mask) if label != background_label]
|
|
40
|
-
|
|
41
|
-
polygons = [] # Track all polygons.
|
|
42
|
-
|
|
43
|
-
# Loop through unique label index.
|
|
44
|
-
for label in labels:
|
|
45
|
-
# Filter to mask for this label.
|
|
46
|
-
label_mask = (mask == label).astype(np.uint8)
|
|
47
|
-
|
|
48
|
-
# Find contours.
|
|
49
|
-
contours, hierarchy = cv.findContours(
|
|
50
|
-
label_mask, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
# Process the contours.
|
|
54
|
-
polygons_dict = {}
|
|
55
|
-
|
|
56
|
-
for idx, (contour, h) in enumerate(zip(contours, hierarchy[0])):
|
|
57
|
-
if len(contour) > 3:
|
|
58
|
-
if idx not in polygons_dict:
|
|
59
|
-
polygons_dict[idx] = {"holes": []}
|
|
60
|
-
|
|
61
|
-
if h[3] == -1:
|
|
62
|
-
polygons_dict[idx]["polygon"] = contour.reshape(-1, 2)
|
|
63
|
-
else:
|
|
64
|
-
polygons_dict[h[3]]["holes"].append(contour.reshape(-1, 2))
|
|
65
|
-
|
|
66
|
-
# Now that we know the polygon and the holes, create a Polygon object for each.
|
|
67
|
-
for data in polygons_dict.values():
|
|
68
|
-
if "polygon" in data:
|
|
69
|
-
polygon = Polygon(data["polygon"], holes=data["holes"])
|
|
70
|
-
|
|
71
|
-
# Shift the polygon by the offset.
|
|
72
|
-
polygon = translate(polygon, xoff=x_offset, yoff=y_offset)
|
|
73
|
-
|
|
74
|
-
# Skip small polygons.
|
|
75
|
-
if polygon.area >= min_area:
|
|
76
|
-
polygons.append([polygon, label])
|
|
77
|
-
|
|
78
|
-
return polygons
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/dash/dash_paperdragon_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/object_detection/tile_image.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4.dev1}/dsa_helpers/ml/transforms/segformer_transforms.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|