dlup 0.3.26__tar.gz → 0.3.28__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.
- {dlup-0.3.26 → dlup-0.3.28}/MANIFEST.in +2 -1
- {dlup-0.3.26/dlup.egg-info → dlup-0.3.28}/PKG-INFO +22 -2
- {dlup-0.3.26 → dlup-0.3.28}/dlup/__init__.py +3 -5
- {dlup-0.3.26 → dlup-0.3.28}/dlup/_image.py +46 -24
- {dlup-0.3.26 → dlup-0.3.28}/dlup/_region.py +2 -3
- {dlup-0.3.26 → dlup-0.3.28}/dlup/annotations.py +135 -90
- dlup-0.3.28/dlup/backends/__init__.py +1 -0
- {dlup-0.3.26/dlup/experimental_backends → dlup-0.3.28/dlup/backends}/common.py +13 -14
- dlup-0.3.28/dlup/background.py +147 -0
- dlup-0.3.26/dlup/background.py → dlup-0.3.28/dlup/background_deprecated.py +39 -149
- {dlup-0.3.26 → dlup-0.3.28}/dlup/cli/__init__.py +2 -3
- {dlup-0.3.26 → dlup-0.3.28}/dlup/cli/mask.py +14 -15
- {dlup-0.3.26 → dlup-0.3.28}/dlup/cli/wsi.py +14 -13
- {dlup-0.3.26 → dlup-0.3.28}/dlup/data/dataset.py +169 -85
- {dlup-0.3.26 → dlup-0.3.28}/dlup/data/experimental/dataset.py +14 -12
- {dlup-0.3.26 → dlup-0.3.28}/dlup/data/transforms.py +54 -32
- {dlup-0.3.26 → dlup-0.3.28}/dlup/experimental_backends/__init__.py +2 -2
- {dlup-0.3.26 → dlup-0.3.28}/dlup/experimental_backends/openslide_backend.py +4 -4
- {dlup-0.3.26 → dlup-0.3.28}/dlup/experimental_backends/pyvips_backend.py +9 -8
- {dlup-0.3.26 → dlup-0.3.28}/dlup/experimental_backends/tifffile_backend.py +7 -4
- {dlup-0.3.26 → dlup-0.3.28}/dlup/tiling.py +18 -12
- dlup-0.3.28/dlup/tools.py +83 -0
- dlup-0.3.28/dlup/types.py +17 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/utils/__init__.py +2 -10
- {dlup-0.3.26 → dlup-0.3.28}/dlup/utils/image.py +1 -1
- {dlup-0.3.26 → dlup-0.3.28}/dlup/utils/imports.py +3 -3
- {dlup-0.3.26 → dlup-0.3.28}/dlup/utils/mask.py +28 -15
- {dlup-0.3.26 → dlup-0.3.28}/dlup/utils/pyvips_utils.py +8 -4
- dlup-0.3.28/dlup/utils/tifffile_utils.py +144 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/viz/plotting.py +9 -4
- {dlup-0.3.26 → dlup-0.3.28}/dlup/writers.py +17 -10
- {dlup-0.3.26 → dlup-0.3.28/dlup.egg-info}/PKG-INFO +22 -2
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/SOURCES.txt +15 -3
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/requires.txt +1 -1
- {dlup-0.3.26 → dlup-0.3.28}/docs/conf.py +5 -1
- {dlup-0.3.26 → dlup-0.3.28}/pyproject.toml +0 -3
- {dlup-0.3.26 → dlup-0.3.28}/setup.cfg +4 -1
- {dlup-0.3.26 → dlup-0.3.28}/setup.py +1 -1
- dlup-0.3.28/tests/backends/__init__.py +0 -0
- dlup-0.3.28/tests/backends/test_common.py +115 -0
- dlup-0.3.28/tests/backends/test_tifffile_backend.py +62 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/common.py +5 -2
- {dlup-0.3.26 → dlup-0.3.28}/tests/conftest.py +2 -2
- dlup-0.3.28/tests/infer_ann.py +3 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/test_annotations.py +4 -2
- dlup-0.3.28/tests/test_cli.py +39 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/test_dataset.py +9 -4
- {dlup-0.3.26 → dlup-0.3.28}/tests/test_image.py +21 -14
- dlup-0.3.28/tests/test_logging.py +44 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/test_tiling.py +8 -8
- dlup-0.3.28/tests/test_transforms.py +76 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/test_writers.py +4 -1
- dlup-0.3.28/tests/utils/__init__.py +0 -0
- dlup-0.3.28/tests/utils/test_imports.py +24 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/utils/test_pyvips.py +0 -1
- dlup-0.3.28/tests/utils/test_tifffile.py +60 -0
- dlup-0.3.28/tests/utils/test_utils.py +32 -0
- dlup-0.3.26/dlup/tools.py +0 -71
- dlup-0.3.26/dlup/types.py +0 -15
- dlup-0.3.26/dlup/utils/tifffile_utils.py +0 -92
- dlup-0.3.26/tests/new_test.py +0 -101
- {dlup-0.3.26 → dlup-0.3.28}/CONTRIBUTING.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/LICENSE +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/README.md +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/_exceptions.py +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/data/__init__.py +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/data/experimental/__init__.py +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/logging.py +0 -0
- /dlup-0.3.26/tests/__init__.py → /dlup-0.3.28/dlup/py.typed +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup/viz/__init__.py +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/dependency_links.txt +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/entry_points.txt +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/not-zip-safe +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/dlup.egg-info/top_level.txt +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/Makefile +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/backends.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/cli.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/contributing.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/examples/dataset_examples.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/examples/tile_directory.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/examples.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/img/checkerboard.png +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/img/dataset_example.png +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/img/dataset_example2.png +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/img/overflow.png +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/img/skip.png +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/index.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/installation.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/make.bat +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/quickstart.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/tiling.rst +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/docs/writers.rst +0 -0
- {dlup-0.3.26/tests/utils → dlup-0.3.28/tests}/__init__.py +0 -0
- {dlup-0.3.26 → dlup-0.3.28}/tests/files/103S.json +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
include CONTRIBUTING.rst
|
|
2
2
|
include LICENSE
|
|
3
3
|
include README.md
|
|
4
|
+
include dlup/py.typed
|
|
4
5
|
|
|
5
6
|
recursive-include tests *
|
|
6
7
|
recursive-exclude * __pycache__
|
|
7
8
|
recursive-exclude * *.py[co]
|
|
8
9
|
|
|
9
|
-
recursive-include docs *.rst *.md conf.py Makefile make.bat *.jpg *.png *.gif
|
|
10
|
+
recursive-include docs *.rst *.md conf.py Makefile make.bat *.jpg *.png *.gif
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dlup
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.28
|
|
4
4
|
Home-page: https://github.com/NKI-AI/dlup
|
|
5
5
|
Author: Jonas Teuwen
|
|
6
6
|
Author-email: j.teuwen@nki.nl
|
|
@@ -15,8 +15,28 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Requires-Python: >=3.10
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
|
-
Provides-Extra: dev
|
|
19
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: numpy>=1.21
|
|
20
|
+
Requires-Dist: scikit-image>=0.19
|
|
21
|
+
Requires-Dist: tifftools
|
|
22
|
+
Requires-Dist: tifffile>=2023.8.12
|
|
23
|
+
Requires-Dist: pyvips>=2.2.1
|
|
24
|
+
Requires-Dist: tqdm
|
|
25
|
+
Requires-Dist: pillow>=9.2.0
|
|
26
|
+
Requires-Dist: openslide-python
|
|
27
|
+
Requires-Dist: opencv-python>=4.8.1.78
|
|
28
|
+
Requires-Dist: shapely>=2.0.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.4.1; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-mock; extra == "dev"
|
|
33
|
+
Requires-Dist: sphinx_copybutton; extra == "dev"
|
|
34
|
+
Requires-Dist: numpydoc; extra == "dev"
|
|
35
|
+
Requires-Dist: myst_parser; extra == "dev"
|
|
36
|
+
Requires-Dist: sphinx-book-theme; extra == "dev"
|
|
37
|
+
Requires-Dist: pylint; extra == "dev"
|
|
38
|
+
Requires-Dist: pydantic>=2.1.1; extra == "dev"
|
|
39
|
+
Requires-Dist: types-requests; extra == "dev"
|
|
20
40
|
|
|
21
41
|
# Deep Learning Utilities for Pathology
|
|
22
42
|
[](https://pypi.python.org/pypi/dlup)
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Copyright (c) dlup contributors
|
|
3
|
-
"""Top-level package for dlup."""
|
|
1
|
+
# Copyright (c) dlup contributors"""Top-level package for dlup."""
|
|
4
2
|
|
|
5
|
-
from ._exceptions import
|
|
3
|
+
from ._exceptions import UnsupportedSlideError
|
|
6
4
|
from ._image import SlideImage
|
|
7
5
|
from ._region import BoundaryMode, RegionView
|
|
8
6
|
|
|
9
7
|
__author__ = """dlup contributors"""
|
|
10
8
|
__email__ = "j.teuwen@nki.nl"
|
|
11
|
-
__version__ = "0.3.
|
|
9
|
+
__version__ = "0.3.28"
|
|
12
10
|
|
|
13
11
|
__all__ = ("SlideImage", "RegionView", "UnsupportedSlideError", "BoundaryMode")
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# coding=utf-8
|
|
2
1
|
# Copyright (c) dlup contributors
|
|
3
2
|
|
|
4
3
|
"""Whole slide image access objects.
|
|
@@ -13,17 +12,19 @@ import errno
|
|
|
13
12
|
import os
|
|
14
13
|
import pathlib
|
|
15
14
|
from enum import IntEnum
|
|
16
|
-
from
|
|
15
|
+
from types import TracebackType
|
|
16
|
+
from typing import Any, Literal, Optional, Type, TypeVar, cast
|
|
17
17
|
|
|
18
|
-
import numpy as np
|
|
19
|
-
import
|
|
18
|
+
import numpy as np
|
|
19
|
+
import numpy.typing as npt
|
|
20
20
|
import PIL
|
|
21
|
-
import PIL.Image
|
|
21
|
+
import PIL.Image
|
|
22
22
|
|
|
23
23
|
from dlup import UnsupportedSlideError
|
|
24
24
|
from dlup._region import BoundaryMode, RegionView
|
|
25
|
-
from dlup.
|
|
26
|
-
from dlup.
|
|
25
|
+
from dlup.backends.common import AbstractSlideBackend
|
|
26
|
+
from dlup.experimental_backends import ImageBackend # type: ignore
|
|
27
|
+
from dlup.types import GenericFloatArray, GenericIntArray, GenericNumber, GenericNumberArray, PathLike
|
|
27
28
|
from dlup.utils.image import check_if_mpp_is_valid
|
|
28
29
|
|
|
29
30
|
_Box = tuple[GenericNumber, GenericNumber, GenericNumber, GenericNumber]
|
|
@@ -42,7 +43,12 @@ class Resampling(IntEnum):
|
|
|
42
43
|
class _SlideImageRegionView(RegionView):
|
|
43
44
|
"""Represents an image view tied to a slide image."""
|
|
44
45
|
|
|
45
|
-
def __init__(
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
wsi: _TSlideImage,
|
|
49
|
+
scaling: GenericNumber,
|
|
50
|
+
boundary_mode: BoundaryMode | None = None,
|
|
51
|
+
):
|
|
46
52
|
"""Initialize with a slide image object and the scaling level."""
|
|
47
53
|
# Always call the parent init
|
|
48
54
|
super().__init__(boundary_mode=boundary_mode)
|
|
@@ -66,7 +72,9 @@ class _SlideImageRegionView(RegionView):
|
|
|
66
72
|
return self._wsi.read_region((x, y), self._scaling, (w, h))
|
|
67
73
|
|
|
68
74
|
|
|
69
|
-
def _clip2size(
|
|
75
|
+
def _clip2size(
|
|
76
|
+
a: npt.NDArray[np.int_ | np.float_], size: tuple[GenericNumber, GenericNumber]
|
|
77
|
+
) -> npt.NDArray[np.int_ | np.float_]:
|
|
70
78
|
"""Clip values from 0 to size boundaries."""
|
|
71
79
|
return np.clip(a, (0, 0), size)
|
|
72
80
|
|
|
@@ -92,7 +100,7 @@ class SlideImage:
|
|
|
92
100
|
>>> wsi = dlup.SlideImage.from_file_path('path/to/slide.svs')
|
|
93
101
|
"""
|
|
94
102
|
|
|
95
|
-
def __init__(self, wsi: AbstractSlideBackend, identifier: str | None = None, **kwargs):
|
|
103
|
+
def __init__(self, wsi: AbstractSlideBackend, identifier: str | None = None, **kwargs: Any) -> None:
|
|
96
104
|
"""Initialize a whole slide image and validate its properties."""
|
|
97
105
|
self._wsi = wsi
|
|
98
106
|
self._identifier = identifier
|
|
@@ -111,20 +119,26 @@ class SlideImage:
|
|
|
111
119
|
|
|
112
120
|
if self._wsi.spacing is None:
|
|
113
121
|
raise UnsupportedSlideError(
|
|
114
|
-
f"The spacing of {identifier} cannot be derived from image and is
|
|
122
|
+
f"The spacing of {identifier} cannot be derived from image and is "
|
|
123
|
+
"not explicitly set in the `overwrite_mpp` parameter."
|
|
115
124
|
)
|
|
116
125
|
|
|
117
126
|
check_if_mpp_is_valid(*self._wsi.spacing)
|
|
118
127
|
self._avg_native_mpp = (float(self._wsi.spacing[0]) + float(self._wsi.spacing[1])) / 2
|
|
119
128
|
|
|
120
|
-
def close(self):
|
|
129
|
+
def close(self) -> None:
|
|
121
130
|
"""Close the underlying image."""
|
|
122
131
|
self._wsi.close()
|
|
123
132
|
|
|
124
|
-
def __enter__(self):
|
|
133
|
+
def __enter__(self) -> "SlideImage":
|
|
125
134
|
return self
|
|
126
135
|
|
|
127
|
-
def __exit__(
|
|
136
|
+
def __exit__(
|
|
137
|
+
self,
|
|
138
|
+
exc_type: Optional[Type[BaseException]],
|
|
139
|
+
exc_val: Optional[BaseException],
|
|
140
|
+
exc_tb: Optional[TracebackType],
|
|
141
|
+
) -> Literal[False]:
|
|
128
142
|
self.close()
|
|
129
143
|
return False
|
|
130
144
|
|
|
@@ -133,8 +147,8 @@ class SlideImage:
|
|
|
133
147
|
cls: Type[_TSlideImage],
|
|
134
148
|
wsi_file_path: PathLike,
|
|
135
149
|
identifier: str | None = None,
|
|
136
|
-
backend:
|
|
137
|
-
**kwargs,
|
|
150
|
+
backend: ImageBackend = ImageBackend.PYVIPS,
|
|
151
|
+
**kwargs: Any,
|
|
138
152
|
) -> _TSlideImage:
|
|
139
153
|
wsi_file_path = pathlib.Path(wsi_file_path)
|
|
140
154
|
|
|
@@ -152,9 +166,9 @@ class SlideImage:
|
|
|
152
166
|
|
|
153
167
|
def read_region(
|
|
154
168
|
self,
|
|
155
|
-
location:
|
|
169
|
+
location: GenericNumberArray | tuple[GenericNumber, GenericNumber],
|
|
156
170
|
scaling: float,
|
|
157
|
-
size: np.
|
|
171
|
+
size: npt.NDArray[np.int_] | tuple[int, int],
|
|
158
172
|
) -> PIL.Image.Image:
|
|
159
173
|
"""Return a region at a specific scaling level of the pyramid.
|
|
160
174
|
|
|
@@ -202,8 +216,8 @@ class SlideImage:
|
|
|
202
216
|
Examples
|
|
203
217
|
--------
|
|
204
218
|
The locations are defined at the requested scaling (with respect to level 0), so if we want to extract at
|
|
205
|
-
location ``(location_x, location_y)`` of a scaling 0.5 (with respect to level 0), and have
|
|
206
|
-
|
|
219
|
+
location ``(location_x, location_y)`` of a scaling 0.5 (with respect to level 0), and have
|
|
220
|
+
resulting tile size of ``(tile_size, tile_size)`` with a scaling factor of 0.5, we can use:
|
|
207
221
|
>>> wsi.read_region(location=(coordinate_x, coordinate_y), scaling=0.5, size=(tile_size, tile_size))
|
|
208
222
|
"""
|
|
209
223
|
owsi = self._wsi
|
|
@@ -247,7 +261,11 @@ class SlideImage:
|
|
|
247
261
|
native_size_adapted = np.ceil(native_size_adapted).astype(int)
|
|
248
262
|
|
|
249
263
|
# We extract the region via openslide with the required extra border
|
|
250
|
-
region = owsi.read_region(
|
|
264
|
+
region = owsi.read_region(
|
|
265
|
+
(level_zero_location_adapted[0], level_zero_location_adapted[1]),
|
|
266
|
+
native_level,
|
|
267
|
+
(native_size_adapted[0], native_size_adapted[1]),
|
|
268
|
+
)
|
|
251
269
|
|
|
252
270
|
# Within this region, there are a bunch of extra pixels, we interpolate to sample
|
|
253
271
|
# the pixel in the right position to retain the right sample weight.
|
|
@@ -256,7 +274,11 @@ class SlideImage:
|
|
|
256
274
|
# TODO: This clipping could be in an error in OpenSlide mirax reader, but it's a minor thing for now
|
|
257
275
|
box = (
|
|
258
276
|
*fractional_coordinates,
|
|
259
|
-
*np.clip(
|
|
277
|
+
*np.clip(
|
|
278
|
+
(fractional_coordinates + native_size),
|
|
279
|
+
a_min=0,
|
|
280
|
+
a_max=np.asarray(region.size),
|
|
281
|
+
),
|
|
260
282
|
)
|
|
261
283
|
box = cast(tuple[float, float, float, float], box)
|
|
262
284
|
size = cast(tuple[int, int], size)
|
|
@@ -307,7 +329,7 @@ class SlideImage:
|
|
|
307
329
|
return self._identifier
|
|
308
330
|
|
|
309
331
|
@property
|
|
310
|
-
def properties(self) -> dict:
|
|
332
|
+
def properties(self) -> dict[str, str | int | float | bool] | None:
|
|
311
333
|
"""Returns any extra associated properties with the image."""
|
|
312
334
|
return self._wsi.properties
|
|
313
335
|
|
|
@@ -338,7 +360,7 @@ class SlideImage:
|
|
|
338
360
|
return width / height
|
|
339
361
|
|
|
340
362
|
@property
|
|
341
|
-
def slide_bounds(self):
|
|
363
|
+
def slide_bounds(self) -> tuple[tuple[int, int], tuple[int, int]]:
|
|
342
364
|
"""Returns the bounds of the slide. These can be smaller than the image itself.
|
|
343
365
|
These bounds are in the format (x, y), (width, height), and are defined at level 0 of the image.
|
|
344
366
|
"""
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Copyright (c) dlup contributors
|
|
2
2
|
"""Defines the RegionView interface."""
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
6
|
from enum import Enum
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import cast
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
|
-
import numpy.typing as npt
|
|
11
10
|
import PIL.Image
|
|
12
11
|
|
|
13
12
|
from dlup.types import GenericFloatArray, GenericIntArray
|