deepdoctection 0.32__py3-none-any.whl → 0.34__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 (111) hide show
  1. deepdoctection/__init__.py +8 -25
  2. deepdoctection/analyzer/dd.py +84 -71
  3. deepdoctection/dataflow/common.py +9 -5
  4. deepdoctection/dataflow/custom.py +5 -5
  5. deepdoctection/dataflow/custom_serialize.py +75 -18
  6. deepdoctection/dataflow/parallel_map.py +3 -3
  7. deepdoctection/dataflow/serialize.py +4 -4
  8. deepdoctection/dataflow/stats.py +3 -3
  9. deepdoctection/datapoint/annotation.py +78 -56
  10. deepdoctection/datapoint/box.py +7 -7
  11. deepdoctection/datapoint/convert.py +6 -6
  12. deepdoctection/datapoint/image.py +157 -75
  13. deepdoctection/datapoint/view.py +175 -151
  14. deepdoctection/datasets/adapter.py +30 -24
  15. deepdoctection/datasets/base.py +10 -10
  16. deepdoctection/datasets/dataflow_builder.py +3 -3
  17. deepdoctection/datasets/info.py +23 -25
  18. deepdoctection/datasets/instances/doclaynet.py +48 -49
  19. deepdoctection/datasets/instances/fintabnet.py +44 -45
  20. deepdoctection/datasets/instances/funsd.py +23 -23
  21. deepdoctection/datasets/instances/iiitar13k.py +8 -8
  22. deepdoctection/datasets/instances/layouttest.py +2 -2
  23. deepdoctection/datasets/instances/publaynet.py +3 -3
  24. deepdoctection/datasets/instances/pubtables1m.py +18 -18
  25. deepdoctection/datasets/instances/pubtabnet.py +30 -29
  26. deepdoctection/datasets/instances/rvlcdip.py +28 -29
  27. deepdoctection/datasets/instances/xfund.py +51 -30
  28. deepdoctection/datasets/save.py +6 -6
  29. deepdoctection/eval/accmetric.py +32 -33
  30. deepdoctection/eval/base.py +8 -9
  31. deepdoctection/eval/cocometric.py +13 -12
  32. deepdoctection/eval/eval.py +32 -26
  33. deepdoctection/eval/tedsmetric.py +16 -12
  34. deepdoctection/eval/tp_eval_callback.py +7 -16
  35. deepdoctection/extern/base.py +339 -134
  36. deepdoctection/extern/d2detect.py +69 -89
  37. deepdoctection/extern/deskew.py +11 -10
  38. deepdoctection/extern/doctrocr.py +81 -64
  39. deepdoctection/extern/fastlang.py +23 -16
  40. deepdoctection/extern/hfdetr.py +53 -38
  41. deepdoctection/extern/hflayoutlm.py +216 -155
  42. deepdoctection/extern/hflm.py +35 -30
  43. deepdoctection/extern/model.py +433 -255
  44. deepdoctection/extern/pdftext.py +15 -15
  45. deepdoctection/extern/pt/ptutils.py +4 -2
  46. deepdoctection/extern/tessocr.py +39 -38
  47. deepdoctection/extern/texocr.py +14 -16
  48. deepdoctection/extern/tp/tfutils.py +16 -2
  49. deepdoctection/extern/tp/tpcompat.py +11 -7
  50. deepdoctection/extern/tp/tpfrcnn/config/config.py +4 -4
  51. deepdoctection/extern/tp/tpfrcnn/modeling/backbone.py +1 -1
  52. deepdoctection/extern/tp/tpfrcnn/modeling/model_box.py +5 -5
  53. deepdoctection/extern/tp/tpfrcnn/modeling/model_fpn.py +6 -6
  54. deepdoctection/extern/tp/tpfrcnn/modeling/model_frcnn.py +4 -4
  55. deepdoctection/extern/tp/tpfrcnn/modeling/model_mrcnn.py +5 -3
  56. deepdoctection/extern/tp/tpfrcnn/preproc.py +5 -5
  57. deepdoctection/extern/tpdetect.py +40 -45
  58. deepdoctection/mapper/cats.py +36 -40
  59. deepdoctection/mapper/cocostruct.py +16 -12
  60. deepdoctection/mapper/d2struct.py +22 -22
  61. deepdoctection/mapper/hfstruct.py +7 -7
  62. deepdoctection/mapper/laylmstruct.py +22 -24
  63. deepdoctection/mapper/maputils.py +9 -10
  64. deepdoctection/mapper/match.py +33 -2
  65. deepdoctection/mapper/misc.py +6 -7
  66. deepdoctection/mapper/pascalstruct.py +4 -4
  67. deepdoctection/mapper/prodigystruct.py +6 -6
  68. deepdoctection/mapper/pubstruct.py +84 -92
  69. deepdoctection/mapper/tpstruct.py +3 -3
  70. deepdoctection/mapper/xfundstruct.py +33 -33
  71. deepdoctection/pipe/anngen.py +39 -14
  72. deepdoctection/pipe/base.py +68 -99
  73. deepdoctection/pipe/common.py +181 -85
  74. deepdoctection/pipe/concurrency.py +14 -10
  75. deepdoctection/pipe/doctectionpipe.py +24 -21
  76. deepdoctection/pipe/language.py +20 -25
  77. deepdoctection/pipe/layout.py +18 -16
  78. deepdoctection/pipe/lm.py +49 -47
  79. deepdoctection/pipe/order.py +63 -65
  80. deepdoctection/pipe/refine.py +102 -109
  81. deepdoctection/pipe/segment.py +157 -162
  82. deepdoctection/pipe/sub_layout.py +50 -40
  83. deepdoctection/pipe/text.py +37 -36
  84. deepdoctection/pipe/transform.py +19 -16
  85. deepdoctection/train/d2_frcnn_train.py +27 -25
  86. deepdoctection/train/hf_detr_train.py +22 -18
  87. deepdoctection/train/hf_layoutlm_train.py +49 -48
  88. deepdoctection/train/tp_frcnn_train.py +10 -11
  89. deepdoctection/utils/concurrency.py +1 -1
  90. deepdoctection/utils/context.py +13 -6
  91. deepdoctection/utils/develop.py +4 -4
  92. deepdoctection/utils/env_info.py +52 -14
  93. deepdoctection/utils/file_utils.py +6 -11
  94. deepdoctection/utils/fs.py +41 -14
  95. deepdoctection/utils/identifier.py +2 -2
  96. deepdoctection/utils/logger.py +15 -15
  97. deepdoctection/utils/metacfg.py +7 -7
  98. deepdoctection/utils/pdf_utils.py +39 -14
  99. deepdoctection/utils/settings.py +188 -182
  100. deepdoctection/utils/tqdm.py +1 -1
  101. deepdoctection/utils/transform.py +14 -9
  102. deepdoctection/utils/types.py +104 -0
  103. deepdoctection/utils/utils.py +7 -7
  104. deepdoctection/utils/viz.py +70 -69
  105. {deepdoctection-0.32.dist-info → deepdoctection-0.34.dist-info}/METADATA +7 -4
  106. deepdoctection-0.34.dist-info/RECORD +146 -0
  107. {deepdoctection-0.32.dist-info → deepdoctection-0.34.dist-info}/WHEEL +1 -1
  108. deepdoctection/utils/detection_types.py +0 -68
  109. deepdoctection-0.32.dist-info/RECORD +0 -146
  110. {deepdoctection-0.32.dist-info → deepdoctection-0.34.dist-info}/LICENSE +0 -0
  111. {deepdoctection-0.32.dist-info → deepdoctection-0.34.dist-info}/top_level.txt +0 -0
@@ -37,8 +37,8 @@ from ...dataflow import CustomDataFromList, DataFlow, MapData
37
37
  from ...datasets.info import DatasetInfo
38
38
  from ...mapper.cats import cat_to_sub_cat, filter_cat
39
39
  from ...mapper.xfundstruct import xfund_to_image
40
- from ...utils.detection_types import JsonDict
41
40
  from ...utils.settings import BioTag, DatasetType, LayoutType, ObjectTypes, TokenClasses, TokenClassWithTag, WordType
41
+ from ...utils.types import FunsdDict
42
42
  from ..base import _BuiltInDataset
43
43
  from ..dataflow_builder import DataFlowBaseBuilder
44
44
  from ..info import DatasetCategories
@@ -56,7 +56,7 @@ _LICENSE = (
56
56
  )
57
57
  _URL = "https://github.com/doc-analysis/XFUND/releases/tag/v1.0"
58
58
  _SPLITS: Mapping[str, str] = {"train": "train", "val": "val"}
59
- _TYPE = DatasetType.token_classification
59
+ _TYPE = DatasetType.TOKEN_CLASSIFICATION
60
60
  _LOCATION = "xfund"
61
61
  _ANNOTATION_FILES: Mapping[str, Union[str, Sequence[str]]] = {
62
62
  "train": [
@@ -70,24 +70,23 @@ _ANNOTATION_FILES: Mapping[str, Union[str, Sequence[str]]] = {
70
70
  ],
71
71
  "val": ["de.val.json", "es.val.json", "fr.val.json", "it.val.json", "ja.val.json", "pt.val.json", "zh.val.json"],
72
72
  }
73
- _INIT_CATEGORIES = [LayoutType.word, LayoutType.text]
74
- _SUB_CATEGORIES: Mapping[ObjectTypes, Mapping[ObjectTypes, Sequence[ObjectTypes]]]
75
- _SUB_CATEGORIES = {
76
- LayoutType.word: {
77
- WordType.token_class: [TokenClasses.other, TokenClasses.question, TokenClasses.answer, TokenClasses.header],
78
- WordType.tag: [BioTag.inside, BioTag.outside, BioTag.begin],
79
- WordType.token_tag: [
80
- TokenClassWithTag.b_answer,
81
- TokenClassWithTag.b_header,
82
- TokenClassWithTag.b_question,
83
- TokenClassWithTag.i_answer,
84
- TokenClassWithTag.i_header,
85
- TokenClassWithTag.i_question,
86
- BioTag.outside,
73
+ _INIT_CATEGORIES: Sequence[ObjectTypes] = [LayoutType.WORD, LayoutType.TEXT]
74
+ _SUB_CATEGORIES: Mapping[ObjectTypes, Mapping[ObjectTypes, Sequence[ObjectTypes]]] = {
75
+ LayoutType.WORD: {
76
+ WordType.TOKEN_CLASS: [TokenClasses.OTHER, TokenClasses.QUESTION, TokenClasses.ANSWER, TokenClasses.HEADER],
77
+ WordType.TAG: [BioTag.INSIDE, BioTag.OUTSIDE, BioTag.BEGIN],
78
+ WordType.TOKEN_TAG: [
79
+ TokenClassWithTag.B_ANSWER,
80
+ TokenClassWithTag.B_HEADER,
81
+ TokenClassWithTag.B_QUESTION,
82
+ TokenClassWithTag.I_ANSWER,
83
+ TokenClassWithTag.I_HEADER,
84
+ TokenClassWithTag.I_QUESTION,
85
+ BioTag.OUTSIDE,
87
86
  ],
88
87
  },
89
- LayoutType.text: {
90
- WordType.token_class: [TokenClasses.other, TokenClasses.question, TokenClasses.answer, TokenClasses.header]
88
+ LayoutType.TEXT: {
89
+ WordType.TOKEN_CLASS: [TokenClasses.OTHER, TokenClasses.QUESTION, TokenClasses.ANSWER, TokenClasses.HEADER]
91
90
  },
92
91
  }
93
92
 
@@ -168,7 +167,7 @@ class XfundBuilder(DataFlowBaseBuilder):
168
167
  df = CustomDataFromList(datapoints, max_datapoints=max_datapoints)
169
168
 
170
169
  # Map
171
- def replace_filename(dp: JsonDict) -> JsonDict:
170
+ def replace_filename(dp: FunsdDict) -> FunsdDict:
172
171
  folder = "_".join(dp["id"].split("_", 2)[:2])
173
172
  dp["img"]["fname"] = os.path.join(self.get_workdir(), folder, dp["img"]["fname"])
174
173
  return dp
@@ -176,18 +175,40 @@ class XfundBuilder(DataFlowBaseBuilder):
176
175
  df = MapData(df, replace_filename)
177
176
  categories_name_as_key = self.categories.get_categories(init=True, name_as_key=True)
178
177
  token_class_names_mapping = {
179
- "other": TokenClasses.other,
180
- "question": TokenClasses.question,
181
- "answer": TokenClasses.answer,
182
- "header": TokenClasses.header,
178
+ "other": TokenClasses.OTHER,
179
+ "question": TokenClasses.QUESTION,
180
+ "answer": TokenClasses.ANSWER,
181
+ "header": TokenClasses.HEADER,
183
182
  }
184
- ner_token_to_id_mapping = self.categories.get_sub_categories(
185
- categories=LayoutType.word,
186
- sub_categories={LayoutType.word: [WordType.token_tag, WordType.tag, WordType.token_class]},
187
- keys=False,
188
- values_as_dict=True,
189
- name_as_key=True,
190
- )
183
+ if LayoutType.WORD in self.categories.get_categories(filtered=True, name_as_key=True):
184
+ ner_token_to_id_mapping = self.categories.get_sub_categories(
185
+ categories=LayoutType.WORD,
186
+ sub_categories={LayoutType.WORD: [WordType.TOKEN_TAG, WordType.TAG, WordType.TOKEN_CLASS]},
187
+ keys=False,
188
+ values_as_dict=True,
189
+ name_as_key=True,
190
+ )
191
+ else:
192
+ ner_token_to_id_mapping = {
193
+ LayoutType.WORD: {
194
+ WordType.TAG: {BioTag.BEGIN: 3, BioTag.INSIDE: 1, BioTag.OUTSIDE: 2},
195
+ WordType.TOKEN_CLASS: {
196
+ TokenClasses.ANSWER: 3,
197
+ TokenClasses.HEADER: 4,
198
+ TokenClasses.OTHER: 1,
199
+ TokenClasses.QUESTION: 2,
200
+ },
201
+ WordType.TOKEN_TAG: {
202
+ TokenClassWithTag.B_ANSWER: 1,
203
+ TokenClassWithTag.B_HEADER: 2,
204
+ TokenClassWithTag.B_QUESTION: 3,
205
+ TokenClassWithTag.I_ANSWER: 4,
206
+ TokenClassWithTag.I_HEADER: 5,
207
+ TokenClassWithTag.I_QUESTION: 6,
208
+ BioTag.OUTSIDE: 7,
209
+ },
210
+ }
211
+ }
191
212
  df = MapData(
192
213
  df,
193
214
  xfund_to_image(
@@ -20,20 +20,21 @@ Module for saving
20
20
  """
21
21
 
22
22
  import json
23
+ import os
23
24
  from pathlib import Path
24
25
  from typing import Optional
25
26
 
26
27
  from ..dataflow import DataFlow, MapData, SerializerJsonlines
27
28
  from ..datapoint.convert import convert_b64_to_np_array
28
29
  from ..datapoint.image import Image
29
- from ..utils.detection_types import JsonDict, Pathlike
30
30
  from ..utils.fs import mkdir_p
31
+ from ..utils.types import ImageDict, PathLikeOrStr
31
32
  from ..utils.viz import viz_handler
32
33
 
33
34
 
34
35
  def dataflow_to_json(
35
36
  df: DataFlow,
36
- path: Pathlike,
37
+ path: PathLikeOrStr,
37
38
  single_files: bool = False,
38
39
  file_name: Optional[str] = None,
39
40
  max_datapoints: Optional[int] = None,
@@ -53,8 +54,7 @@ def dataflow_to_json(
53
54
  :param save_image_in_json: Will save the image to the JSON object
54
55
  :param highest_hierarchy_only: If True it will remove all image attributes of ImageAnnotations
55
56
  """
56
- if isinstance(path, str):
57
- path = Path(path)
57
+ path = Path(path)
58
58
  if single_files:
59
59
  mkdir_p(path)
60
60
  if not save_image_in_json:
@@ -68,8 +68,8 @@ def dataflow_to_json(
68
68
  df = MapData(df, _remove_hh)
69
69
  df = MapData(df, lambda dp: dp.as_dict())
70
70
 
71
- def _path_to_str(dp: JsonDict) -> JsonDict:
72
- dp["location"] = str(dp["location"])
71
+ def _path_to_str(dp: ImageDict) -> ImageDict:
72
+ dp["location"] = os.fspath(dp["location"])
73
73
  return dp
74
74
 
75
75
  df = MapData(df, _path_to_str)
@@ -19,9 +19,8 @@
19
19
  Module for Accuracy metric
20
20
  """
21
21
  from collections import Counter
22
- from typing import Any
23
22
  from typing import Counter as TypeCounter
24
- from typing import Dict, List, Mapping, Optional, Sequence, Tuple, Union
23
+ from typing import Mapping, Optional, Sequence, Union
25
24
 
26
25
  import numpy as np
27
26
  from numpy import float32, int32
@@ -32,10 +31,10 @@ from termcolor import colored
32
31
  from ..dataflow import DataFlow
33
32
  from ..datasets.info import DatasetCategories
34
33
  from ..mapper.cats import image_to_cat_id
35
- from ..utils.detection_types import JsonDict
36
34
  from ..utils.file_utils import Requirement
37
35
  from ..utils.logger import LoggingRecord, logger
38
36
  from ..utils.settings import ObjectTypes, TypeOrStr, get_type
37
+ from ..utils.types import MetricResults
39
38
  from .base import MetricBase
40
39
  from .registry import metric_registry
41
40
 
@@ -54,7 +53,7 @@ __all__ = [
54
53
 
55
54
  def _mask_some_gt_and_pr_labels(
56
55
  np_label_gt: NDArray[int32], np_label_pr: NDArray[int32], masks: Sequence[int]
57
- ) -> Tuple[NDArray[int32], NDArray[int32]]:
56
+ ) -> tuple[NDArray[int32], NDArray[int32]]:
58
57
  if len(np_label_gt) != len(masks):
59
58
  raise ValueError(f"length of label_gt ({len(np_label_gt)}) and masks ({len(masks)}) must be equal")
60
59
  np_masks = np.asarray(masks)
@@ -77,8 +76,8 @@ def accuracy(label_gt: Sequence[int], label_predictions: Sequence[int], masks: O
77
76
  Calculates the accuracy given predictions and labels. Ignores masked indices. Uses
78
77
  `sklearn.metrics.accuracy_score`
79
78
 
80
- :param label_gt: List of ground truth labels
81
- :param label_predictions: List of predictions. Must have the same length as label_gt
79
+ :param label_gt: list of ground truth labels
80
+ :param label_predictions: list of predictions. Must have the same length as label_gt
82
81
  :param masks: An optional list with masks to ignore some samples.
83
82
 
84
83
  :return: Accuracy score with only unmasked values to be considered
@@ -102,9 +101,9 @@ def confusion(
102
101
  """
103
102
  Calculates the accuracy matrix given the predictions and labels. Ignores masked indices.
104
103
 
105
- :param label_gt: List of ground truth labels
106
- :param label_predictions: List of predictions. Must have the same length as label_gt
107
- :param masks: List with masks of same length as label_gt.
104
+ :param label_gt: list of ground truth labels
105
+ :param label_predictions: list of predictions. Must have the same length as label_gt
106
+ :param masks: list with masks of same length as label_gt.
108
107
 
109
108
  :return: numpy array
110
109
  """
@@ -127,9 +126,9 @@ def precision(
127
126
  Calculates the precision for a multi classification problem using a confusion matrix. The output will
128
127
  be the precision by category.
129
128
 
130
- :param label_gt: List of ground truth labels
131
- :param label_predictions: List of predictions. Must have the same length as label_gt
132
- :param masks: List with masks of same length as label_gt.
129
+ :param label_gt: list of ground truth labels
130
+ :param label_predictions: list of predictions. Must have the same length as label_gt
131
+ :param masks: list with masks of same length as label_gt.
133
132
  :param micro: If True, it will calculate the micro average precision
134
133
  :return: numpy array
135
134
  """
@@ -157,9 +156,9 @@ def recall(
157
156
  Calculates the recall for a multi classification problem using a confusion matrix. The output will
158
157
  be the recall by category.
159
158
 
160
- :param label_gt: List of ground truth labels
161
- :param label_predictions: List of predictions. Must have the same length as label_gt
162
- :param masks: List with masks of same length as label_gt.
159
+ :param label_gt: list of ground truth labels
160
+ :param label_predictions: list of predictions. Must have the same length as label_gt
161
+ :param masks: list with masks of same length as label_gt.
163
162
  :param micro: If True, it will calculate the micro average recall
164
163
  :return: numpy array
165
164
  """
@@ -188,9 +187,9 @@ def f1_score(
188
187
  Calculates the recall for a multi classification problem using a confusion matrix. The output will
189
188
  be the recall by category.
190
189
 
191
- :param label_gt: List of ground truth labels
192
- :param label_predictions: List of predictions. Must have the same length as label_gt
193
- :param masks: List with masks of same length as label_gt.
190
+ :param label_gt: list of ground truth labels
191
+ :param label_predictions: list of predictions. Must have the same length as label_gt
192
+ :param masks: list with masks of same length as label_gt.
194
193
  :param micro: If True, it will calculate the micro average f1 score
195
194
  :param per_label: If True, it will return the f1 score per label, otherwise will return the mean of all f1's
196
195
  :return: numpy array
@@ -217,7 +216,7 @@ class ClassificationMetric(MetricBase):
217
216
  @classmethod
218
217
  def dump(
219
218
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
220
- ) -> Tuple[Any, Any]:
219
+ ) -> tuple[dict[str, list[int]], dict[str, list[int]]]:
221
220
  dataflow_gt.reset_state()
222
221
  dataflow_predictions.reset_state()
223
222
 
@@ -225,8 +224,8 @@ class ClassificationMetric(MetricBase):
225
224
  if cls._cats is None and cls._sub_cats is None:
226
225
  cls._cats = categories.get_categories(as_dict=False, filtered=True)
227
226
  mapper_with_setting = cls.mapper(cls._cats, cls._sub_cats, cls._summary_sub_cats)
228
- labels_gt: Dict[str, List[int]] = {}
229
- labels_predictions: Dict[str, List[int]] = {}
227
+ labels_gt: dict[str, list[int]] = {}
228
+ labels_predictions: dict[str, list[int]] = {}
230
229
 
231
230
  # returned images of gt and predictions are likely not in the same order. We therefore first stream all data
232
231
  # into a dict and generate our result vectors thereafter.
@@ -253,7 +252,7 @@ class ClassificationMetric(MetricBase):
253
252
  @classmethod
254
253
  def get_distance(
255
254
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
256
- ) -> List[JsonDict]:
255
+ ) -> list[MetricResults]:
257
256
  labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
258
257
 
259
258
  results = []
@@ -290,7 +289,7 @@ class ClassificationMetric(MetricBase):
290
289
  sub_category_names = {cat1: [sub_cat1, sub_cat2], cat2: sub_cat3}
291
290
 
292
291
 
293
- :param category_names: List of category names
292
+ :param category_names: list of category names
294
293
  :param sub_category_names: Dict of categories and their sub categories that are supposed to be evaluated,
295
294
  e.g. {"FOO": ["bak","baz"]} will evaluate "bak" and "baz"
296
295
  :param summary_sub_category_names: string or list of summary sub categories
@@ -346,7 +345,7 @@ class ClassificationMetric(MetricBase):
346
345
  )
347
346
 
348
347
  @classmethod
349
- def get_requirements(cls) -> List[Requirement]:
348
+ def get_requirements(cls) -> list[Requirement]:
350
349
  return []
351
350
 
352
351
  @property
@@ -395,7 +394,7 @@ class ConfusionMetric(ClassificationMetric):
395
394
  @classmethod
396
395
  def get_distance(
397
396
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
398
- ) -> List[JsonDict]:
397
+ ) -> list[MetricResults]:
399
398
  labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
400
399
 
401
400
  results = []
@@ -407,10 +406,10 @@ class ConfusionMetric(ClassificationMetric):
407
406
  results.append(
408
407
  {
409
408
  "key": key.value if isinstance(key, ObjectTypes) else key,
410
- "category_id_gt": row_number,
409
+ "category_id": row_number,
411
410
  "category_id_pr": col_number,
412
411
  "val": float(val),
413
- "num_samples_gt": number_labels[row_number],
412
+ "num_samples": number_labels[row_number],
414
413
  }
415
414
  )
416
415
  cls._results = results
@@ -420,12 +419,12 @@ class ConfusionMetric(ClassificationMetric):
420
419
  def print_result(cls) -> None:
421
420
  data = {}
422
421
  for entry in cls._results:
423
- if entry["category_id_gt"] not in data:
424
- data[entry["category_id_gt"]] = [entry["category_id_gt"], entry["val"]]
422
+ if entry["category_id"] not in data:
423
+ data[entry["category_id"]] = [entry["category_id"], entry["val"]]
425
424
  else:
426
- data[entry["category_id_gt"]].append(entry["val"])
425
+ data[entry["category_id"]].append(entry["val"])
427
426
 
428
- header = ["predictions -> \n ground truth |\n v"] + list(data.keys())
427
+ header = ["predictions -> \n ground truth |\n v"] + list(list(str(element) for element in data))
429
428
  table = tabulate([data[k] for k, _ in enumerate(data, 1)], headers=header, tablefmt="pipe")
430
429
  logger.info("Confusion matrix: \n %s", colored(table, "cyan"))
431
430
 
@@ -442,7 +441,7 @@ class PrecisionMetric(ClassificationMetric):
442
441
  @classmethod
443
442
  def get_distance(
444
443
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
445
- ) -> List[JsonDict]:
444
+ ) -> list[MetricResults]:
446
445
  labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
447
446
 
448
447
  results = []
@@ -494,7 +493,7 @@ class PrecisionMetricMicro(ClassificationMetric):
494
493
  @classmethod
495
494
  def get_distance(
496
495
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
497
- ) -> List[JsonDict]:
496
+ ) -> list[MetricResults]:
498
497
  labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
499
498
 
500
499
  results = []
@@ -20,13 +20,13 @@ Module for the base class for evaluations and metrics
20
20
  """
21
21
 
22
22
  from abc import ABC, abstractmethod
23
- from typing import Any, Callable, List, Optional, Tuple
23
+ from typing import Any, Callable, Optional
24
24
 
25
25
  from ..dataflow import DataFlow
26
26
  from ..datasets.info import DatasetCategories
27
- from ..utils.detection_types import JsonDict
28
27
  from ..utils.error import DependencyError
29
28
  from ..utils.file_utils import Requirement
29
+ from ..utils.types import MetricResults
30
30
 
31
31
 
32
32
  class MetricBase(ABC):
@@ -46,8 +46,7 @@ class MetricBase(ABC):
46
46
 
47
47
  name: str
48
48
  metric: Callable[[Any, Any], Optional[Any]]
49
- mapper: Callable[[Any, Any], Optional[Any]]
50
- _results: List[JsonDict]
49
+ _results: list[MetricResults]
51
50
 
52
51
  def __new__(cls, *args, **kwargs): # type: ignore # pylint: disable=W0613
53
52
  requirements = cls.get_requirements()
@@ -63,7 +62,7 @@ class MetricBase(ABC):
63
62
 
64
63
  @classmethod
65
64
  @abstractmethod
66
- def get_requirements(cls) -> List[Requirement]:
65
+ def get_requirements(cls) -> list[Requirement]:
67
66
  """
68
67
  Get a list of requirements for running the detector
69
68
  """
@@ -73,7 +72,7 @@ class MetricBase(ABC):
73
72
  @abstractmethod
74
73
  def get_distance(
75
74
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
76
- ) -> List[JsonDict]:
75
+ ) -> list[MetricResults]:
77
76
  """
78
77
  Takes of the ground truth processing strand as well as the prediction strand and generates the metric results.
79
78
 
@@ -87,7 +86,7 @@ class MetricBase(ABC):
87
86
  @abstractmethod
88
87
  def dump(
89
88
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
90
- ) -> Tuple[Any, Any]:
89
+ ) -> tuple[Any, Any]:
91
90
  """
92
91
  Dump the dataflow with ground truth annotations and predictions. Use it as auxiliary method and call it from
93
92
  `get_distance`.
@@ -99,7 +98,7 @@ class MetricBase(ABC):
99
98
  raise NotImplementedError()
100
99
 
101
100
  @classmethod
102
- def result_list_to_dict(cls, results: List[JsonDict]) -> JsonDict:
101
+ def result_list_to_dict(cls, results: list[MetricResults]) -> MetricResults:
103
102
  """
104
103
  Converts the result from `get_distance` to a dict. It concatenates all keys of the inner dict and uses
105
104
  the metric result 'val' as value.
@@ -107,7 +106,7 @@ class MetricBase(ABC):
107
106
  :param results: List of dict as input
108
107
  :return: Dict with metric results.
109
108
  """
110
- output: JsonDict = {}
109
+ output: MetricResults = {}
111
110
  for res in results:
112
111
  new_key = ""
113
112
  new_val = 0.0
@@ -18,9 +18,10 @@
18
18
  """
19
19
  Module for metrics that require the COCOeval class.
20
20
  """
21
+ from __future__ import annotations
21
22
 
22
23
  from copy import copy
23
- from typing import Dict, List, Optional, Tuple, Union
24
+ from typing import Optional, Union
24
25
 
25
26
  import numpy as np
26
27
  from lazy_imports import try_import
@@ -29,8 +30,8 @@ from ..dataflow import DataFlow
29
30
  from ..datasets.info import DatasetCategories
30
31
  from ..mapper.cats import re_assign_cat_ids
31
32
  from ..mapper.cocostruct import image_to_coco
32
- from ..utils.detection_types import JsonDict
33
33
  from ..utils.file_utils import Requirement, cocotools_available, get_cocotools_requirement
34
+ from ..utils.types import JsonDict, MetricResults
34
35
  from .base import MetricBase
35
36
  from .registry import metric_registry
36
37
 
@@ -120,15 +121,15 @@ class CocoMetric(MetricBase):
120
121
 
121
122
  name = "mAP and mAR"
122
123
  metric = COCOeval if cocotools_available() else None
123
- mapper = image_to_coco # type: ignore
124
+ mapper = image_to_coco
124
125
  _f1_score = None
125
126
  _f1_iou = None
126
- _params: Dict[str, Union[List[int], List[List[int]]]] = {}
127
+ _params: dict[str, Union[list[int], list[list[int]]]] = {}
127
128
 
128
129
  @classmethod
129
130
  def dump(
130
131
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
131
- ) -> Tuple["COCO", "COCO"]:
132
+ ) -> tuple[COCO, COCO]:
132
133
  cats = [{"id": int(k), "name": v} for k, v in categories.get_categories(as_dict=True, filtered=True).items()]
133
134
  imgs_gt, imgs_pr = [], []
134
135
  anns_gt, anns_pr = [], []
@@ -137,11 +138,11 @@ class CocoMetric(MetricBase):
137
138
  dataflow_predictions.reset_state()
138
139
 
139
140
  for dp_gt, dp_pred in zip(dataflow_gt, dataflow_predictions):
140
- img_gt, ann_gt = cls.mapper(dp_gt) # type: ignore
141
+ img_gt, ann_gt = cls.mapper(dp_gt)
141
142
  dp_pred = re_assign_cat_ids(categories.get_categories(as_dict=True, filtered=True, name_as_key=True))(
142
143
  dp_pred
143
144
  )
144
- img_pr, ann_pr = cls.mapper(dp_pred) # type: ignore
145
+ img_pr, ann_pr = cls.mapper(dp_pred)
145
146
  imgs_gt.append(img_gt)
146
147
  imgs_pr.append(img_pr)
147
148
  anns_gt.extend(ann_gt)
@@ -162,7 +163,7 @@ class CocoMetric(MetricBase):
162
163
  @classmethod
163
164
  def get_distance(
164
165
  cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
165
- ) -> List[JsonDict]:
166
+ ) -> list[MetricResults]:
166
167
  coco_gt, coco_predictions = cls.dump(dataflow_gt, dataflow_predictions, categories)
167
168
 
168
169
  metric = cls.metric(coco_gt, coco_predictions, iouType="bbox")
@@ -192,7 +193,7 @@ class CocoMetric(MetricBase):
192
193
  return results
193
194
 
194
195
  @classmethod
195
- def get_summary_default_parameters(cls) -> List[JsonDict]:
196
+ def get_summary_default_parameters(cls) -> list[JsonDict]:
196
197
  """
197
198
  Returns default parameters of evaluation results. May differ from other CocoMetric classes.
198
199
 
@@ -215,8 +216,8 @@ class CocoMetric(MetricBase):
215
216
  @classmethod
216
217
  def set_params(
217
218
  cls,
218
- max_detections: Optional[List[int]] = None,
219
- area_range: Optional[List[List[int]]] = None,
219
+ max_detections: Optional[list[int]] = None,
220
+ area_range: Optional[list[list[int]]] = None,
220
221
  f1_score: bool = False,
221
222
  f1_iou: float = 0.9,
222
223
  ) -> None:
@@ -239,5 +240,5 @@ class CocoMetric(MetricBase):
239
240
  cls._f1_iou = f1_iou
240
241
 
241
242
  @classmethod
242
- def get_requirements(cls) -> List[Requirement]:
243
+ def get_requirements(cls) -> list[Requirement]:
243
244
  return [get_cocotools_requirement()]