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.
- deepdoctection/__init__.py +38 -29
- deepdoctection/analyzer/dd.py +36 -29
- deepdoctection/configs/conf_dd_one.yaml +34 -31
- deepdoctection/dataflow/base.py +0 -19
- deepdoctection/dataflow/custom.py +4 -3
- deepdoctection/dataflow/custom_serialize.py +14 -5
- deepdoctection/dataflow/parallel_map.py +12 -11
- deepdoctection/dataflow/serialize.py +5 -4
- deepdoctection/datapoint/annotation.py +35 -13
- deepdoctection/datapoint/box.py +3 -5
- deepdoctection/datapoint/convert.py +3 -1
- deepdoctection/datapoint/image.py +79 -36
- deepdoctection/datapoint/view.py +152 -49
- deepdoctection/datasets/__init__.py +1 -4
- deepdoctection/datasets/adapter.py +6 -3
- deepdoctection/datasets/base.py +86 -11
- deepdoctection/datasets/dataflow_builder.py +1 -1
- deepdoctection/datasets/info.py +4 -4
- deepdoctection/datasets/instances/doclaynet.py +3 -2
- deepdoctection/datasets/instances/fintabnet.py +2 -1
- deepdoctection/datasets/instances/funsd.py +2 -1
- deepdoctection/datasets/instances/iiitar13k.py +5 -2
- deepdoctection/datasets/instances/layouttest.py +4 -8
- deepdoctection/datasets/instances/publaynet.py +2 -2
- deepdoctection/datasets/instances/pubtables1m.py +6 -3
- deepdoctection/datasets/instances/pubtabnet.py +2 -1
- deepdoctection/datasets/instances/rvlcdip.py +2 -1
- deepdoctection/datasets/instances/xfund.py +2 -1
- deepdoctection/eval/__init__.py +1 -4
- deepdoctection/eval/accmetric.py +1 -1
- deepdoctection/eval/base.py +5 -4
- deepdoctection/eval/cocometric.py +2 -1
- deepdoctection/eval/eval.py +19 -15
- deepdoctection/eval/tedsmetric.py +14 -11
- deepdoctection/eval/tp_eval_callback.py +14 -7
- deepdoctection/extern/__init__.py +2 -7
- deepdoctection/extern/base.py +39 -13
- deepdoctection/extern/d2detect.py +182 -90
- deepdoctection/extern/deskew.py +36 -9
- deepdoctection/extern/doctrocr.py +265 -83
- deepdoctection/extern/fastlang.py +49 -9
- deepdoctection/extern/hfdetr.py +106 -55
- deepdoctection/extern/hflayoutlm.py +441 -122
- deepdoctection/extern/hflm.py +225 -0
- deepdoctection/extern/model.py +56 -47
- deepdoctection/extern/pdftext.py +10 -5
- deepdoctection/extern/pt/__init__.py +1 -3
- deepdoctection/extern/pt/nms.py +6 -2
- deepdoctection/extern/pt/ptutils.py +27 -18
- deepdoctection/extern/tessocr.py +134 -22
- deepdoctection/extern/texocr.py +6 -2
- deepdoctection/extern/tp/tfutils.py +43 -9
- deepdoctection/extern/tp/tpcompat.py +14 -11
- deepdoctection/extern/tp/tpfrcnn/__init__.py +20 -0
- deepdoctection/extern/tp/tpfrcnn/common.py +7 -3
- deepdoctection/extern/tp/tpfrcnn/config/__init__.py +20 -0
- deepdoctection/extern/tp/tpfrcnn/config/config.py +9 -6
- deepdoctection/extern/tp/tpfrcnn/modeling/__init__.py +20 -0
- deepdoctection/extern/tp/tpfrcnn/modeling/backbone.py +17 -7
- deepdoctection/extern/tp/tpfrcnn/modeling/generalized_rcnn.py +12 -6
- deepdoctection/extern/tp/tpfrcnn/modeling/model_box.py +9 -4
- deepdoctection/extern/tp/tpfrcnn/modeling/model_cascade.py +8 -5
- deepdoctection/extern/tp/tpfrcnn/modeling/model_fpn.py +16 -11
- deepdoctection/extern/tp/tpfrcnn/modeling/model_frcnn.py +17 -10
- deepdoctection/extern/tp/tpfrcnn/modeling/model_mrcnn.py +14 -8
- deepdoctection/extern/tp/tpfrcnn/modeling/model_rpn.py +15 -10
- deepdoctection/extern/tp/tpfrcnn/predict.py +9 -4
- deepdoctection/extern/tp/tpfrcnn/preproc.py +8 -9
- deepdoctection/extern/tp/tpfrcnn/utils/__init__.py +20 -0
- deepdoctection/extern/tp/tpfrcnn/utils/box_ops.py +10 -2
- deepdoctection/extern/tpdetect.py +54 -30
- deepdoctection/mapper/__init__.py +3 -8
- deepdoctection/mapper/d2struct.py +9 -7
- deepdoctection/mapper/hfstruct.py +7 -2
- deepdoctection/mapper/laylmstruct.py +164 -21
- deepdoctection/mapper/maputils.py +16 -3
- deepdoctection/mapper/misc.py +6 -3
- deepdoctection/mapper/prodigystruct.py +1 -1
- deepdoctection/mapper/pubstruct.py +10 -10
- deepdoctection/mapper/tpstruct.py +3 -3
- deepdoctection/pipe/__init__.py +1 -1
- deepdoctection/pipe/anngen.py +35 -8
- deepdoctection/pipe/base.py +53 -19
- deepdoctection/pipe/common.py +23 -13
- deepdoctection/pipe/concurrency.py +2 -1
- deepdoctection/pipe/doctectionpipe.py +2 -2
- deepdoctection/pipe/language.py +3 -2
- deepdoctection/pipe/layout.py +6 -3
- deepdoctection/pipe/lm.py +34 -66
- deepdoctection/pipe/order.py +142 -35
- deepdoctection/pipe/refine.py +26 -24
- deepdoctection/pipe/segment.py +21 -16
- deepdoctection/pipe/{cell.py → sub_layout.py} +30 -9
- deepdoctection/pipe/text.py +14 -8
- deepdoctection/pipe/transform.py +16 -9
- deepdoctection/train/__init__.py +6 -12
- deepdoctection/train/d2_frcnn_train.py +36 -28
- deepdoctection/train/hf_detr_train.py +26 -17
- deepdoctection/train/hf_layoutlm_train.py +133 -111
- deepdoctection/train/tp_frcnn_train.py +21 -19
- deepdoctection/utils/__init__.py +3 -0
- deepdoctection/utils/concurrency.py +1 -1
- deepdoctection/utils/context.py +2 -2
- deepdoctection/utils/env_info.py +41 -84
- deepdoctection/utils/error.py +84 -0
- deepdoctection/utils/file_utils.py +4 -15
- deepdoctection/utils/fs.py +7 -7
- deepdoctection/utils/logger.py +1 -0
- deepdoctection/utils/mocks.py +93 -0
- deepdoctection/utils/pdf_utils.py +5 -4
- deepdoctection/utils/settings.py +6 -1
- deepdoctection/utils/transform.py +1 -1
- deepdoctection/utils/utils.py +0 -6
- deepdoctection/utils/viz.py +48 -5
- {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/METADATA +57 -73
- deepdoctection-0.32.dist-info/RECORD +146 -0
- {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/WHEEL +1 -1
- deepdoctection-0.30.dist-info/RECORD +0 -143
- {deepdoctection-0.30.dist-info → deepdoctection-0.32.dist-info}/LICENSE +0 -0
- {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
|
-
|
|
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) ->
|
|
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
|
-
|
|
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,
|
|
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) ->
|
|
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) ->
|
|
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
|
-
|
|
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) ->
|
|
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) ->
|
|
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) ->
|
|
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) ->
|
|
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) ->
|
|
112
|
+
def _builder(self) -> XfundBuilder:
|
|
112
113
|
return XfundBuilder(location=_LOCATION, annotation_files=_ANNOTATION_FILES)
|
|
113
114
|
|
|
114
115
|
|
deepdoctection/eval/__init__.py
CHANGED
|
@@ -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 *
|
deepdoctection/eval/accmetric.py
CHANGED
|
@@ -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
|
|
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)
|
deepdoctection/eval/base.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
37
|
+
with try_import() as cc_import_guard:
|
|
37
38
|
from pycocotools.coco import COCO
|
|
38
39
|
from pycocotools.cocoeval import COCOeval
|
|
39
40
|
|
deepdoctection/eval/eval.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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[
|
|
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]) ->
|
|
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
|
-
|
|
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:
|
|
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) ->
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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 *
|
deepdoctection/extern/base.py
CHANGED
|
@@ -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()
|