deepdoctection 0.30__py3-none-any.whl → 0.32__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 (120) hide show
  1. deepdoctection/__init__.py +38 -29
  2. deepdoctection/analyzer/dd.py +36 -29
  3. deepdoctection/configs/conf_dd_one.yaml +34 -31
  4. deepdoctection/dataflow/base.py +0 -19
  5. deepdoctection/dataflow/custom.py +4 -3
  6. deepdoctection/dataflow/custom_serialize.py +14 -5
  7. deepdoctection/dataflow/parallel_map.py +12 -11
  8. deepdoctection/dataflow/serialize.py +5 -4
  9. deepdoctection/datapoint/annotation.py +35 -13
  10. deepdoctection/datapoint/box.py +3 -5
  11. deepdoctection/datapoint/convert.py +3 -1
  12. deepdoctection/datapoint/image.py +79 -36
  13. deepdoctection/datapoint/view.py +152 -49
  14. deepdoctection/datasets/__init__.py +1 -4
  15. deepdoctection/datasets/adapter.py +6 -3
  16. deepdoctection/datasets/base.py +86 -11
  17. deepdoctection/datasets/dataflow_builder.py +1 -1
  18. deepdoctection/datasets/info.py +4 -4
  19. deepdoctection/datasets/instances/doclaynet.py +3 -2
  20. deepdoctection/datasets/instances/fintabnet.py +2 -1
  21. deepdoctection/datasets/instances/funsd.py +2 -1
  22. deepdoctection/datasets/instances/iiitar13k.py +5 -2
  23. deepdoctection/datasets/instances/layouttest.py +4 -8
  24. deepdoctection/datasets/instances/publaynet.py +2 -2
  25. deepdoctection/datasets/instances/pubtables1m.py +6 -3
  26. deepdoctection/datasets/instances/pubtabnet.py +2 -1
  27. deepdoctection/datasets/instances/rvlcdip.py +2 -1
  28. deepdoctection/datasets/instances/xfund.py +2 -1
  29. deepdoctection/eval/__init__.py +1 -4
  30. deepdoctection/eval/accmetric.py +1 -1
  31. deepdoctection/eval/base.py +5 -4
  32. deepdoctection/eval/cocometric.py +2 -1
  33. deepdoctection/eval/eval.py +19 -15
  34. deepdoctection/eval/tedsmetric.py +14 -11
  35. deepdoctection/eval/tp_eval_callback.py +14 -7
  36. deepdoctection/extern/__init__.py +2 -7
  37. deepdoctection/extern/base.py +39 -13
  38. deepdoctection/extern/d2detect.py +182 -90
  39. deepdoctection/extern/deskew.py +36 -9
  40. deepdoctection/extern/doctrocr.py +265 -83
  41. deepdoctection/extern/fastlang.py +49 -9
  42. deepdoctection/extern/hfdetr.py +106 -55
  43. deepdoctection/extern/hflayoutlm.py +441 -122
  44. deepdoctection/extern/hflm.py +225 -0
  45. deepdoctection/extern/model.py +56 -47
  46. deepdoctection/extern/pdftext.py +10 -5
  47. deepdoctection/extern/pt/__init__.py +1 -3
  48. deepdoctection/extern/pt/nms.py +6 -2
  49. deepdoctection/extern/pt/ptutils.py +27 -18
  50. deepdoctection/extern/tessocr.py +134 -22
  51. deepdoctection/extern/texocr.py +6 -2
  52. deepdoctection/extern/tp/tfutils.py +43 -9
  53. deepdoctection/extern/tp/tpcompat.py +14 -11
  54. deepdoctection/extern/tp/tpfrcnn/__init__.py +20 -0
  55. deepdoctection/extern/tp/tpfrcnn/common.py +7 -3
  56. deepdoctection/extern/tp/tpfrcnn/config/__init__.py +20 -0
  57. deepdoctection/extern/tp/tpfrcnn/config/config.py +9 -6
  58. deepdoctection/extern/tp/tpfrcnn/modeling/__init__.py +20 -0
  59. deepdoctection/extern/tp/tpfrcnn/modeling/backbone.py +17 -7
  60. deepdoctection/extern/tp/tpfrcnn/modeling/generalized_rcnn.py +12 -6
  61. deepdoctection/extern/tp/tpfrcnn/modeling/model_box.py +9 -4
  62. deepdoctection/extern/tp/tpfrcnn/modeling/model_cascade.py +8 -5
  63. deepdoctection/extern/tp/tpfrcnn/modeling/model_fpn.py +16 -11
  64. deepdoctection/extern/tp/tpfrcnn/modeling/model_frcnn.py +17 -10
  65. deepdoctection/extern/tp/tpfrcnn/modeling/model_mrcnn.py +14 -8
  66. deepdoctection/extern/tp/tpfrcnn/modeling/model_rpn.py +15 -10
  67. deepdoctection/extern/tp/tpfrcnn/predict.py +9 -4
  68. deepdoctection/extern/tp/tpfrcnn/preproc.py +8 -9
  69. deepdoctection/extern/tp/tpfrcnn/utils/__init__.py +20 -0
  70. deepdoctection/extern/tp/tpfrcnn/utils/box_ops.py +10 -2
  71. deepdoctection/extern/tpdetect.py +54 -30
  72. deepdoctection/mapper/__init__.py +3 -8
  73. deepdoctection/mapper/d2struct.py +9 -7
  74. deepdoctection/mapper/hfstruct.py +7 -2
  75. deepdoctection/mapper/laylmstruct.py +164 -21
  76. deepdoctection/mapper/maputils.py +16 -3
  77. deepdoctection/mapper/misc.py +6 -3
  78. deepdoctection/mapper/prodigystruct.py +1 -1
  79. deepdoctection/mapper/pubstruct.py +10 -10
  80. deepdoctection/mapper/tpstruct.py +3 -3
  81. deepdoctection/pipe/__init__.py +1 -1
  82. deepdoctection/pipe/anngen.py +35 -8
  83. deepdoctection/pipe/base.py +53 -19
  84. deepdoctection/pipe/common.py +23 -13
  85. deepdoctection/pipe/concurrency.py +2 -1
  86. deepdoctection/pipe/doctectionpipe.py +2 -2
  87. deepdoctection/pipe/language.py +3 -2
  88. deepdoctection/pipe/layout.py +6 -3
  89. deepdoctection/pipe/lm.py +34 -66
  90. deepdoctection/pipe/order.py +142 -35
  91. deepdoctection/pipe/refine.py +26 -24
  92. deepdoctection/pipe/segment.py +21 -16
  93. deepdoctection/pipe/{cell.py → sub_layout.py} +30 -9
  94. deepdoctection/pipe/text.py +14 -8
  95. deepdoctection/pipe/transform.py +16 -9
  96. deepdoctection/train/__init__.py +6 -12
  97. deepdoctection/train/d2_frcnn_train.py +36 -28
  98. deepdoctection/train/hf_detr_train.py +26 -17
  99. deepdoctection/train/hf_layoutlm_train.py +133 -111
  100. deepdoctection/train/tp_frcnn_train.py +21 -19
  101. deepdoctection/utils/__init__.py +3 -0
  102. deepdoctection/utils/concurrency.py +1 -1
  103. deepdoctection/utils/context.py +2 -2
  104. deepdoctection/utils/env_info.py +41 -84
  105. deepdoctection/utils/error.py +84 -0
  106. deepdoctection/utils/file_utils.py +4 -15
  107. deepdoctection/utils/fs.py +7 -7
  108. deepdoctection/utils/logger.py +1 -0
  109. deepdoctection/utils/mocks.py +93 -0
  110. deepdoctection/utils/pdf_utils.py +5 -4
  111. deepdoctection/utils/settings.py +6 -1
  112. deepdoctection/utils/transform.py +1 -1
  113. deepdoctection/utils/utils.py +0 -6
  114. deepdoctection/utils/viz.py +48 -5
  115. {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/METADATA +57 -73
  116. deepdoctection-0.32.dist-info/RECORD +146 -0
  117. {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/WHEEL +1 -1
  118. deepdoctection-0.30.dist-info/RECORD +0 -143
  119. {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/LICENSE +0 -0
  120. {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/top_level.txt +0 -0
@@ -35,10 +35,13 @@ Module for IIITar13K dataset. Install the dataset following the folder structure
35
35
  │ ├── ...
36
36
 
37
37
  """
38
+ from __future__ import annotations
38
39
 
39
40
  import os
40
41
  from typing import Mapping, Union
41
42
 
43
+ from lazy_imports import try_import
44
+
42
45
  from ...dataflow import DataFlow, MapData, SerializerFiles
43
46
  from ...datasets.info import DatasetInfo
44
47
  from ...mapper.maputils import curry
@@ -53,7 +56,7 @@ from ..dataflow_builder import DataFlowBaseBuilder
53
56
  from ..info import DatasetCategories
54
57
  from ..registry import dataset_registry
55
58
 
56
- if lxml_available():
59
+ with try_import() as import_guard:
57
60
  from lxml import etree
58
61
 
59
62
  _NAME = "iiitar13k"
@@ -99,7 +102,7 @@ class IIITar13K(_BuiltInDataset):
99
102
  def _categories(self) -> DatasetCategories:
100
103
  return DatasetCategories(init_categories=_INIT_CATEGORIES)
101
104
 
102
- def _builder(self) -> "IIITar13KBuilder":
105
+ def _builder(self) -> IIITar13KBuilder:
103
106
  return IIITar13KBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
104
107
 
105
108
 
@@ -24,6 +24,7 @@ Module for Testlayout dataset. Install the dataset following the folder structur
24
24
  ├── test
25
25
  │ ├── xrf_layout_test.jsonl
26
26
  """
27
+ from __future__ import annotations
27
28
 
28
29
  from typing import Mapping, Union
29
30
 
@@ -49,12 +50,7 @@ _LICENSE = (
49
50
  " – Permissive – Version 1.0 License. Dr. Janis Meyer does not own the copyright of the images. \n"
50
51
  " Use of the images must abide by the PMC Open Access Subset Terms of Use."
51
52
  )
52
- _URL = [
53
- "https://www.googleapis.com/drive/v3/files/1ZD4Ef4gd2FIfp7vR8jbnrZeXD3gSWNqE?alt"
54
- "=media&key=AIzaSyDuoPG6naK-kRJikScR7cP_1sQBF1r3fWU",
55
- "https://www.googleapis.com/drive/v3/files/18HD62LFLa1iAmqffo4SyjuEQ32MzyNQ0?alt"
56
- "=media&key=AIzaSyDuoPG6naK-kRJikScR7cP_1sQBF1r3fWU",
57
- ]
53
+
58
54
  _SPLITS: Mapping[str, str] = {"test": "test", "predict": "predict"}
59
55
  _TYPE = DatasetType.object_detection
60
56
  _LOCATION = "testlayout"
@@ -77,12 +73,12 @@ class LayoutTest(_BuiltInDataset):
77
73
 
78
74
  @classmethod
79
75
  def _info(cls) -> DatasetInfo:
80
- return DatasetInfo(name=_NAME, description=_DESCRIPTION, license=_LICENSE, url=_URL, splits=_SPLITS, type=_TYPE)
76
+ return DatasetInfo(name=_NAME, description=_DESCRIPTION, license=_LICENSE, splits=_SPLITS, type=_TYPE)
81
77
 
82
78
  def _categories(self) -> DatasetCategories:
83
79
  return DatasetCategories(init_categories=_INIT_CATEGORIES)
84
80
 
85
- def _builder(self) -> "LayoutTestBuilder":
81
+ def _builder(self) -> LayoutTestBuilder:
86
82
  return LayoutTestBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
87
83
 
88
84
 
@@ -28,7 +28,7 @@ Module for Publaynet dataset. Place the dataset as follows
28
28
  ├── train.json
29
29
  ├── val.json
30
30
  """
31
-
31
+ from __future__ import annotations
32
32
 
33
33
  from typing import Mapping, Union
34
34
 
@@ -84,7 +84,7 @@ class Publaynet(_BuiltInDataset):
84
84
  def _categories(self) -> DatasetCategories:
85
85
  return DatasetCategories(init_categories=_INIT_CATEGORIES)
86
86
 
87
- def _builder(self) -> "PublaynetBuilder":
87
+ def _builder(self) -> PublaynetBuilder:
88
88
  return PublaynetBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
89
89
 
90
90
 
@@ -37,10 +37,13 @@ Module for PubTables1M-Detection-PASCAL-VOC dataset. Install the dataset followi
37
37
  ├── PubTables-1M-Structure_Annotations_Test
38
38
  ├── PubTables-1M-Structure_Images_Test
39
39
  """
40
+ from __future__ import annotations
40
41
 
41
42
  import os
42
43
  from typing import Mapping, Union
43
44
 
45
+ from lazy_imports import try_import
46
+
44
47
  from ...dataflow import DataFlow, MapData, SerializerFiles
45
48
  from ...datasets.info import DatasetInfo
46
49
  from ...mapper.cats import filter_cat
@@ -56,7 +59,7 @@ from ..dataflow_builder import DataFlowBaseBuilder
56
59
  from ..info import DatasetCategories
57
60
  from ..registry import dataset_registry
58
61
 
59
- if lxml_available():
62
+ with try_import() as import_guard:
60
63
  from lxml import etree
61
64
 
62
65
  _NAME = "pubtables1m_det"
@@ -102,7 +105,7 @@ class Pubtables1MDet(_BuiltInDataset):
102
105
  def _categories(self) -> DatasetCategories:
103
106
  return DatasetCategories(init_categories=_INIT_CATEGORIES_DET)
104
107
 
105
- def _builder(self) -> "Pubtables1MBuilder":
108
+ def _builder(self) -> Pubtables1MBuilder:
106
109
  return Pubtables1MBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
107
110
 
108
111
 
@@ -225,7 +228,7 @@ class Pubtables1MStruct(_BuiltInDataset):
225
228
  def _categories(self) -> DatasetCategories:
226
229
  return DatasetCategories(init_categories=_INIT_CATEGORIES_STRUCT)
227
230
 
228
- def _builder(self) -> "Pubtables1MBuilderStruct":
231
+ def _builder(self) -> Pubtables1MBuilderStruct:
229
232
  return Pubtables1MBuilderStruct(location=_LOCATION, annotation_files=_ANNOTATION_FILES_STRUCT)
230
233
 
231
234
 
@@ -27,6 +27,7 @@ Module for Pubtabnet dataset. Place the dataset as follows
27
27
  │ ├── PMC3.png
28
28
  ├── PubTabNet_2.0.0.jsonl
29
29
  """
30
+ from __future__ import annotations
30
31
 
31
32
  from typing import Dict, List, Mapping, Union
32
33
 
@@ -119,7 +120,7 @@ class Pubtabnet(_BuiltInDataset):
119
120
  def _categories(self) -> DatasetCategories:
120
121
  return DatasetCategories(init_categories=_INIT_CATEGORIES, init_sub_categories=_SUB_CATEGORIES)
121
122
 
122
- def _builder(self) -> "PubtabnetBuilder":
123
+ def _builder(self) -> PubtabnetBuilder:
123
124
  return PubtabnetBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
124
125
 
125
126
 
@@ -29,6 +29,7 @@ Module for Publaynet dataset. Place the dataset as follows
29
29
  │ ├── train.txt
30
30
  │ ├── val.txt
31
31
  """
32
+ from __future__ import annotations
32
33
 
33
34
  import os
34
35
  from typing import Mapping, Union
@@ -102,7 +103,7 @@ class Rvlcdip(_BuiltInDataset):
102
103
  def _categories(self) -> DatasetCategories:
103
104
  return DatasetCategories(init_categories=_INIT_CATEGORIES)
104
105
 
105
- def _builder(self) -> "RvlcdipBuilder":
106
+ def _builder(self) -> RvlcdipBuilder:
106
107
  return RvlcdipBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
107
108
 
108
109
 
@@ -27,6 +27,7 @@ Module for XFUND dataset. Install the dataset following the folder structure
27
27
  │ ├── de_val_0.jpg
28
28
  ├── es_train
29
29
  """
30
+ from __future__ import annotations
30
31
 
31
32
  import json
32
33
  import os
@@ -108,7 +109,7 @@ class Xfund(_BuiltInDataset):
108
109
  def _categories(self) -> DatasetCategories:
109
110
  return DatasetCategories(init_categories=_INIT_CATEGORIES, init_sub_categories=_SUB_CATEGORIES)
110
111
 
111
- def _builder(self) -> "XfundBuilder":
112
+ def _builder(self) -> XfundBuilder:
112
113
  return XfundBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
113
114
 
114
115
 
@@ -20,12 +20,9 @@ Init file for eval package. Contains metrics (customized for special tasks), eva
20
20
  for training.
21
21
  """
22
22
 
23
- from ..utils.file_utils import apted_available
24
23
  from .accmetric import *
25
24
  from .base import *
26
25
  from .cocometric import *
27
26
  from .eval import *
28
27
  from .registry import *
29
-
30
- if apted_available():
31
- from .tedsmetric import *
28
+ from .tedsmetric import *
@@ -87,7 +87,7 @@ def accuracy(label_gt: Sequence[int], label_predictions: Sequence[int], masks: O
87
87
  np_label_gt, np_label_pr = np.asarray(label_gt), np.asarray(label_predictions)
88
88
  if len(np_label_gt) != len(np_label_pr):
89
89
  raise ValueError(
90
- f"length of label_gt ({len(np_label_gt)}) and label_predictions" f" ({len(np_label_pr)}) must be equal"
90
+ f"length label_gt: {len(np_label_gt)}, length label_predictions: ({len(np_label_pr)}) but must be equal"
91
91
  )
92
92
  if masks is not None:
93
93
  np_label_gt, np_label_pr = _mask_some_gt_and_pr_labels(np_label_gt, np_label_pr, masks)
@@ -25,6 +25,7 @@ from typing import Any, Callable, List, Optional, Tuple
25
25
  from ..dataflow import DataFlow
26
26
  from ..datasets.info import DatasetCategories
27
27
  from ..utils.detection_types import JsonDict
28
+ from ..utils.error import DependencyError
28
29
  from ..utils.file_utils import Requirement
29
30
 
30
31
 
@@ -52,7 +53,7 @@ class MetricBase(ABC):
52
53
  requirements = cls.get_requirements()
53
54
  name = cls.__name__ if hasattr(cls, "__name__") else cls.__class__.__name__
54
55
  if not all(requirement[1] for requirement in requirements):
55
- raise ImportError(
56
+ raise DependencyError(
56
57
  "\n".join(
57
58
  [f"{name} has the following dependencies:"]
58
59
  + [requirement[2] for requirement in requirements if not requirement[1]]
@@ -66,7 +67,7 @@ class MetricBase(ABC):
66
67
  """
67
68
  Get a list of requirements for running the detector
68
69
  """
69
- raise NotImplementedError
70
+ raise NotImplementedError()
70
71
 
71
72
  @classmethod
72
73
  @abstractmethod
@@ -80,7 +81,7 @@ class MetricBase(ABC):
80
81
  :param dataflow_predictions: Dataflow with predictions.
81
82
  :param categories: DatasetCategories with respect to the underlying dataset.
82
83
  """
83
- raise NotImplementedError
84
+ raise NotImplementedError()
84
85
 
85
86
  @classmethod
86
87
  @abstractmethod
@@ -95,7 +96,7 @@ class MetricBase(ABC):
95
96
  :param dataflow_predictions: Dataflow with predictions.
96
97
  :param categories: DatasetCategories with respect to the underlying dataset.
97
98
  """
98
- raise NotImplementedError
99
+ raise NotImplementedError()
99
100
 
100
101
  @classmethod
101
102
  def result_list_to_dict(cls, results: List[JsonDict]) -> JsonDict:
@@ -23,6 +23,7 @@ from copy import copy
23
23
  from typing import Dict, List, Optional, Tuple, Union
24
24
 
25
25
  import numpy as np
26
+ from lazy_imports import try_import
26
27
 
27
28
  from ..dataflow import DataFlow
28
29
  from ..datasets.info import DatasetCategories
@@ -33,7 +34,7 @@ from ..utils.file_utils import Requirement, cocotools_available, get_cocotools_r
33
34
  from .base import MetricBase
34
35
  from .registry import metric_registry
35
36
 
36
- if cocotools_available():
37
+ with try_import() as cc_import_guard:
37
38
  from pycocotools.coco import COCO
38
39
  from pycocotools.cocoeval import COCOeval
39
40
 
@@ -19,36 +19,35 @@
19
19
  """
20
20
  Module for `Evaluator`
21
21
  """
22
-
23
- __all__ = ["Evaluator"]
22
+ from __future__ import annotations
24
23
 
25
24
  from copy import deepcopy
26
- from typing import Any, Dict, List, Literal, Mapping, Optional, Type, Union, overload
25
+ from typing import Any, Dict, Generator, List, Literal, Mapping, Optional, Type, Union, overload
27
26
 
28
27
  import numpy as np
28
+ from lazy_imports import try_import
29
29
 
30
30
  from ..dataflow import CacheData, DataFlow, DataFromList, MapData
31
31
  from ..datapoint.image import Image
32
32
  from ..datasets.base import DatasetBase
33
33
  from ..mapper.cats import filter_cat, remove_cats
34
+ from ..mapper.d2struct import to_wandb_image
34
35
  from ..mapper.misc import maybe_load_image, maybe_remove_image, maybe_remove_image_from_category
35
36
  from ..pipe.base import LanguageModelPipelineComponent, PredictorPipelineComponent
36
37
  from ..pipe.common import PageParsingService
37
38
  from ..pipe.concurrency import MultiThreadPipelineComponent
38
39
  from ..pipe.doctectionpipe import DoctectionPipe
39
40
  from ..utils.detection_types import ImageType
40
- from ..utils.file_utils import detectron2_available, wandb_available
41
41
  from ..utils.logger import LoggingRecord, logger
42
42
  from ..utils.settings import DatasetType, LayoutType, TypeOrStr, get_type
43
43
  from ..utils.viz import interactive_imshow
44
44
  from .base import MetricBase
45
45
 
46
- if wandb_available():
46
+ with try_import() as wb_import_guard:
47
47
  import wandb # pylint:disable=W0611
48
48
  from wandb import Artifact, Table
49
49
 
50
- if wandb_available() and detectron2_available():
51
- from ..mapper.d2struct import to_wandb_image
50
+ __all__ = ["Evaluator"]
52
51
 
53
52
 
54
53
  class Evaluator:
@@ -94,7 +93,7 @@ class Evaluator:
94
93
  component_or_pipeline: Union[PredictorPipelineComponent, LanguageModelPipelineComponent, DoctectionPipe],
95
94
  metric: Union[Type[MetricBase], MetricBase],
96
95
  num_threads: int = 2,
97
- run: Optional["wandb.sdk.wandb_run.Run"] = None,
96
+ run: Optional[wandb.sdk.wandb_run.Run] = None,
98
97
  ) -> None:
99
98
  """
100
99
  Evaluating a pipeline component on a dataset with a given metric.
@@ -171,7 +170,7 @@ class Evaluator:
171
170
  "metric has no attribute sub_cats and cannot be used for token classification datasets"
172
171
  )
173
172
  else:
174
- raise NotImplementedError
173
+ raise NotImplementedError()
175
174
 
176
175
  else:
177
176
  self.wandb_table_agent = None
@@ -271,11 +270,11 @@ class Evaluator:
271
270
  sub_cats_to_remove = meta_anns["sub_categories"]
272
271
  df_pr = MapData(df_pr, remove_cats(sub_categories=sub_cats_to_remove))
273
272
  else:
274
- raise NotImplementedError
273
+ raise NotImplementedError()
275
274
 
276
275
  return df_pr
277
276
 
278
- def compare(self, interactive: bool = False, **kwargs: Union[str, int]) -> Optional[ImageType]:
277
+ def compare(self, interactive: bool = False, **kwargs: Union[str, int]) -> Generator[ImageType, None, None]:
279
278
  """
280
279
  Visualize ground truth and prediction datapoint. Given a dataflow config it will run predictions per sample
281
280
  and concat the prediction image (with predicted bounding boxes) with ground truth image.
@@ -292,6 +291,8 @@ class Evaluator:
292
291
  show_layouts = kwargs.pop("show_layouts", True)
293
292
  show_table_structure = kwargs.pop("show_table_structure", True)
294
293
  show_words = kwargs.pop("show_words", False)
294
+ show_token_class = kwargs.pop("show_token_class", True)
295
+ ignore_default_token_class = kwargs.pop("ignore_default_token_class", False)
295
296
 
296
297
  df_gt = self.dataset.dataflow.build(**kwargs)
297
298
  df_pr = self.dataset.dataflow.build(**kwargs)
@@ -321,18 +322,21 @@ class Evaluator:
321
322
  show_layouts=show_layouts,
322
323
  show_table_structure=show_table_structure,
323
324
  show_words=show_words,
325
+ show_token_class=show_token_class,
326
+ ignore_default_token_class=ignore_default_token_class,
324
327
  ), dp_pred.viz(
325
328
  show_tables=show_tables,
326
329
  show_layouts=show_layouts,
327
330
  show_table_structure=show_table_structure,
328
331
  show_words=show_words,
332
+ show_token_class=show_token_class,
333
+ ignore_default_token_class=ignore_default_token_class,
329
334
  )
330
335
  img_concat = np.concatenate((img_gt, img_pred), axis=1)
331
336
  if interactive:
332
337
  interactive_imshow(img_concat)
333
338
  else:
334
- return img_concat
335
- return None
339
+ yield img_concat
336
340
 
337
341
 
338
342
  class WandbTableAgent:
@@ -350,7 +354,7 @@ class WandbTableAgent:
350
354
 
351
355
  def __init__(
352
356
  self,
353
- wandb_run: "wandb.sdk.wandb_run.Run",
357
+ wandb_run: wandb.sdk.wandb_run.Run,
354
358
  dataset_name: str,
355
359
  num_samples: int,
356
360
  categories: Mapping[str, TypeOrStr],
@@ -409,7 +413,7 @@ class WandbTableAgent:
409
413
  self._table_rows = []
410
414
  self._counter = 0
411
415
 
412
- def _build_table(self) -> "Table":
416
+ def _build_table(self) -> Table:
413
417
  """
414
418
  Builds wandb.Table object for logging evaluation
415
419
 
@@ -20,28 +20,31 @@ import statistics
20
20
  from collections import defaultdict, deque
21
21
  from typing import Any, List, Optional, Tuple
22
22
 
23
+ from lazy_imports import try_import
24
+
23
25
  from ..dataflow import DataFlow, DataFromList, MapData, MultiThreadMapData
24
26
  from ..datapoint.view import Page
25
27
  from ..datasets.base import DatasetCategories
26
28
  from ..utils.detection_types import JsonDict
27
- from ..utils.file_utils import (
28
- Requirement,
29
- apted_available,
30
- distance_available,
31
- get_apted_requirement,
32
- get_distance_requirement,
33
- get_lxml_requirement,
34
- lxml_available,
35
- )
29
+ from ..utils.file_utils import Requirement, get_apted_requirement, get_distance_requirement, get_lxml_requirement
36
30
  from ..utils.logger import LoggingRecord, logger
37
31
  from ..utils.settings import LayoutType
38
32
  from .base import MetricBase
39
33
  from .registry import metric_registry
40
34
 
41
- if distance_available() and lxml_available() and apted_available():
42
- import distance # type: ignore
35
+ with try_import() as ap_import_guard:
43
36
  from apted import APTED, Config # type: ignore
44
37
  from apted.helpers import Tree # type: ignore
38
+
39
+
40
+ if not ap_import_guard.is_successful():
41
+ from ..utils.mocks import Config, Tree
42
+
43
+
44
+ with try_import() as ds_import_guard:
45
+ import distance # type: ignore
46
+
47
+ with try_import() as lx_import_guard:
45
48
  from lxml import etree
46
49
 
47
50
 
@@ -19,13 +19,16 @@
19
19
  Module for EvalCallback in Tensorpack
20
20
  """
21
21
 
22
+ from __future__ import annotations
23
+
22
24
  from itertools import count
23
25
  from typing import Mapping, Optional, Sequence, Type, Union
24
26
 
27
+ from lazy_imports import try_import
28
+
25
29
  from ..datasets import DatasetBase
26
30
  from ..extern.tpdetect import TPFrcnnDetector
27
31
  from ..pipe.base import PredictorPipelineComponent
28
- from ..utils.file_utils import tensorpack_available
29
32
  from ..utils.logger import LoggingRecord, logger
30
33
  from ..utils.metacfg import AttrDict
31
34
  from ..utils.settings import ObjectTypes
@@ -33,12 +36,15 @@ from .base import MetricBase
33
36
  from .eval import Evaluator
34
37
 
35
38
  # pylint: disable=import-error
36
- if tensorpack_available():
39
+ with try_import() as import_guard:
37
40
  from tensorpack.callbacks import Callback
38
41
  from tensorpack.predict import OnlinePredictor
39
42
  from tensorpack.utils.gpu import get_num_gpu
40
43
  # pylint: enable=import-error
41
44
 
45
+ if not import_guard.is_successful():
46
+ from ..utils.mocks import Callback
47
+
42
48
 
43
49
  # The following class is modified from
44
50
  # https://github.com/tensorpack/tensorpack/blob/master/examples/FasterRCNN/eval.py
@@ -53,7 +59,7 @@ class EvalCallback(Callback): # pylint: disable=R0903
53
59
 
54
60
  _chief_only = False
55
61
 
56
- def __init__(
62
+ def __init__( # pylint: disable=W0231
57
63
  self,
58
64
  dataset: DatasetBase,
59
65
  category_names: Optional[Union[ObjectTypes, Sequence[ObjectTypes]]],
@@ -83,10 +89,11 @@ class EvalCallback(Callback): # pylint: disable=R0903
83
89
  self.num_gpu = get_num_gpu()
84
90
  self.category_names = category_names
85
91
  self.sub_categories = sub_categories
86
- assert isinstance(pipeline_component.predictor, TPFrcnnDetector), (
87
- f"pipeline_component.predictor must be of "
88
- f"type TPFrcnnDetector but is type {type(pipeline_component.predictor)}"
89
- )
92
+ if not isinstance(pipeline_component.predictor, TPFrcnnDetector):
93
+ raise TypeError(
94
+ f"pipeline_component.predictor must be of type TPFrcnnDetector but is "
95
+ f"type {type(pipeline_component.predictor)}"
96
+ )
90
97
  self.cfg = pipeline_component.predictor.model.cfg
91
98
  if _use_replicated(self.cfg):
92
99
  self.evaluator = Evaluator(dataset, pipeline_component, metric, num_threads=self.num_gpu * 2)
@@ -19,8 +19,8 @@
19
19
  Wrappers for models of external libraries as well as implementation of the Cascade-RCNN model of Tensorpack.
20
20
  """
21
21
 
22
- from ..utils.file_utils import detectron2_available, tensorpack_available
23
22
  from .base import *
23
+ from .d2detect import *
24
24
  from .deskew import *
25
25
  from .doctrocr import *
26
26
  from .fastlang import *
@@ -30,9 +30,4 @@ from .model import *
30
30
  from .pdftext import *
31
31
  from .tessocr import *
32
32
  from .texocr import * # type: ignore
33
-
34
- if tensorpack_available():
35
- from .tpdetect import *
36
-
37
- if detectron2_available():
38
- from .d2detect import *
33
+ from .tpdetect import *
@@ -25,6 +25,7 @@ from dataclasses import dataclass
25
25
  from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
26
26
 
27
27
  from ..utils.detection_types import ImageType, JsonDict, Requirement
28
+ from ..utils.identifier import get_uuid_from_str
28
29
  from ..utils.settings import DefaultType, ObjectTypes, TypeOrStr, get_type
29
30
 
30
31
 
@@ -34,6 +35,7 @@ class PredictorBase(ABC):
34
35
  """
35
36
 
36
37
  name: str
38
+ model_id: str
37
39
 
38
40
  def __new__(cls, *args, **kwargs): # type: ignore # pylint: disable=W0613
39
41
  requirements = cls.get_requirements()
@@ -53,14 +55,22 @@ class PredictorBase(ABC):
53
55
  """
54
56
  Get a list of requirements for running the detector
55
57
  """
56
- raise NotImplementedError
58
+ raise NotImplementedError()
57
59
 
58
60
  @abstractmethod
59
61
  def clone(self) -> "PredictorBase":
60
62
  """
61
63
  Clone an instance
62
64
  """
63
- raise NotImplementedError
65
+ raise NotImplementedError()
66
+
67
+ def get_model_id(self) -> str:
68
+ """
69
+ Get the generating model
70
+ """
71
+ if self.name is not None:
72
+ return get_uuid_from_str(self.name)[:8]
73
+ raise ValueError("name must be set before calling get_model_id")
64
74
 
65
75
 
66
76
  @dataclass
@@ -102,6 +112,7 @@ class DetectionResult:
102
112
  line: Optional[str] = None
103
113
  uuid: Optional[str] = None
104
114
  relationships: Optional[Dict[str, Any]] = None
115
+ angle: Optional[float] = None
105
116
 
106
117
 
107
118
  class ObjectDetector(PredictorBase):
@@ -133,7 +144,7 @@ class ObjectDetector(PredictorBase):
133
144
  """
134
145
  Abstract method predict
135
146
  """
136
- raise NotImplementedError
147
+ raise NotImplementedError()
137
148
 
138
149
  @property
139
150
  def accepts_batch(self) -> bool:
@@ -174,14 +185,14 @@ class PdfMiner(PredictorBase):
174
185
  """
175
186
  Abstract method predict
176
187
  """
177
- raise NotImplementedError
188
+ raise NotImplementedError()
178
189
 
179
190
  @abstractmethod
180
191
  def get_width_height(self, pdf_bytes: bytes) -> Tuple[float, float]:
181
192
  """
182
193
  Abstract method get_width_height
183
194
  """
184
- raise NotImplementedError
195
+ raise NotImplementedError()
185
196
 
186
197
  def clone(self) -> PredictorBase:
187
198
  return self.__class__()
@@ -212,7 +223,7 @@ class TextRecognizer(PredictorBase):
212
223
  """
213
224
  Abstract method predict
214
225
  """
215
- raise NotImplementedError
226
+ raise NotImplementedError()
216
227
 
217
228
  @property
218
229
  def accepts_batch(self) -> bool:
@@ -294,7 +305,7 @@ class LMTokenClassifier(PredictorBase):
294
305
  """
295
306
  Abstract method predict
296
307
  """
297
- raise NotImplementedError
308
+ raise NotImplementedError()
298
309
 
299
310
  def possible_tokens(self) -> List[ObjectTypes]:
300
311
  """
@@ -307,7 +318,7 @@ class LMTokenClassifier(PredictorBase):
307
318
  """
308
319
  Clone an instance
309
320
  """
310
- raise NotImplementedError
321
+ raise NotImplementedError()
311
322
 
312
323
  @staticmethod
313
324
  def default_kwargs_for_input_mapping() -> JsonDict:
@@ -341,7 +352,7 @@ class LMSequenceClassifier(PredictorBase):
341
352
  """
342
353
  Abstract method predict
343
354
  """
344
- raise NotImplementedError
355
+ raise NotImplementedError()
345
356
 
346
357
  def possible_categories(self) -> List[ObjectTypes]:
347
358
  """
@@ -354,7 +365,7 @@ class LMSequenceClassifier(PredictorBase):
354
365
  """
355
366
  Clone an instance
356
367
  """
357
- raise NotImplementedError
368
+ raise NotImplementedError()
358
369
 
359
370
  @staticmethod
360
371
  def default_kwargs_for_input_mapping() -> JsonDict:
@@ -388,7 +399,7 @@ class LanguageDetector(PredictorBase):
388
399
  """
389
400
  Abstract method predict
390
401
  """
391
- raise NotImplementedError
402
+ raise NotImplementedError()
392
403
 
393
404
  def possible_languages(self) -> List[ObjectTypes]:
394
405
  """
@@ -403,11 +414,26 @@ class ImageTransformer(PredictorBase):
403
414
  """
404
415
 
405
416
  @abstractmethod
406
- def transform(self, np_img: ImageType) -> ImageType:
417
+ def transform(self, np_img: ImageType, specification: DetectionResult) -> ImageType:
407
418
  """
408
419
  Abstract method transform
409
420
  """
410
- raise NotImplementedError
421
+ raise NotImplementedError()
422
+
423
+ @abstractmethod
424
+ def predict(self, np_img: ImageType) -> DetectionResult:
425
+ """
426
+ Abstract method predict
427
+ """
428
+ raise NotImplementedError()
411
429
 
412
430
  def clone(self) -> PredictorBase:
413
431
  return self.__class__()
432
+
433
+ @staticmethod
434
+ @abstractmethod
435
+ def possible_category() -> ObjectTypes:
436
+ """
437
+ Returns a (single) category the `ImageTransformer` can predict
438
+ """
439
+ raise NotImplementedError()