dsa-helpers 1.0.3.dev0__tar.gz → 1.0.4__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.
Files changed (49) hide show
  1. {dsa_helpers-1.0.3.dev0/dsa_helpers.egg-info → dsa_helpers-1.0.4}/PKG-INFO +4 -14
  2. dsa_helpers-1.0.4/README.md +13 -0
  3. dsa_helpers-1.0.3.dev0/dsa_helpers/utils.py → dsa_helpers-1.0.4/dsa_helpers/image_utils.py +39 -15
  4. dsa_helpers-1.0.4/dsa_helpers/utils.py +35 -0
  5. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4/dsa_helpers.egg-info}/PKG-INFO +4 -14
  6. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers.egg-info/SOURCES.txt +1 -0
  7. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/pyproject.toml +1 -1
  8. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/tests/test.ipynb +22 -10
  9. dsa_helpers-1.0.3.dev0/README.md +0 -24
  10. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/.gitignore +0 -0
  11. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/.readthedocs.yaml +0 -0
  12. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/LICENSE +0 -0
  13. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/app.py +0 -0
  14. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/docs/requirements.txt +0 -0
  15. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/docs/source/conf.py +0 -0
  16. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/docs/source/index.rst +0 -0
  17. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/__init__.py +0 -0
  18. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/dash/__init__.py +0 -0
  19. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/dash/dash_paperdragon_utils.py +0 -0
  20. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/dash/header.py +0 -0
  21. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/dash/header_callbacks.py +0 -0
  22. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/girder_utils.py +0 -0
  23. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/imread.py +0 -0
  24. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/imwrite.py +0 -0
  25. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/__init__.py +0 -0
  26. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/callbacks.py +0 -0
  27. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py +0 -0
  28. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/datasets/__init__.py +0 -0
  29. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/datasets/utils.py +0 -0
  30. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/evaluate.py +0 -0
  31. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/metrics.py +0 -0
  32. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/object_detection/__init__.py +0 -0
  33. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
  34. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
  35. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/object_detection/utils.py +0 -0
  36. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/segformer_semantic_segmentation/__init__.py +0 -0
  37. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/segformer_semantic_segmentation/inference.py +0 -0
  38. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/transforms/__init__.py +0 -0
  39. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/ml/transforms/segformer_transforms.py +0 -0
  40. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/mongo_utils.py +0 -0
  41. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/tile_utils.py +0 -0
  42. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers/tiling.py +0 -0
  43. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers.egg-info/dependency_links.txt +0 -0
  44. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers.egg-info/requires.txt +0 -0
  45. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/dsa_helpers.egg-info/top_level.txt +0 -0
  46. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/setup.cfg +0 -0
  47. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/tests/app/Dockerfile +0 -0
  48. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/tests/app/app.py +0 -0
  49. {dsa_helpers-1.0.3.dev0 → dsa_helpers-1.0.4}/tests/docker-compose.yaml +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: dsa_helpers
3
- Version: 1.0.3.dev0
3
+ Version: 1.0.4
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
- ## Instructions for Development
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).
@@ -1,16 +1,30 @@
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
+
1
15
  import numpy as np
2
- from . import imread
3
16
  import cv2 as cv
17
+ from .imread import imread
4
18
 
5
- from shapely.geometry import Polygon
6
19
  from shapely.affinity import translate
20
+ from shapely.geometry import Polygon
7
21
 
8
22
 
9
- def mask_to_shapely(
23
+ def label_mask_to_polygons(
10
24
  mask: str | np.ndarray,
11
25
  x_offset: int = 0,
12
26
  y_offset: int = 0,
13
- background_label: int | None = 0,
27
+ exclude_labels: int | list[int] = 0,
14
28
  min_area: int = 0,
15
29
  ) -> list[Polygon, int]:
16
30
  """
@@ -20,25 +34,30 @@ def mask_to_shapely(
20
34
  Args:
21
35
  mask (str | np.ndarray): Path to the mask image or the mask.
22
36
  x_offset (int): Offset to add to x coordinates of polygons.
23
- Default is 0.
24
37
  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.
38
+ exclude_labels (int | list[int]): Label(s) to exclude from the
39
+ output.
40
+ min_area (int): Minimum area of polygons to include.
29
41
 
30
42
  Returns:
31
43
  list[Polygon, int]: List of polygons and their corresponding
32
44
  labels.
33
45
 
34
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.
35
52
  if isinstance(mask, str):
36
53
  mask = imread(mask, grayscale=True)
37
54
 
38
- # Find unique labels (excluding background 0)
39
- labels = [label for label in np.unique(mask) if label != background_label]
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
+ ]
40
59
 
41
- polygons = [] # Track all polygons.
60
+ polygons = [] # track all polygons
42
61
 
43
62
  # Loop through unique label index.
44
63
  for label in labels:
@@ -54,16 +73,21 @@ def mask_to_shapely(
54
73
  polygons_dict = {}
55
74
 
56
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.
57
78
  if len(contour) > 3:
79
+ # To include holes, group the polygons by their parent index.
58
80
  if idx not in polygons_dict:
59
81
  polygons_dict[idx] = {"holes": []}
60
82
 
61
83
  if h[3] == -1:
84
+ # This does not have a parent so its a polygon.
62
85
  polygons_dict[idx]["polygon"] = contour.reshape(-1, 2)
63
86
  else:
87
+ # This has a parent so its a hole.
64
88
  polygons_dict[h[3]]["holes"].append(contour.reshape(-1, 2))
65
89
 
66
- # Now that we know the polygon and the holes, create a Polygon object for each.
90
+ # Convert to shapely polygon objects.
67
91
  for data in polygons_dict.values():
68
92
  if "polygon" in data:
69
93
  polygon = Polygon(data["polygon"], holes=data["holes"])
@@ -71,8 +95,8 @@ def mask_to_shapely(
71
95
  # Shift the polygon by the offset.
72
96
  polygon = translate(polygon, xoff=x_offset, yoff=y_offset)
73
97
 
74
- # Skip small polygons.
98
+ # Include the polygon if it's greater than the minimum area.
75
99
  if polygon.area >= min_area:
76
- polygons.append([polygon, label])
100
+ polygons.append([polygon, int(label)])
77
101
 
78
102
  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.2
1
+ Metadata-Version: 2.4
2
2
  Name: dsa_helpers
3
- Version: 1.0.3.dev0
3
+ Version: 1.0.4
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
- ## Instructions for Development
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).
@@ -9,6 +9,7 @@ docs/source/conf.py
9
9
  docs/source/index.rst
10
10
  dsa_helpers/__init__.py
11
11
  dsa_helpers/girder_utils.py
12
+ dsa_helpers/image_utils.py
12
13
  dsa_helpers/imread.py
13
14
  dsa_helpers/imwrite.py
14
15
  dsa_helpers/mongo_utils.py
@@ -35,7 +35,7 @@ classifiers = [
35
35
  "License :: OSI Approved :: MIT License",
36
36
  ]
37
37
  keywords = ["dsa", "girder", "girder_client"]
38
- version = "v1.0.3.dev0"
38
+ version = "v1.0.4"
39
39
 
40
40
  [project.urls]
41
41
  Repository = "https://github.com/Gutman-Lab/dsa-python-utils"
@@ -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
  ],
@@ -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.
File without changes
File without changes
File without changes
File without changes