deepdoctection 0.42.1__py3-none-any.whl → 0.43.1__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.

Files changed (124) hide show
  1. deepdoctection/__init__.py +4 -2
  2. deepdoctection/analyzer/__init__.py +2 -1
  3. deepdoctection/analyzer/config.py +919 -0
  4. deepdoctection/analyzer/dd.py +36 -62
  5. deepdoctection/analyzer/factory.py +311 -141
  6. deepdoctection/configs/conf_dd_one.yaml +100 -44
  7. deepdoctection/configs/profiles.jsonl +32 -0
  8. deepdoctection/dataflow/__init__.py +9 -6
  9. deepdoctection/dataflow/base.py +33 -15
  10. deepdoctection/dataflow/common.py +96 -75
  11. deepdoctection/dataflow/custom.py +36 -29
  12. deepdoctection/dataflow/custom_serialize.py +135 -91
  13. deepdoctection/dataflow/parallel_map.py +33 -31
  14. deepdoctection/dataflow/serialize.py +15 -10
  15. deepdoctection/dataflow/stats.py +41 -28
  16. deepdoctection/datapoint/__init__.py +4 -6
  17. deepdoctection/datapoint/annotation.py +104 -66
  18. deepdoctection/datapoint/box.py +190 -130
  19. deepdoctection/datapoint/convert.py +66 -39
  20. deepdoctection/datapoint/image.py +151 -95
  21. deepdoctection/datapoint/view.py +383 -236
  22. deepdoctection/datasets/__init__.py +2 -6
  23. deepdoctection/datasets/adapter.py +11 -11
  24. deepdoctection/datasets/base.py +118 -81
  25. deepdoctection/datasets/dataflow_builder.py +18 -12
  26. deepdoctection/datasets/info.py +76 -57
  27. deepdoctection/datasets/instances/__init__.py +6 -2
  28. deepdoctection/datasets/instances/doclaynet.py +17 -14
  29. deepdoctection/datasets/instances/fintabnet.py +16 -22
  30. deepdoctection/datasets/instances/funsd.py +11 -6
  31. deepdoctection/datasets/instances/iiitar13k.py +9 -9
  32. deepdoctection/datasets/instances/layouttest.py +9 -9
  33. deepdoctection/datasets/instances/publaynet.py +9 -9
  34. deepdoctection/datasets/instances/pubtables1m.py +13 -13
  35. deepdoctection/datasets/instances/pubtabnet.py +13 -15
  36. deepdoctection/datasets/instances/rvlcdip.py +8 -8
  37. deepdoctection/datasets/instances/xfund.py +11 -9
  38. deepdoctection/datasets/registry.py +18 -11
  39. deepdoctection/datasets/save.py +12 -11
  40. deepdoctection/eval/__init__.py +3 -2
  41. deepdoctection/eval/accmetric.py +72 -52
  42. deepdoctection/eval/base.py +29 -10
  43. deepdoctection/eval/cocometric.py +14 -12
  44. deepdoctection/eval/eval.py +56 -41
  45. deepdoctection/eval/registry.py +6 -3
  46. deepdoctection/eval/tedsmetric.py +24 -9
  47. deepdoctection/eval/tp_eval_callback.py +13 -12
  48. deepdoctection/extern/__init__.py +1 -1
  49. deepdoctection/extern/base.py +176 -97
  50. deepdoctection/extern/d2detect.py +127 -92
  51. deepdoctection/extern/deskew.py +19 -10
  52. deepdoctection/extern/doctrocr.py +162 -108
  53. deepdoctection/extern/fastlang.py +25 -17
  54. deepdoctection/extern/hfdetr.py +137 -60
  55. deepdoctection/extern/hflayoutlm.py +329 -248
  56. deepdoctection/extern/hflm.py +67 -33
  57. deepdoctection/extern/model.py +108 -762
  58. deepdoctection/extern/pdftext.py +37 -12
  59. deepdoctection/extern/pt/nms.py +15 -1
  60. deepdoctection/extern/pt/ptutils.py +13 -9
  61. deepdoctection/extern/tessocr.py +87 -54
  62. deepdoctection/extern/texocr.py +29 -14
  63. deepdoctection/extern/tp/tfutils.py +36 -8
  64. deepdoctection/extern/tp/tpcompat.py +54 -16
  65. deepdoctection/extern/tp/tpfrcnn/config/config.py +20 -4
  66. deepdoctection/extern/tpdetect.py +4 -2
  67. deepdoctection/mapper/__init__.py +1 -1
  68. deepdoctection/mapper/cats.py +117 -76
  69. deepdoctection/mapper/cocostruct.py +35 -17
  70. deepdoctection/mapper/d2struct.py +56 -29
  71. deepdoctection/mapper/hfstruct.py +32 -19
  72. deepdoctection/mapper/laylmstruct.py +221 -185
  73. deepdoctection/mapper/maputils.py +71 -35
  74. deepdoctection/mapper/match.py +76 -62
  75. deepdoctection/mapper/misc.py +68 -44
  76. deepdoctection/mapper/pascalstruct.py +13 -12
  77. deepdoctection/mapper/prodigystruct.py +33 -19
  78. deepdoctection/mapper/pubstruct.py +42 -32
  79. deepdoctection/mapper/tpstruct.py +39 -19
  80. deepdoctection/mapper/xfundstruct.py +20 -13
  81. deepdoctection/pipe/__init__.py +1 -2
  82. deepdoctection/pipe/anngen.py +104 -62
  83. deepdoctection/pipe/base.py +226 -107
  84. deepdoctection/pipe/common.py +206 -123
  85. deepdoctection/pipe/concurrency.py +74 -47
  86. deepdoctection/pipe/doctectionpipe.py +108 -47
  87. deepdoctection/pipe/language.py +41 -24
  88. deepdoctection/pipe/layout.py +45 -18
  89. deepdoctection/pipe/lm.py +146 -78
  90. deepdoctection/pipe/order.py +205 -119
  91. deepdoctection/pipe/refine.py +111 -63
  92. deepdoctection/pipe/registry.py +1 -1
  93. deepdoctection/pipe/segment.py +213 -142
  94. deepdoctection/pipe/sub_layout.py +76 -46
  95. deepdoctection/pipe/text.py +52 -33
  96. deepdoctection/pipe/transform.py +8 -6
  97. deepdoctection/train/d2_frcnn_train.py +87 -69
  98. deepdoctection/train/hf_detr_train.py +72 -40
  99. deepdoctection/train/hf_layoutlm_train.py +85 -46
  100. deepdoctection/train/tp_frcnn_train.py +56 -28
  101. deepdoctection/utils/concurrency.py +59 -16
  102. deepdoctection/utils/context.py +40 -19
  103. deepdoctection/utils/develop.py +26 -17
  104. deepdoctection/utils/env_info.py +86 -37
  105. deepdoctection/utils/error.py +16 -10
  106. deepdoctection/utils/file_utils.py +246 -71
  107. deepdoctection/utils/fs.py +162 -43
  108. deepdoctection/utils/identifier.py +29 -16
  109. deepdoctection/utils/logger.py +49 -32
  110. deepdoctection/utils/metacfg.py +83 -21
  111. deepdoctection/utils/pdf_utils.py +119 -62
  112. deepdoctection/utils/settings.py +24 -10
  113. deepdoctection/utils/tqdm.py +10 -5
  114. deepdoctection/utils/transform.py +182 -46
  115. deepdoctection/utils/utils.py +61 -28
  116. deepdoctection/utils/viz.py +150 -104
  117. deepdoctection-0.43.1.dist-info/METADATA +376 -0
  118. deepdoctection-0.43.1.dist-info/RECORD +149 -0
  119. deepdoctection/analyzer/_config.py +0 -146
  120. deepdoctection-0.42.1.dist-info/METADATA +0 -431
  121. deepdoctection-0.42.1.dist-info/RECORD +0 -148
  122. {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.1.dist-info}/WHEEL +0 -0
  123. {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.1.dist-info}/licenses/LICENSE +0 -0
  124. {deepdoctection-0.42.1.dist-info → deepdoctection-0.43.1.dist-info}/top_level.txt +0 -0
@@ -16,8 +16,9 @@
16
16
  # limitations under the License.
17
17
 
18
18
  """
19
- Conversion functions associated to functionalities of datapoint classes
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
- custom func: as_dict to use instead of `dataclasses.asdict` . It also checks if a dataclass has a
51
- 'remove_keys' and will remove all attributes that are returned. Ensures that private attributes are not taken
52
- into account when generating a dict.
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
- :param obj: Object to convert into a dict.
55
- :param dict_factory: A factory to generate the dict.
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 numpy array of shape (width,height,channel).
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
- :param image: An image as base64 string.
85
- :return: numpy array.
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
- :param np_image: An image as numpy array.
96
- :return: An image as base64 string.
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
- :param np_image: An image as numpy array.
107
- :return: An image as base64 bytes.
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 numpy array
125
+ Converts an image in `bytes` to a `np.array`
115
126
 
116
- :param image_bytes: An image as bytes.
117
- :return: numpy array.
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 numpy array. Note, that this method expects poppler to be installed.
126
- Please check the installation guides at https://poppler.freedesktop.org/ . If no value for dpi is provided
127
- the output size will be determined by the mediaBox of the pdf file ready. Note, that the image size will be in
128
- this case rather small.
129
-
130
- :param pdf_bytes: A pdf as bytes object. A byte representation can from a pdf file can be generated e.g. with
131
- `utils.fs.load_bytes_from_pdf_file`
132
- :param dpi: The dpi value of the resulting output image. For high resolution set dpi=300.
133
- :return: Image as numpy array.
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
- If both is available you can steer the selection of the render engine with environment variables:
164
-
165
- USE_DD_POPPLER: Set to 1, "TRUE", "True" to use poppler
166
- USE_DD_PDFIUM: Set to 1, "TRUE", "True" to use pdfium
167
-
168
- :param pdf_bytes: A pdf as bytes object. A byte representation can from a pdf file can be generated e.g. with
169
- `utils.fs.load_bytes_from_pdf_file`
170
- :param dpi: The dpi value of the resulting output image. For high resolution set dpi=300.
171
- :param width: The width of the resulting output image. This option does only work when using Poppler as
172
- PDF renderer
173
- :param height: The height of the resulting output image. This option does only work when using Poppler as
174
- PDF renderer
175
- :return: Image as numpy array.
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
- In the case of full pipelines, the image data model is also the highest hierarchy class in which document pages
55
- including their discovered features can be processed.
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. Allocation as base64 encoding string or as pdf bytes are
74
- possible and are converted via a `image.setter`. Other formats are rejected. As a result of the transfer,
75
- the width and height of the image are determined. These are accessible via `width` or `height`.
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 of another image. The bounding box is accessed in relation to the embedding image via the annotation_id.
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
- Note: If the input is an np.array, ensure that the image is in BGR-format as this is the standard
144
- format for the whole package.
145
- :param image: Accepts numpy arrays, base64 encodings or bytes generated from pdf documents.
146
- Everything else will be rejected.
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. This attribute will be set dynamically and is not part of the core Image data model
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
- :param clear_bbox: If set to `True` it will remove the image width and height. This is necessary,
207
- if the image is going to be replaced with a transform. It will also remove the self
208
- embedding entry
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
- or
233
+ or
222
234
 
235
+ ```python
223
236
  image.get_image().to_b64()
237
+ ```
224
238
 
225
- :return: desired image encoding representation
239
+ Returns:
240
+ Desired image encoding representation
226
241
  """
227
242
 
228
243
  class _Img:
229
244
  """
230
- Helper class. Do not use it in your code.
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
- :param width: width of image
280
- :param height: height of image
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
- :param image_id: A uuid of the embedding image.
292
- :param bounding_box: bounding box of this image in terms of the embedding image.
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
- :param image_id: uuid string of the embedding image
303
- :return: The bounding box of this instance in terms of the embedding image
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
- :param image_id: uuid string of the embedding image
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
- :param annotation: image annotation to store
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 the category name. (Since only image annotations are currently allowed in the container,
353
- annotation_type is a redundant filter condition.) Only annotations that have active = 'True' are
354
- returned. If more than one condition is provided, only annotations will be returned that satisfy all conditions.
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
- :param category_names: A single name or list of names
358
- :param annotation_ids: A single id or list of ids
359
- :param service_ids: A single service name or list of service names
360
- :param model_id: A single model name or list of model names
361
- :param session_ids: A single session id or list of session ids
362
- :param ignore_inactive: If set to `True` only active annotations are returned.
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
- :return: A (possibly empty) list of Annotations
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
- :return: A custom dict.
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
- :return: A json string.
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
- :param annotation: An annotation to generate the uuid for
439
- :return: uuid string
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 = [str(getattr(annotation, attribute)) for attribute in attributes]
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`. Make sure, the element is in the list for otherwise a ValueError will be raised.
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
- :param annotation_ids: The annotation to remove
457
- :param service_ids: The service id to remove
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
- :param annotation_id: An annotation id of the image annotations.
533
- :param crop_image: Whether to store the cropped image as np.array.
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
- :param annotation_id: image annotation you want to assign image annotation from this image. Note, that the
568
- annotation must have a not None `image`.
569
- :param category_names: Filter the proposals of all image categories of this image by some given category names.
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
- :param kwargs: dict with `Image` attributes and nested dicts for initializing annotations,
621
- :return: Initialized image
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 .json file.
694
+ Create `Image` instance from `.json` file.
695
+
696
+ Args:
697
+ file_path: file_path
652
698
 
653
- :param file_path: file_path
654
- :return: Initialized image
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
- :return: List of attributes
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
- :return: Annotation state instance
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 numpy array cannot be serialized `image` values will be converted into
713
- base64 encodings.
714
- :param image_to_json: If True will save the image as b64 encoded string in output
715
- :param highest_hierarchy_only: If True it will remove all image attributes of ImageAnnotations
716
- :param path: Path to save the .json file to. If `None` results will be saved in the folder of the original
717
- document.
718
- :param dry: Will run dry, i.e. without saving anything but returning the dict
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
- """Returns all active dumped categories"""
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 a dictionary with service ids as keys and lists of annotation ids that have been generated by the
763
- service
764
- :return: default with service ids as keys and lists of annotation ids as values
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, CategoryAnnotation and ContainerAnnotation of the image.
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
- :return: default dict with annotation ids as keys and lists of AnnotationMap as values
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():