deepdoctection 0.42.1__py3-none-any.whl → 0.43__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.
Potentially problematic release.
This version of deepdoctection might be problematic. Click here for more details.
- deepdoctection/__init__.py +2 -1
- deepdoctection/analyzer/__init__.py +2 -1
- deepdoctection/analyzer/config.py +904 -0
- deepdoctection/analyzer/dd.py +36 -62
- deepdoctection/analyzer/factory.py +311 -141
- deepdoctection/configs/conf_dd_one.yaml +100 -44
- deepdoctection/configs/profiles.jsonl +32 -0
- deepdoctection/dataflow/__init__.py +9 -6
- deepdoctection/dataflow/base.py +33 -15
- deepdoctection/dataflow/common.py +96 -75
- deepdoctection/dataflow/custom.py +36 -29
- deepdoctection/dataflow/custom_serialize.py +135 -91
- deepdoctection/dataflow/parallel_map.py +33 -31
- deepdoctection/dataflow/serialize.py +15 -10
- deepdoctection/dataflow/stats.py +41 -28
- deepdoctection/datapoint/__init__.py +4 -6
- deepdoctection/datapoint/annotation.py +104 -66
- deepdoctection/datapoint/box.py +190 -130
- deepdoctection/datapoint/convert.py +66 -39
- deepdoctection/datapoint/image.py +151 -95
- deepdoctection/datapoint/view.py +383 -236
- deepdoctection/datasets/__init__.py +2 -6
- deepdoctection/datasets/adapter.py +11 -11
- deepdoctection/datasets/base.py +118 -81
- deepdoctection/datasets/dataflow_builder.py +18 -12
- deepdoctection/datasets/info.py +76 -57
- deepdoctection/datasets/instances/__init__.py +6 -2
- deepdoctection/datasets/instances/doclaynet.py +17 -14
- deepdoctection/datasets/instances/fintabnet.py +16 -22
- deepdoctection/datasets/instances/funsd.py +11 -6
- deepdoctection/datasets/instances/iiitar13k.py +9 -9
- deepdoctection/datasets/instances/layouttest.py +9 -9
- deepdoctection/datasets/instances/publaynet.py +9 -9
- deepdoctection/datasets/instances/pubtables1m.py +13 -13
- deepdoctection/datasets/instances/pubtabnet.py +13 -15
- deepdoctection/datasets/instances/rvlcdip.py +8 -8
- deepdoctection/datasets/instances/xfund.py +11 -9
- deepdoctection/datasets/registry.py +18 -11
- deepdoctection/datasets/save.py +12 -11
- deepdoctection/eval/__init__.py +3 -2
- deepdoctection/eval/accmetric.py +72 -52
- deepdoctection/eval/base.py +29 -10
- deepdoctection/eval/cocometric.py +14 -12
- deepdoctection/eval/eval.py +56 -41
- deepdoctection/eval/registry.py +6 -3
- deepdoctection/eval/tedsmetric.py +24 -9
- deepdoctection/eval/tp_eval_callback.py +13 -12
- deepdoctection/extern/__init__.py +1 -1
- deepdoctection/extern/base.py +176 -97
- deepdoctection/extern/d2detect.py +127 -92
- deepdoctection/extern/deskew.py +19 -10
- deepdoctection/extern/doctrocr.py +157 -106
- deepdoctection/extern/fastlang.py +25 -17
- deepdoctection/extern/hfdetr.py +137 -60
- deepdoctection/extern/hflayoutlm.py +329 -248
- deepdoctection/extern/hflm.py +67 -33
- deepdoctection/extern/model.py +108 -762
- deepdoctection/extern/pdftext.py +37 -12
- deepdoctection/extern/pt/nms.py +15 -1
- deepdoctection/extern/pt/ptutils.py +13 -9
- deepdoctection/extern/tessocr.py +87 -54
- deepdoctection/extern/texocr.py +29 -14
- deepdoctection/extern/tp/tfutils.py +36 -8
- deepdoctection/extern/tp/tpcompat.py +54 -16
- deepdoctection/extern/tp/tpfrcnn/config/config.py +20 -4
- deepdoctection/extern/tpdetect.py +4 -2
- deepdoctection/mapper/__init__.py +1 -1
- deepdoctection/mapper/cats.py +117 -76
- deepdoctection/mapper/cocostruct.py +35 -17
- deepdoctection/mapper/d2struct.py +56 -29
- deepdoctection/mapper/hfstruct.py +32 -19
- deepdoctection/mapper/laylmstruct.py +221 -185
- deepdoctection/mapper/maputils.py +71 -35
- deepdoctection/mapper/match.py +76 -62
- deepdoctection/mapper/misc.py +68 -44
- deepdoctection/mapper/pascalstruct.py +13 -12
- deepdoctection/mapper/prodigystruct.py +33 -19
- deepdoctection/mapper/pubstruct.py +42 -32
- deepdoctection/mapper/tpstruct.py +39 -19
- deepdoctection/mapper/xfundstruct.py +20 -13
- deepdoctection/pipe/__init__.py +1 -2
- deepdoctection/pipe/anngen.py +104 -62
- deepdoctection/pipe/base.py +226 -107
- deepdoctection/pipe/common.py +206 -123
- deepdoctection/pipe/concurrency.py +74 -47
- deepdoctection/pipe/doctectionpipe.py +108 -47
- deepdoctection/pipe/language.py +41 -24
- deepdoctection/pipe/layout.py +45 -18
- deepdoctection/pipe/lm.py +146 -78
- deepdoctection/pipe/order.py +196 -113
- deepdoctection/pipe/refine.py +111 -63
- deepdoctection/pipe/registry.py +1 -1
- deepdoctection/pipe/segment.py +213 -142
- deepdoctection/pipe/sub_layout.py +76 -46
- deepdoctection/pipe/text.py +52 -33
- deepdoctection/pipe/transform.py +8 -6
- deepdoctection/train/d2_frcnn_train.py +87 -69
- deepdoctection/train/hf_detr_train.py +72 -40
- deepdoctection/train/hf_layoutlm_train.py +85 -46
- deepdoctection/train/tp_frcnn_train.py +56 -28
- deepdoctection/utils/concurrency.py +59 -16
- deepdoctection/utils/context.py +40 -19
- deepdoctection/utils/develop.py +25 -17
- deepdoctection/utils/env_info.py +85 -36
- deepdoctection/utils/error.py +16 -10
- deepdoctection/utils/file_utils.py +246 -62
- deepdoctection/utils/fs.py +162 -43
- deepdoctection/utils/identifier.py +29 -16
- deepdoctection/utils/logger.py +49 -32
- deepdoctection/utils/metacfg.py +83 -21
- deepdoctection/utils/pdf_utils.py +119 -62
- deepdoctection/utils/settings.py +24 -10
- deepdoctection/utils/tqdm.py +10 -5
- deepdoctection/utils/transform.py +182 -46
- deepdoctection/utils/utils.py +61 -28
- deepdoctection/utils/viz.py +150 -104
- deepdoctection-0.43.dist-info/METADATA +376 -0
- deepdoctection-0.43.dist-info/RECORD +149 -0
- deepdoctection/analyzer/_config.py +0 -146
- deepdoctection-0.42.1.dist-info/METADATA +0 -431
- deepdoctection-0.42.1.dist-info/RECORD +0 -148
- {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.dist-info}/WHEEL +0 -0
- {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.dist-info}/licenses/LICENSE +0 -0
- {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.dist-info}/top_level.txt +0 -0
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
"""
|
|
19
|
-
Conversion functions
|
|
19
|
+
Conversion functions for images and pdfs
|
|
20
20
|
"""
|
|
21
|
+
|
|
21
22
|
import base64
|
|
22
23
|
import copy
|
|
23
24
|
from dataclasses import fields, is_dataclass
|
|
@@ -47,12 +48,13 @@ __all__ = [
|
|
|
47
48
|
|
|
48
49
|
def as_dict(obj: Any, dict_factory) -> Union[Any]: # type: ignore
|
|
49
50
|
"""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
Args:
|
|
52
|
+
custom func: as_dict to use instead of `dataclasses.asdict` . It also checks if a dataclass has a
|
|
53
|
+
'remove_keys' and will remove all attributes that are returned. Ensures that private attributes
|
|
54
|
+
are not taken into account when generating a `dict`.
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
obj: Object to convert into a dict.
|
|
57
|
+
dict_factory: A factory to generate the dict.
|
|
56
58
|
"""
|
|
57
59
|
|
|
58
60
|
if is_dataclass(obj):
|
|
@@ -79,10 +81,13 @@ def as_dict(obj: Any, dict_factory) -> Union[Any]: # type: ignore
|
|
|
79
81
|
|
|
80
82
|
def convert_b64_to_np_array(image: str) -> PixelValues:
|
|
81
83
|
"""
|
|
82
|
-
Converts an image in base4 string encoding representation to a
|
|
84
|
+
Converts an image in base4 string encoding representation to a `np.array` of shape `(width,height,channel)`.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
image: An image as `base64` string.
|
|
83
88
|
|
|
84
|
-
:
|
|
85
|
-
|
|
89
|
+
Returns:
|
|
90
|
+
numpy array.
|
|
86
91
|
"""
|
|
87
92
|
|
|
88
93
|
return viz_handler.convert_b64_to_np(image).astype(uint8)
|
|
@@ -92,8 +97,11 @@ def convert_np_array_to_b64(np_image: PixelValues) -> str:
|
|
|
92
97
|
"""
|
|
93
98
|
Converts an image from numpy array into a base64 string encoding representation
|
|
94
99
|
|
|
95
|
-
:
|
|
96
|
-
|
|
100
|
+
Args:
|
|
101
|
+
np_image: An image as numpy array.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
An image as `base64` string.
|
|
97
105
|
"""
|
|
98
106
|
return viz_handler.convert_np_to_b64(np_image)
|
|
99
107
|
|
|
@@ -103,18 +111,24 @@ def convert_np_array_to_b64_b(np_image: PixelValues) -> bytes:
|
|
|
103
111
|
"""
|
|
104
112
|
Converts an image from numpy array into a base64 bytes encoding representation
|
|
105
113
|
|
|
106
|
-
:
|
|
107
|
-
|
|
114
|
+
Args:
|
|
115
|
+
np_image: An image as numpy array.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
An image as `base64` bytes.
|
|
108
119
|
"""
|
|
109
120
|
return viz_handler.encode(np_image)
|
|
110
121
|
|
|
111
122
|
|
|
112
123
|
def convert_bytes_to_np_array(image_bytes: bytes) -> PixelValues:
|
|
113
124
|
"""
|
|
114
|
-
Converts an image in bytes to a
|
|
125
|
+
Converts an image in `bytes` to a `np.array`
|
|
115
126
|
|
|
116
|
-
:
|
|
117
|
-
|
|
127
|
+
Args:
|
|
128
|
+
image_bytes: An image as bytes.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
numpy array.
|
|
118
132
|
"""
|
|
119
133
|
return viz_handler.convert_bytes_to_np(image_bytes)
|
|
120
134
|
|
|
@@ -122,15 +136,20 @@ def convert_bytes_to_np_array(image_bytes: bytes) -> PixelValues:
|
|
|
122
136
|
@deprecated("Use convert_pdf_bytes_to_np_array_v2", "2022-02-23")
|
|
123
137
|
def convert_pdf_bytes_to_np_array(pdf_bytes: bytes, dpi: Optional[int] = None) -> PixelValues:
|
|
124
138
|
"""
|
|
125
|
-
Converts a pdf passed as bytes into a
|
|
126
|
-
Please check the installation guides at https://poppler.freedesktop.org
|
|
127
|
-
the output size will be determined by the mediaBox of the pdf file ready.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
:
|
|
133
|
-
|
|
139
|
+
Converts a pdf passed as bytes into a `np.array`. Note, that this method expects poppler to be installed.
|
|
140
|
+
Please check the installation guides at <https://poppler.freedesktop.org/> . If no value for `dpi` is provided
|
|
141
|
+
the output size will be determined by the mediaBox of the pdf file ready.
|
|
142
|
+
|
|
143
|
+
Note:
|
|
144
|
+
The image size will be in this case rather small.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
pdf_bytes: A pdf as bytes object. A byte representation can from a pdf file can be generated e.g. with
|
|
148
|
+
`utils.fs.load_bytes_from_pdf_file`
|
|
149
|
+
dpi: The dpi value of the resulting output image. For high resolution set `dpi=300`.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
Image as numpy array.
|
|
134
153
|
"""
|
|
135
154
|
from pdf2image import convert_from_bytes # type: ignore # pylint: disable=C0415, E0401
|
|
136
155
|
|
|
@@ -159,20 +178,28 @@ def convert_pdf_bytes_to_np_array_v2(
|
|
|
159
178
|
pdf_bytes: bytes, dpi: Optional[int] = None, width: Optional[int] = None, height: Optional[int] = None
|
|
160
179
|
) -> PixelValues:
|
|
161
180
|
"""
|
|
162
|
-
Converts a pdf passed as bytes into a numpy array. We use poppler or pdfmium to convert the pdf to an image.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
:
|
|
174
|
-
|
|
175
|
-
|
|
181
|
+
Converts a pdf passed as bytes into a numpy array. We use poppler or `pdfmium` to convert the pdf to an image.
|
|
182
|
+
|
|
183
|
+
Note:
|
|
184
|
+
If both is available you can steer the selection of the render engine with environment variables:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
# Set the environment variable to use poppler
|
|
188
|
+
USE_DD_POPPLER="1" or ("TRUE", "True")
|
|
189
|
+
USE_DD_PDFIUM="0" or anything that is not ("1", "TRUE", "True")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
pdf_bytes: A pdf as bytes object. A byte representation can from a pdf file can be generated e.g. with
|
|
194
|
+
`utils.fs.load_bytes_from_pdf_file`
|
|
195
|
+
dpi: The dpi value of the resulting output image. For high resolution set dpi=300.
|
|
196
|
+
width: The width of the resulting output image. This option does only work when using Poppler as
|
|
197
|
+
PDF renderer
|
|
198
|
+
height: The height of the resulting output image. This option does only work when using Poppler as
|
|
199
|
+
PDF renderer
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Image as numpy array.
|
|
176
203
|
"""
|
|
177
204
|
|
|
178
205
|
if dpi is None:
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
"""
|
|
19
|
-
Dataclass Image
|
|
19
|
+
Dataclass `Image`
|
|
20
20
|
"""
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
@@ -51,35 +51,39 @@ class Image:
|
|
|
51
51
|
Data points from datasets must be mapped in this format so that the processing tools (pipeline components) can
|
|
52
52
|
be called up without further adjustment.
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
An image can be provided with an image_id by providing the external_id, which can be clearly identified
|
|
58
|
-
as a md5 hash string. If such an id is not given, an image_id is derived from the file_name and, if necessary,
|
|
59
|
-
from the given location.
|
|
60
|
-
|
|
61
|
-
When initializing the object, the following arguments can be specified:
|
|
62
|
-
|
|
63
|
-
`file_name`: Should be equal to the name of a physical file representing the image. If the image is part
|
|
64
|
-
of a larger document (e.g. pdf-document) the file_name should be populated as a concatenation of the document file
|
|
65
|
-
and its page number.
|
|
66
|
-
|
|
67
|
-
`location`: Full path to the document or to the physical file. Loading functions from disk use this attribute.
|
|
68
|
-
|
|
69
|
-
`external_id`: A string or integer value for generating an image id.
|
|
54
|
+
An image can be provided with an `image_id` by providing the `external_id`, which can be clearly identified
|
|
55
|
+
as a `md5` hash. If such an id is not given, an `image_id` will be derived from `file_name` and, if necessary,
|
|
56
|
+
from `location`.
|
|
70
57
|
|
|
71
58
|
All other attributes represent containers (lists or dicts) that can be populated and managed using their own method.
|
|
72
59
|
|
|
73
|
-
In `image`, the image may be saved as np.array
|
|
74
|
-
possible and are converted via a `image.setter`. Other formats are rejected.
|
|
75
|
-
the width and height of the image are determined.
|
|
60
|
+
In `image`, the image may be saved as `np.array`. Allocation as `base64` encoding string or as pdf bytes are
|
|
61
|
+
possible and are converted via a `image.setter`. Other formats are rejected.
|
|
62
|
+
If an image of a given size is added, the width and height of the image are determined.
|
|
63
|
+
|
|
76
64
|
Using `embeddings`, various bounding boxes can be saved that describe the position of the image as a
|
|
77
|
-
sub-image
|
|
78
|
-
Embeddings are often used in connection with annotations in which `image` is populated.
|
|
65
|
+
sub-image. The bounding box is accessed in relation to the embedding image via the `annotation_id`.
|
|
66
|
+
Embeddings are often used in connection with annotations in which the `image` is populated.
|
|
67
|
+
|
|
68
|
+
All `ImageAnnotations` of the image are saved in the list annotations. Other types of annotation are
|
|
69
|
+
not permitted.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
file_name: Should be equal to the name of a physical file representing the image. If the image is part
|
|
73
|
+
of a larger document (e.g. pdf-document) the file_name should be populated as a concatenation of
|
|
74
|
+
the document file and its page number.
|
|
75
|
+
location: Full path to the document or to the physical file. Loading functions from disk use this attribute.
|
|
76
|
+
document_id: A unique identifier for the document. If not set, it will be set to the `image_id`.
|
|
77
|
+
page_number: The page number of the image in the document. If not set, it will be set to 0.
|
|
78
|
+
external_id: A string or integer value for generating an `image_id`.
|
|
79
|
+
_image_id: A unique identifier for the image. If not set, it will be set to a generated `uuid`.
|
|
80
|
+
_image: The image as a numpy array. If not set, it will be set to None. Do not set this attribute directly.
|
|
81
|
+
_bbox: The bounding box of the image. If not set, it will be set to None. Do not set this attribute directly.
|
|
82
|
+
embeddings: A dictionary of `image_id` to `BoundingBox`es. If not set, it will be set to an empty dict.
|
|
83
|
+
annotations: A list of `ImageAnnotation` objects. Use `get_annotation` to retrieve annotations.
|
|
84
|
+
_annotation_ids: A list of `annotation_id`s. Used internally to ensure uniqueness of annotations.
|
|
85
|
+
_summary: A `CategoryAnnotation` for image-level informations. If not set, it will be set to None.
|
|
79
86
|
|
|
80
|
-
All ImageAnnotations associated with the image are used in the list annotations. Other types of annotation are
|
|
81
|
-
not permitted and must either be transported as sub-category of an ImageAnnotation or placed as a summary
|
|
82
|
-
annotation in the `summary`.
|
|
83
87
|
"""
|
|
84
88
|
|
|
85
89
|
file_name: str
|
|
@@ -109,7 +113,7 @@ class Image:
|
|
|
109
113
|
@property
|
|
110
114
|
def image_id(self) -> str:
|
|
111
115
|
"""
|
|
112
|
-
image_id
|
|
116
|
+
`image_id`
|
|
113
117
|
"""
|
|
114
118
|
if self._image_id is not None:
|
|
115
119
|
return self._image_id
|
|
@@ -118,7 +122,7 @@ class Image:
|
|
|
118
122
|
@image_id.setter
|
|
119
123
|
def image_id(self, input_id: str) -> None:
|
|
120
124
|
"""
|
|
121
|
-
image_id setter
|
|
125
|
+
`image_id` setter
|
|
122
126
|
"""
|
|
123
127
|
if self._image_id is not None:
|
|
124
128
|
raise ImageError("image_id already defined and cannot be reset")
|
|
@@ -140,10 +144,14 @@ class Image:
|
|
|
140
144
|
def image(self, image: Optional[Union[str, PixelValues, bytes]]) -> None:
|
|
141
145
|
"""
|
|
142
146
|
Sets the image for internal storage. Will convert to numpy array before storing internally.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
|
|
148
|
+
Note:
|
|
149
|
+
If the input is an np.array, ensure that the image is in BGR-format as this is the standard
|
|
150
|
+
format for the whole package.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
image: Accepts `np.array`s, `base64` encodings or `bytes` generated from pdf documents.
|
|
154
|
+
Everything else will be rejected.
|
|
147
155
|
"""
|
|
148
156
|
|
|
149
157
|
if isinstance(image, property):
|
|
@@ -184,7 +192,7 @@ class Image:
|
|
|
184
192
|
@property
|
|
185
193
|
def pdf_bytes(self) -> Optional[bytes]:
|
|
186
194
|
"""
|
|
187
|
-
pdf_bytes
|
|
195
|
+
`pdf_bytes`. This attribute will be set dynamically and is not part of the core Image data model
|
|
188
196
|
"""
|
|
189
197
|
if hasattr(self, "_pdf_bytes"):
|
|
190
198
|
return getattr(self, "_pdf_bytes")
|
|
@@ -193,7 +201,7 @@ class Image:
|
|
|
193
201
|
@pdf_bytes.setter
|
|
194
202
|
def pdf_bytes(self, pdf_bytes: bytes) -> None:
|
|
195
203
|
"""
|
|
196
|
-
pdf_bytes setter
|
|
204
|
+
`pdf_bytes` setter
|
|
197
205
|
"""
|
|
198
206
|
assert isinstance(pdf_bytes, bytes)
|
|
199
207
|
if not hasattr(self, "_pdf_bytes"):
|
|
@@ -203,9 +211,10 @@ class Image:
|
|
|
203
211
|
"""
|
|
204
212
|
Removes the `Image.image`. Useful, if the image must be a lightweight object.
|
|
205
213
|
|
|
206
|
-
:
|
|
207
|
-
|
|
208
|
-
|
|
214
|
+
Args:
|
|
215
|
+
clear_bbox: If set to `True` it will remove the image width and height. This is necessary,
|
|
216
|
+
if the image is going to be replaced with a transform. It will also remove the self
|
|
217
|
+
embedding entry
|
|
209
218
|
"""
|
|
210
219
|
self._image = None
|
|
211
220
|
if clear_bbox:
|
|
@@ -214,20 +223,26 @@ class Image:
|
|
|
214
223
|
|
|
215
224
|
def get_image(self) -> _Img: # type: ignore # pylint: disable=E0602
|
|
216
225
|
"""
|
|
217
|
-
Get the image either in base64 string representation or as np.array
|
|
226
|
+
Get the image either in base64 string representation or as `np.array`.
|
|
218
227
|
|
|
228
|
+
Example:
|
|
229
|
+
```python
|
|
219
230
|
image.get_image().to_np_array()
|
|
231
|
+
```
|
|
220
232
|
|
|
221
|
-
|
|
233
|
+
or
|
|
222
234
|
|
|
235
|
+
```python
|
|
223
236
|
image.get_image().to_b64()
|
|
237
|
+
```
|
|
224
238
|
|
|
225
|
-
:
|
|
239
|
+
Returns:
|
|
240
|
+
Desired image encoding representation
|
|
226
241
|
"""
|
|
227
242
|
|
|
228
243
|
class _Img:
|
|
229
244
|
"""
|
|
230
|
-
Helper class. Do not use it
|
|
245
|
+
Helper class. Do not use it.
|
|
231
246
|
"""
|
|
232
247
|
|
|
233
248
|
def __init__(self, img: Optional[PixelValues]):
|
|
@@ -256,7 +271,7 @@ class Image:
|
|
|
256
271
|
@property
|
|
257
272
|
def width(self) -> float:
|
|
258
273
|
"""
|
|
259
|
-
width
|
|
274
|
+
`width`
|
|
260
275
|
"""
|
|
261
276
|
if self._bbox is None:
|
|
262
277
|
raise ImageError("Width not available. Call set_width_height first")
|
|
@@ -265,7 +280,7 @@ class Image:
|
|
|
265
280
|
@property
|
|
266
281
|
def height(self) -> float:
|
|
267
282
|
"""
|
|
268
|
-
height
|
|
283
|
+
`height`
|
|
269
284
|
"""
|
|
270
285
|
if self._bbox is None:
|
|
271
286
|
raise ImageError("Height not available. Call set_width_height first")
|
|
@@ -276,8 +291,9 @@ class Image:
|
|
|
276
291
|
Defines bounding box of the image if not already set. Use this, if you do not want to keep the image separated
|
|
277
292
|
for memory reasons.
|
|
278
293
|
|
|
279
|
-
:
|
|
280
|
-
|
|
294
|
+
Args:
|
|
295
|
+
width: width of image
|
|
296
|
+
height: height of image
|
|
281
297
|
"""
|
|
282
298
|
if self._bbox is None:
|
|
283
299
|
self._bbox = BoundingBox(ulx=0.0, uly=0.0, height=height, width=width, absolute_coords=True)
|
|
@@ -288,8 +304,9 @@ class Image:
|
|
|
288
304
|
Set embedding pair. Pass an image_id and a bounding box defining the spacial position of this image with
|
|
289
305
|
respect to the embedding image.
|
|
290
306
|
|
|
291
|
-
:
|
|
292
|
-
|
|
307
|
+
Args:
|
|
308
|
+
image_id: A uuid of the embedding image.
|
|
309
|
+
bounding_box: bounding box of this image in terms of the embedding image.
|
|
293
310
|
"""
|
|
294
311
|
if not isinstance(bounding_box, BoundingBox):
|
|
295
312
|
raise BoundingBoxError(f"Bounding box must be of type BoundingBox, is of type {type(bounding_box)}")
|
|
@@ -299,8 +316,11 @@ class Image:
|
|
|
299
316
|
"""
|
|
300
317
|
Returns the bounding box according to the `image_id`.
|
|
301
318
|
|
|
302
|
-
:
|
|
303
|
-
|
|
319
|
+
Args:
|
|
320
|
+
image_id: uuid string of the embedding image
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
The bounding box of this instance in terms of the embedding image
|
|
304
324
|
"""
|
|
305
325
|
|
|
306
326
|
return self.embeddings[image_id]
|
|
@@ -309,7 +329,8 @@ class Image:
|
|
|
309
329
|
"""
|
|
310
330
|
Remove an embedding from the image.
|
|
311
331
|
|
|
312
|
-
:
|
|
332
|
+
Args:
|
|
333
|
+
image_id: `uuid` string of the embedding image
|
|
313
334
|
"""
|
|
314
335
|
if image_id in self.embeddings:
|
|
315
336
|
self.embeddings.pop(image_id)
|
|
@@ -324,7 +345,8 @@ class Image:
|
|
|
324
345
|
an image. It gives the annotation an `annotation_id` in relation to the `image_id` in order to ensure uniqueness
|
|
325
346
|
across all images.
|
|
326
347
|
|
|
327
|
-
:
|
|
348
|
+
Args:
|
|
349
|
+
annotation: image annotation to store
|
|
328
350
|
"""
|
|
329
351
|
if not isinstance(annotation, ImageAnnotation):
|
|
330
352
|
raise AnnotationError(
|
|
@@ -349,19 +371,21 @@ class Image:
|
|
|
349
371
|
) -> list[ImageAnnotation]:
|
|
350
372
|
"""
|
|
351
373
|
Selection of annotations from the annotation container. Filter conditions can be defined by specifying
|
|
352
|
-
the annotation_id or
|
|
353
|
-
|
|
354
|
-
|
|
374
|
+
the `annotation_id` or `category_name`.
|
|
375
|
+
Only annotations that have active = 'True' are returned. If more than one condition is provided, only
|
|
376
|
+
annotations will be returned that satisfy all conditions.
|
|
355
377
|
If no condition is provided, it will return all active annotations.
|
|
356
378
|
|
|
357
|
-
:
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
379
|
+
Args:
|
|
380
|
+
category_names: A single name or list of names
|
|
381
|
+
annotation_ids: A single id or list of ids
|
|
382
|
+
service_ids: A single service name or list of service names
|
|
383
|
+
model_id: A single model name or list of model names
|
|
384
|
+
session_ids: A single session id or list of session ids
|
|
385
|
+
ignore_inactive: If set to `True` only active annotations are returned.
|
|
363
386
|
|
|
364
|
-
:
|
|
387
|
+
Returns:
|
|
388
|
+
A (possibly empty) list of `ImageAnnotation`s
|
|
365
389
|
"""
|
|
366
390
|
|
|
367
391
|
if category_names is not None:
|
|
@@ -403,7 +427,8 @@ class Image:
|
|
|
403
427
|
Returns the full image dataclass as dict. Uses the custom `convert.as_dict` to disregard attributes
|
|
404
428
|
defined by `remove_keys`.
|
|
405
429
|
|
|
406
|
-
:
|
|
430
|
+
Returns:
|
|
431
|
+
A custom `dict`.
|
|
407
432
|
"""
|
|
408
433
|
|
|
409
434
|
img_dict = as_dict(self, dict_factory=dict)
|
|
@@ -417,7 +442,8 @@ class Image:
|
|
|
417
442
|
"""
|
|
418
443
|
Returns the full image dataclass as json string.
|
|
419
444
|
|
|
420
|
-
:
|
|
445
|
+
Returns:
|
|
446
|
+
A `JSON` object.
|
|
421
447
|
"""
|
|
422
448
|
|
|
423
449
|
return json.dumps(self.as_dict(), indent=4)
|
|
@@ -425,7 +451,7 @@ class Image:
|
|
|
425
451
|
@staticmethod
|
|
426
452
|
def remove_keys() -> list[str]:
|
|
427
453
|
"""
|
|
428
|
-
A list of attributes to suspend from as_dict creation.
|
|
454
|
+
A list of attributes to suspend from `as_dict` creation.
|
|
429
455
|
"""
|
|
430
456
|
|
|
431
457
|
return ["_annotation_ids", "_category_name"]
|
|
@@ -435,12 +461,20 @@ class Image:
|
|
|
435
461
|
Generate a uuid for a given annotation. To guarantee uniqueness the generation depends on the datapoint
|
|
436
462
|
`image_id` as well as on the annotation.
|
|
437
463
|
|
|
438
|
-
:
|
|
439
|
-
|
|
464
|
+
Args:
|
|
465
|
+
annotation: An annotation to generate the `uuid` for
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
uuid string
|
|
440
469
|
"""
|
|
441
470
|
|
|
442
471
|
attributes = annotation.get_defining_attributes()
|
|
443
|
-
attributes_values = [
|
|
472
|
+
attributes_values = [
|
|
473
|
+
str(getattr(annotation, attribute))
|
|
474
|
+
if attribute != "bounding_box"
|
|
475
|
+
else getattr(annotation, "bounding_box").get_legacy_string()
|
|
476
|
+
for attribute in attributes
|
|
477
|
+
]
|
|
444
478
|
return get_uuid(*attributes_values, str(self.image_id))
|
|
445
479
|
|
|
446
480
|
def remove(
|
|
@@ -451,10 +485,14 @@ class Image:
|
|
|
451
485
|
"""
|
|
452
486
|
Instead of removing consider deactivating annotations.
|
|
453
487
|
|
|
454
|
-
Calls `List.remove`.
|
|
488
|
+
Calls `List.remove`.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
annotation_ids: The annotation to remove
|
|
492
|
+
service_ids: The service id to remove
|
|
455
493
|
|
|
456
|
-
:
|
|
457
|
-
|
|
494
|
+
Raises:
|
|
495
|
+
ValueError: If the annotation or service id is not found in the image.
|
|
458
496
|
"""
|
|
459
497
|
ann_id_to_annotation_maps = self.get_annotation_id_to_annotation_maps()
|
|
460
498
|
|
|
@@ -529,8 +567,9 @@ class Image:
|
|
|
529
567
|
by the bounding box. The image is cut out and the determinable fields such as height, width and the embeddings
|
|
530
568
|
are determined. The partial image is not saved if `crop_image = 'False'` is set.
|
|
531
569
|
|
|
532
|
-
:
|
|
533
|
-
|
|
570
|
+
Args:
|
|
571
|
+
annotation_id: An annotation id of the image annotations.
|
|
572
|
+
crop_image: Whether to store the cropped image as `np.array`.
|
|
534
573
|
"""
|
|
535
574
|
|
|
536
575
|
ann = self.get_annotation(annotation_ids=annotation_id)[0]
|
|
@@ -564,9 +603,10 @@ class Image:
|
|
|
564
603
|
image of the image annotation. All annotations of this image are also dumped onto the image of the image
|
|
565
604
|
annotation, provided that their bounding boxes are completely in the box of the annotation under consideration.
|
|
566
605
|
|
|
567
|
-
:
|
|
568
|
-
|
|
569
|
-
|
|
606
|
+
Args:
|
|
607
|
+
annotation_id: image annotation you want to assign image annotation from this image. Note, that the
|
|
608
|
+
annotation must have a not None `image`.
|
|
609
|
+
category_names: Filter the proposals of all image categories of this image by some given category names.
|
|
570
610
|
"""
|
|
571
611
|
|
|
572
612
|
ann = self.get_annotation(annotation_ids=annotation_id)[0]
|
|
@@ -617,8 +657,11 @@ class Image:
|
|
|
617
657
|
"""
|
|
618
658
|
Create `Image` instance from dict.
|
|
619
659
|
|
|
620
|
-
:
|
|
621
|
-
|
|
660
|
+
Args:
|
|
661
|
+
kwargs: dict with `Image` attributes and nested dicts for initializing annotations,
|
|
662
|
+
|
|
663
|
+
Returns:
|
|
664
|
+
Initialized image
|
|
622
665
|
"""
|
|
623
666
|
image = cls(kwargs.get("file_name"), kwargs.get("location"), kwargs.get("external_id"))
|
|
624
667
|
image._image_id = kwargs.get("_image_id")
|
|
@@ -648,10 +691,13 @@ class Image:
|
|
|
648
691
|
@no_type_check
|
|
649
692
|
def from_file(cls, file_path: str) -> Image:
|
|
650
693
|
"""
|
|
651
|
-
Create `Image` instance from
|
|
694
|
+
Create `Image` instance from `.json` file.
|
|
695
|
+
|
|
696
|
+
Args:
|
|
697
|
+
file_path: file_path
|
|
652
698
|
|
|
653
|
-
:
|
|
654
|
-
|
|
699
|
+
Returns:
|
|
700
|
+
Initialized image
|
|
655
701
|
"""
|
|
656
702
|
with open(file_path, "r", encoding="UTF-8") as file:
|
|
657
703
|
image = Image.from_dict(**json.load(file))
|
|
@@ -662,7 +708,8 @@ class Image:
|
|
|
662
708
|
"""
|
|
663
709
|
Returns the list of attributes that define the `state_id` of an image.
|
|
664
710
|
|
|
665
|
-
:
|
|
711
|
+
Returns:
|
|
712
|
+
list of attributes
|
|
666
713
|
"""
|
|
667
714
|
return ["annotations", "embeddings", "_image", "_summary"]
|
|
668
715
|
|
|
@@ -672,7 +719,8 @@ class Image:
|
|
|
672
719
|
Different to `image_id` this id does depend on every state attributes and might therefore change
|
|
673
720
|
over time.
|
|
674
721
|
|
|
675
|
-
:
|
|
722
|
+
Returns:
|
|
723
|
+
Annotation state instance
|
|
676
724
|
"""
|
|
677
725
|
container_ids = []
|
|
678
726
|
attributes = self.get_state_attributes()
|
|
@@ -709,13 +757,15 @@ class Image:
|
|
|
709
757
|
dry: bool = False,
|
|
710
758
|
) -> Optional[Union[ImageDict, str]]:
|
|
711
759
|
"""
|
|
712
|
-
Export image as dictionary. As
|
|
713
|
-
base64 encodings.
|
|
714
|
-
|
|
715
|
-
:
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
760
|
+
Export image as dictionary. As `np.array` cannot be serialized `image` values will be converted into
|
|
761
|
+
`base64` encodings.
|
|
762
|
+
|
|
763
|
+
Args:
|
|
764
|
+
image_to_json: If `True` will save the image as b64 encoded string in output
|
|
765
|
+
highest_hierarchy_only: If True it will remove all image attributes of ImageAnnotations
|
|
766
|
+
path: Path to save the .json file to. If `None` results will be saved in the folder of the original
|
|
767
|
+
document.
|
|
768
|
+
dry: Will run dry, i.e. without saving anything but returning the `dict`
|
|
719
769
|
|
|
720
770
|
:return: optional dict
|
|
721
771
|
"""
|
|
@@ -743,6 +793,8 @@ class Image:
|
|
|
743
793
|
path_json = fspath(path) + ".json"
|
|
744
794
|
if highest_hierarchy_only:
|
|
745
795
|
self.remove_image_from_lower_hierarchy()
|
|
796
|
+
else:
|
|
797
|
+
self.remove_image_from_lower_hierarchy(pixel_values_only=True)
|
|
746
798
|
export_dict = self.as_dict()
|
|
747
799
|
export_dict["location"] = fspath(export_dict["location"])
|
|
748
800
|
if not image_to_json:
|
|
@@ -754,14 +806,17 @@ class Image:
|
|
|
754
806
|
return path_json
|
|
755
807
|
|
|
756
808
|
def get_categories_from_current_state(self) -> set[str]:
|
|
757
|
-
"""
|
|
809
|
+
"""
|
|
810
|
+
Returns:
|
|
811
|
+
All active dumped categories
|
|
812
|
+
"""
|
|
758
813
|
return {ann.category_name for ann in self.get_annotation()}
|
|
759
814
|
|
|
760
815
|
def get_service_id_to_annotation_id(self) -> defaultdict[str, list[str]]:
|
|
761
816
|
"""
|
|
762
|
-
Returns
|
|
763
|
-
|
|
764
|
-
|
|
817
|
+
Returns:
|
|
818
|
+
A dictionary with `service_id`s as keys and lists of annotation ids that have been generated by the
|
|
819
|
+
service
|
|
765
820
|
"""
|
|
766
821
|
service_id_dict = defaultdict(list)
|
|
767
822
|
for ann in self.get_annotation():
|
|
@@ -781,10 +836,11 @@ class Image:
|
|
|
781
836
|
|
|
782
837
|
def get_annotation_id_to_annotation_maps(self) -> defaultdict[str, list[AnnotationMap]]:
|
|
783
838
|
"""
|
|
784
|
-
Returns a dictionary with annotation ids as keys and lists of AnnotationMap as values. The range of ids
|
|
785
|
-
is the union of all ImageAnnotation
|
|
839
|
+
Returns a dictionary with annotation ids as keys and lists of `AnnotationMap` as values. The range of ids
|
|
840
|
+
is the union of all `ImageAnnotation`, `CategoryAnnotation` and `ContainerAnnotation` of the image.
|
|
786
841
|
|
|
787
|
-
:
|
|
842
|
+
Returns:
|
|
843
|
+
`defaultdict` with `annotation_id`s as keys and lists of `AnnotationMap` as values
|
|
788
844
|
"""
|
|
789
845
|
all_ann_id_dict = defaultdict(list)
|
|
790
846
|
for ann in self.get_annotation():
|