deepdoctection 0.35__py3-none-any.whl → 0.36__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 +3 -6
- deepdoctection/analyzer/_config.py +10 -18
- deepdoctection/analyzer/factory.py +214 -18
- deepdoctection/configs/conf_dd_one.yaml +4 -0
- deepdoctection/datapoint/view.py +90 -15
- deepdoctection/eval/cocometric.py +59 -13
- deepdoctection/mapper/match.py +4 -2
- deepdoctection/utils/utils.py +39 -0
- deepdoctection/utils/viz.py +16 -13
- {deepdoctection-0.35.dist-info → deepdoctection-0.36.dist-info}/METADATA +116 -112
- {deepdoctection-0.35.dist-info → deepdoctection-0.36.dist-info}/RECORD +14 -14
- {deepdoctection-0.35.dist-info → deepdoctection-0.36.dist-info}/WHEEL +1 -1
- {deepdoctection-0.35.dist-info → deepdoctection-0.36.dist-info}/LICENSE +0 -0
- {deepdoctection-0.35.dist-info → deepdoctection-0.36.dist-info}/top_level.txt +0 -0
deepdoctection/__init__.py
CHANGED
|
@@ -24,14 +24,10 @@ from .utils.logger import LoggingRecord, logger
|
|
|
24
24
|
|
|
25
25
|
# pylint: enable=wrong-import-position
|
|
26
26
|
|
|
27
|
-
__version__ = 0.
|
|
27
|
+
__version__ = 0.36
|
|
28
28
|
|
|
29
29
|
_IMPORT_STRUCTURE = {
|
|
30
|
-
"analyzer": [
|
|
31
|
-
"config_sanity_checks",
|
|
32
|
-
"get_dd_analyzer",
|
|
33
|
-
"ServiceFactory"
|
|
34
|
-
],
|
|
30
|
+
"analyzer": ["config_sanity_checks", "get_dd_analyzer", "ServiceFactory"],
|
|
35
31
|
"configs": [],
|
|
36
32
|
"dataflow": [
|
|
37
33
|
"DataFlowTerminated",
|
|
@@ -379,6 +375,7 @@ _IMPORT_STRUCTURE = {
|
|
|
379
375
|
"get_pdf_file_writer",
|
|
380
376
|
"PDFStreamer",
|
|
381
377
|
"pdf_to_np_array",
|
|
378
|
+
"split_pdf",
|
|
382
379
|
"ObjectTypes",
|
|
383
380
|
"TypeOrStr",
|
|
384
381
|
"object_types_registry",
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
"""Pipeline configuration for deepdoctection analyzer. Do not change the defaults in this file. """
|
|
19
19
|
|
|
20
|
+
from ..datapoint.view import IMAGE_DEFAULTS
|
|
20
21
|
from ..utils.metacfg import AttrDict
|
|
21
22
|
from ..utils.settings import CellType, LayoutType
|
|
22
23
|
|
|
23
24
|
cfg = AttrDict()
|
|
24
25
|
|
|
26
|
+
|
|
25
27
|
cfg.LANGUAGE = None
|
|
26
28
|
cfg.LIB = None
|
|
27
29
|
cfg.DEVICE = None
|
|
@@ -32,11 +34,9 @@ cfg.USE_TABLE_SEGMENTATION = True
|
|
|
32
34
|
cfg.TF.LAYOUT.WEIGHTS = "layout/model-800000_inf_only.data-00000-of-00001"
|
|
33
35
|
cfg.TF.LAYOUT.FILTER = None
|
|
34
36
|
|
|
35
|
-
|
|
36
37
|
cfg.TF.CELL.WEIGHTS = "cell/model-1800000_inf_only.data-00000-of-00001"
|
|
37
38
|
cfg.TF.CELL.FILTER = None
|
|
38
39
|
|
|
39
|
-
|
|
40
40
|
cfg.TF.ITEM.WEIGHTS = "item/model-1620000_inf_only.data-00000-of-00001"
|
|
41
41
|
cfg.TF.ITEM.FILTER = None
|
|
42
42
|
|
|
@@ -112,7 +112,7 @@ cfg.OCR.WEIGHTS.DOCTR_WORD.PT = "doctr/db_resnet50/pt/db_resnet50-ac60cadc.pt"
|
|
|
112
112
|
cfg.OCR.WEIGHTS.DOCTR_RECOGNITION.TF = "doctr/crnn_vgg16_bn/tf/crnn_vgg16_bn-76b7f2c6.zip"
|
|
113
113
|
cfg.OCR.WEIGHTS.DOCTR_RECOGNITION.PT = "doctr/crnn_vgg16_bn/pt/crnn_vgg16_bn-9762b0b0.pt"
|
|
114
114
|
|
|
115
|
-
cfg.TEXT_CONTAINER =
|
|
115
|
+
cfg.TEXT_CONTAINER = IMAGE_DEFAULTS["text_container"]
|
|
116
116
|
cfg.WORD_MATCHING.PARENTAL_CATEGORIES = [
|
|
117
117
|
LayoutType.TEXT,
|
|
118
118
|
LayoutType.TITLE,
|
|
@@ -127,24 +127,16 @@ cfg.WORD_MATCHING.RULE = "ioa"
|
|
|
127
127
|
cfg.WORD_MATCHING.THRESHOLD = 0.6
|
|
128
128
|
cfg.WORD_MATCHING.MAX_PARENT_ONLY = True
|
|
129
129
|
|
|
130
|
-
cfg.TEXT_ORDERING.TEXT_BLOCK_CATEGORIES = [
|
|
131
|
-
|
|
132
|
-
LayoutType.TITLE,
|
|
133
|
-
LayoutType.LIST,
|
|
134
|
-
LayoutType.CELL,
|
|
135
|
-
CellType.COLUMN_HEADER,
|
|
136
|
-
CellType.PROJECTED_ROW_HEADER,
|
|
137
|
-
CellType.SPANNING,
|
|
138
|
-
CellType.ROW_HEADER,
|
|
139
|
-
]
|
|
140
|
-
cfg.TEXT_ORDERING.FLOATING_TEXT_BLOCK_CATEGORIES = [
|
|
141
|
-
LayoutType.TEXT,
|
|
142
|
-
LayoutType.TITLE,
|
|
143
|
-
LayoutType.LIST,
|
|
144
|
-
]
|
|
130
|
+
cfg.TEXT_ORDERING.TEXT_BLOCK_CATEGORIES = IMAGE_DEFAULTS["text_block_categories"]
|
|
131
|
+
cfg.TEXT_ORDERING.FLOATING_TEXT_BLOCK_CATEGORIES = IMAGE_DEFAULTS["floating_text_block_categories"]
|
|
145
132
|
cfg.TEXT_ORDERING.INCLUDE_RESIDUAL_TEXT_CONTAINER = False
|
|
146
133
|
cfg.TEXT_ORDERING.STARTING_POINT_TOLERANCE = 0.005
|
|
147
134
|
cfg.TEXT_ORDERING.BROKEN_LINE_TOLERANCE = 0.003
|
|
148
135
|
cfg.TEXT_ORDERING.HEIGHT_TOLERANCE = 2.0
|
|
149
136
|
cfg.TEXT_ORDERING.PARAGRAPH_BREAK = 0.035
|
|
137
|
+
|
|
138
|
+
cfg.USE_LAYOUT_LINK = False
|
|
139
|
+
cfg.LAYOUT_LINK.PARENTAL_CATEGORIES = []
|
|
140
|
+
cfg.LAYOUT_LINK.CHILD_CATEGORIES = []
|
|
141
|
+
|
|
150
142
|
cfg.freeze()
|
|
@@ -33,7 +33,13 @@ from ..extern.tessocr import TesseractOcrDetector, TesseractRotationTransformer
|
|
|
33
33
|
from ..extern.texocr import TextractOcrDetector
|
|
34
34
|
from ..extern.tpdetect import TPFrcnnDetector
|
|
35
35
|
from ..pipe.base import PipelineComponent
|
|
36
|
-
from ..pipe.common import
|
|
36
|
+
from ..pipe.common import (
|
|
37
|
+
AnnotationNmsService,
|
|
38
|
+
IntersectionMatcher,
|
|
39
|
+
MatchingService,
|
|
40
|
+
NeighbourMatcher,
|
|
41
|
+
PageParsingService,
|
|
42
|
+
)
|
|
37
43
|
from ..pipe.doctectionpipe import DoctectionPipe
|
|
38
44
|
from ..pipe.layout import ImageLayoutService
|
|
39
45
|
from ..pipe.order import TextOrderService
|
|
@@ -78,7 +84,7 @@ class ServiceFactory:
|
|
|
78
84
|
"""
|
|
79
85
|
|
|
80
86
|
@staticmethod
|
|
81
|
-
def
|
|
87
|
+
def _build_layout_detector(
|
|
82
88
|
config: AttrDict,
|
|
83
89
|
mode: str,
|
|
84
90
|
) -> Union[D2FrcnnDetector, TPFrcnnDetector, HFDetrDerivedDetector, D2FrcnnTracingDetector]:
|
|
@@ -141,17 +147,38 @@ class ServiceFactory:
|
|
|
141
147
|
)
|
|
142
148
|
|
|
143
149
|
@staticmethod
|
|
144
|
-
def
|
|
150
|
+
def build_layout_detector(
|
|
151
|
+
config: AttrDict, mode: str
|
|
152
|
+
) -> Union[D2FrcnnDetector, TPFrcnnDetector, HFDetrDerivedDetector, D2FrcnnTracingDetector]:
|
|
153
|
+
"""Building a layout detector according to the config
|
|
154
|
+
|
|
155
|
+
:param config: configuration object
|
|
156
|
+
:param mode: either `LAYOUT`,`CELL` or `ITEM`
|
|
157
|
+
"""
|
|
158
|
+
return ServiceFactory._build_layout_detector(config, mode)
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def _build_rotation_detector() -> TesseractRotationTransformer:
|
|
145
162
|
"""Building a rotation detector"""
|
|
146
163
|
return TesseractRotationTransformer()
|
|
147
164
|
|
|
148
165
|
@staticmethod
|
|
149
|
-
def
|
|
166
|
+
def build_rotation_detector() -> TesseractRotationTransformer:
|
|
167
|
+
"""Building a rotation detector"""
|
|
168
|
+
return ServiceFactory._build_rotation_detector()
|
|
169
|
+
|
|
170
|
+
@staticmethod
|
|
171
|
+
def _build_transform_service(transform_predictor: ImageTransformer) -> SimpleTransformService:
|
|
150
172
|
"""Building a transform service with a given predictor"""
|
|
151
173
|
return SimpleTransformService(transform_predictor)
|
|
152
174
|
|
|
153
175
|
@staticmethod
|
|
154
|
-
def
|
|
176
|
+
def build_transform_service(transform_predictor: ImageTransformer) -> SimpleTransformService:
|
|
177
|
+
"""Building a transform service with a given predictor"""
|
|
178
|
+
return ServiceFactory._build_transform_service(transform_predictor)
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def _build_padder(config: AttrDict, mode: str) -> PadTransform:
|
|
155
182
|
"""Building a padder according to the config
|
|
156
183
|
|
|
157
184
|
:param config: configuration object
|
|
@@ -164,10 +191,20 @@ class ServiceFactory:
|
|
|
164
191
|
getattr(config.PT, mode).PAD.BOTTOM,
|
|
165
192
|
getattr(config.PT, mode).PAD.LEFT,
|
|
166
193
|
)
|
|
167
|
-
return PadTransform(top=top, right=right, bottom=bottom, left=left)
|
|
194
|
+
return PadTransform(top=top, right=right, bottom=bottom, left=left) #
|
|
168
195
|
|
|
169
196
|
@staticmethod
|
|
170
|
-
def
|
|
197
|
+
def build_padder(config: AttrDict, mode: str) -> PadTransform:
|
|
198
|
+
"""Building a padder according to the config
|
|
199
|
+
|
|
200
|
+
:param config: configuration object
|
|
201
|
+
:param mode: either `LAYOUT`,`CELL` or `ITEM`
|
|
202
|
+
:return `PadTransform` instance
|
|
203
|
+
"""
|
|
204
|
+
return ServiceFactory._build_padder(config, mode)
|
|
205
|
+
|
|
206
|
+
@staticmethod
|
|
207
|
+
def _build_layout_service(config: AttrDict, detector: ObjectDetector, mode: str) -> ImageLayoutService:
|
|
171
208
|
"""Building a layout service with a given detector
|
|
172
209
|
|
|
173
210
|
:param config: configuration object
|
|
@@ -181,7 +218,18 @@ class ServiceFactory:
|
|
|
181
218
|
return ImageLayoutService(layout_detector=detector, to_image=True, crop_image=True, padder=padder)
|
|
182
219
|
|
|
183
220
|
@staticmethod
|
|
184
|
-
def
|
|
221
|
+
def build_layout_service(config: AttrDict, detector: ObjectDetector, mode: str) -> ImageLayoutService:
|
|
222
|
+
"""Building a layout service with a given detector
|
|
223
|
+
|
|
224
|
+
:param config: configuration object
|
|
225
|
+
:param detector: will be passed to the `ImageLayoutService`
|
|
226
|
+
:param mode: either `LAYOUT`,`CELL` or `ITEM`
|
|
227
|
+
:return `ImageLayoutService` instance
|
|
228
|
+
"""
|
|
229
|
+
return ServiceFactory._build_layout_service(config, detector, mode)
|
|
230
|
+
|
|
231
|
+
@staticmethod
|
|
232
|
+
def _build_layout_nms_service(config: AttrDict) -> AnnotationNmsService:
|
|
185
233
|
"""Building a NMS service for layout annotations
|
|
186
234
|
|
|
187
235
|
:param config: configuration object
|
|
@@ -199,7 +247,15 @@ class ServiceFactory:
|
|
|
199
247
|
)
|
|
200
248
|
|
|
201
249
|
@staticmethod
|
|
202
|
-
def
|
|
250
|
+
def build_layout_nms_service(config: AttrDict) -> AnnotationNmsService:
|
|
251
|
+
"""Building a NMS service for layout annotations
|
|
252
|
+
|
|
253
|
+
:param config: configuration object
|
|
254
|
+
"""
|
|
255
|
+
return ServiceFactory._build_layout_nms_service(config)
|
|
256
|
+
|
|
257
|
+
@staticmethod
|
|
258
|
+
def _build_sub_image_service(config: AttrDict, detector: ObjectDetector, mode: str) -> SubImageLayoutService:
|
|
203
259
|
"""
|
|
204
260
|
Building a sub image layout service with a given detector
|
|
205
261
|
|
|
@@ -226,7 +282,19 @@ class ServiceFactory:
|
|
|
226
282
|
)
|
|
227
283
|
|
|
228
284
|
@staticmethod
|
|
229
|
-
def
|
|
285
|
+
def build_sub_image_service(config: AttrDict, detector: ObjectDetector, mode: str) -> SubImageLayoutService:
|
|
286
|
+
"""
|
|
287
|
+
Building a sub image layout service with a given detector
|
|
288
|
+
|
|
289
|
+
:param config: configuration object
|
|
290
|
+
:param detector: will be passed to the `SubImageLayoutService`
|
|
291
|
+
:param mode: either `LAYOUT`,`CELL` or `ITEM`
|
|
292
|
+
:return: `SubImageLayoutService` instance
|
|
293
|
+
"""
|
|
294
|
+
return ServiceFactory._build_sub_image_service(config, detector, mode)
|
|
295
|
+
|
|
296
|
+
@staticmethod
|
|
297
|
+
def _build_ocr_detector(config: AttrDict) -> Union[TesseractOcrDetector, DoctrTextRecognizer, TextractOcrDetector]:
|
|
230
298
|
"""
|
|
231
299
|
Building OCR predictor
|
|
232
300
|
|
|
@@ -266,6 +334,15 @@ class ServiceFactory:
|
|
|
266
334
|
return TextractOcrDetector(**credentials_kwargs)
|
|
267
335
|
raise ValueError("You have set USE_OCR=True but any of USE_TESSERACT, USE_DOCTR, USE_TEXTRACT is set to False")
|
|
268
336
|
|
|
337
|
+
@staticmethod
|
|
338
|
+
def build_ocr_detector(config: AttrDict) -> Union[TesseractOcrDetector, DoctrTextRecognizer, TextractOcrDetector]:
|
|
339
|
+
"""
|
|
340
|
+
Building OCR predictor
|
|
341
|
+
|
|
342
|
+
:param config: configuration object
|
|
343
|
+
"""
|
|
344
|
+
return ServiceFactory._build_ocr_detector(config)
|
|
345
|
+
|
|
269
346
|
@staticmethod
|
|
270
347
|
def build_doctr_word_detector(config: AttrDict) -> DoctrTextlineDetector:
|
|
271
348
|
"""Building `DoctrTextlineDetector` instance
|
|
@@ -285,7 +362,7 @@ class ServiceFactory:
|
|
|
285
362
|
)
|
|
286
363
|
|
|
287
364
|
@staticmethod
|
|
288
|
-
def
|
|
365
|
+
def _build_table_segmentation_service(
|
|
289
366
|
config: AttrDict,
|
|
290
367
|
detector: ObjectDetector,
|
|
291
368
|
) -> Union[PubtablesSegmentationService, TableSegmentationService]:
|
|
@@ -342,7 +419,32 @@ class ServiceFactory:
|
|
|
342
419
|
return table_segmentation
|
|
343
420
|
|
|
344
421
|
@staticmethod
|
|
345
|
-
def
|
|
422
|
+
def build_table_segmentation_service(
|
|
423
|
+
config: AttrDict,
|
|
424
|
+
detector: ObjectDetector,
|
|
425
|
+
) -> Union[PubtablesSegmentationService, TableSegmentationService]:
|
|
426
|
+
"""
|
|
427
|
+
Build and return a table segmentation service based on the provided detector.
|
|
428
|
+
|
|
429
|
+
Depending on the type of the detector, this method will return either a `PubtablesSegmentationService` or a
|
|
430
|
+
`TableSegmentationService` instance. The selection is made as follows:
|
|
431
|
+
|
|
432
|
+
- If the detector is an instance of `HFDetrDerivedDetector`, a `PubtablesSegmentationService` is created and
|
|
433
|
+
returned. This service uses specific configuration parameters for segmentation, such as assignment rules,
|
|
434
|
+
thresholds, and cell names defined in the `cfg` object.
|
|
435
|
+
- For other detector types, a `TableSegmentationService` is created and returned. This service also uses
|
|
436
|
+
configuration parameters from the `cfg` object but is tailored for different segmentation needs.
|
|
437
|
+
|
|
438
|
+
:param config: configuration object
|
|
439
|
+
:param detector: An instance of `ObjectDetector` used to determine the type of table segmentation
|
|
440
|
+
service to build.
|
|
441
|
+
:return: An instance of either `PubtablesSegmentationService` or `TableSegmentationService` based on the
|
|
442
|
+
detector type.
|
|
443
|
+
"""
|
|
444
|
+
return ServiceFactory._build_table_segmentation_service(config, detector)
|
|
445
|
+
|
|
446
|
+
@staticmethod
|
|
447
|
+
def _build_table_refinement_service(config: AttrDict) -> TableSegmentationRefinementService:
|
|
346
448
|
"""Building a table segmentation refinement service
|
|
347
449
|
|
|
348
450
|
:param config: configuration object
|
|
@@ -354,7 +456,16 @@ class ServiceFactory:
|
|
|
354
456
|
)
|
|
355
457
|
|
|
356
458
|
@staticmethod
|
|
357
|
-
def
|
|
459
|
+
def build_table_refinement_service(config: AttrDict) -> TableSegmentationRefinementService:
|
|
460
|
+
"""Building a table segmentation refinement service
|
|
461
|
+
|
|
462
|
+
:param config: configuration object
|
|
463
|
+
:return: TableSegmentationRefinementService
|
|
464
|
+
"""
|
|
465
|
+
return ServiceFactory._build_table_refinement_service(config)
|
|
466
|
+
|
|
467
|
+
@staticmethod
|
|
468
|
+
def _build_pdf_text_detector(config: AttrDict) -> PdfPlumberTextDetector:
|
|
358
469
|
"""Building a PDF text detector
|
|
359
470
|
|
|
360
471
|
:param config: configuration object
|
|
@@ -365,7 +476,16 @@ class ServiceFactory:
|
|
|
365
476
|
)
|
|
366
477
|
|
|
367
478
|
@staticmethod
|
|
368
|
-
def
|
|
479
|
+
def build_pdf_text_detector(config: AttrDict) -> PdfPlumberTextDetector:
|
|
480
|
+
"""Building a PDF text detector
|
|
481
|
+
|
|
482
|
+
:param config: configuration object
|
|
483
|
+
:return: PdfPlumberTextDetector
|
|
484
|
+
"""
|
|
485
|
+
return ServiceFactory._build_pdf_text_detector(config)
|
|
486
|
+
|
|
487
|
+
@staticmethod
|
|
488
|
+
def _build_pdf_miner_text_service(detector: PdfMiner) -> TextExtractionService:
|
|
369
489
|
"""Building a PDFMiner text extraction service
|
|
370
490
|
|
|
371
491
|
:param detector: PdfMiner
|
|
@@ -373,6 +493,15 @@ class ServiceFactory:
|
|
|
373
493
|
"""
|
|
374
494
|
return TextExtractionService(detector)
|
|
375
495
|
|
|
496
|
+
@staticmethod
|
|
497
|
+
def build_pdf_miner_text_service(detector: PdfMiner) -> TextExtractionService:
|
|
498
|
+
"""Building a PDFMiner text extraction service
|
|
499
|
+
|
|
500
|
+
:param detector: PdfMiner
|
|
501
|
+
:return: TextExtractionService
|
|
502
|
+
"""
|
|
503
|
+
return ServiceFactory._build_pdf_miner_text_service(detector)
|
|
504
|
+
|
|
376
505
|
@staticmethod
|
|
377
506
|
def build_doctr_word_detector_service(detector: DoctrTextlineDetector) -> ImageLayoutService:
|
|
378
507
|
"""Building a Doctr word detector service
|
|
@@ -385,7 +514,7 @@ class ServiceFactory:
|
|
|
385
514
|
)
|
|
386
515
|
|
|
387
516
|
@staticmethod
|
|
388
|
-
def
|
|
517
|
+
def _build_text_extraction_service(
|
|
389
518
|
config: AttrDict, detector: Union[TesseractOcrDetector, DoctrTextRecognizer, TextractOcrDetector]
|
|
390
519
|
) -> TextExtractionService:
|
|
391
520
|
"""Building a text extraction service
|
|
@@ -401,7 +530,19 @@ class ServiceFactory:
|
|
|
401
530
|
)
|
|
402
531
|
|
|
403
532
|
@staticmethod
|
|
404
|
-
def
|
|
533
|
+
def build_text_extraction_service(
|
|
534
|
+
config: AttrDict, detector: Union[TesseractOcrDetector, DoctrTextRecognizer, TextractOcrDetector]
|
|
535
|
+
) -> TextExtractionService:
|
|
536
|
+
"""Building a text extraction service
|
|
537
|
+
|
|
538
|
+
:param config: configuration object
|
|
539
|
+
:param detector: OCR detector
|
|
540
|
+
:return: TextExtractionService
|
|
541
|
+
"""
|
|
542
|
+
return ServiceFactory._build_text_extraction_service(config, detector)
|
|
543
|
+
|
|
544
|
+
@staticmethod
|
|
545
|
+
def _build_word_matching_service(config: AttrDict) -> MatchingService:
|
|
405
546
|
"""Building a word matching service
|
|
406
547
|
|
|
407
548
|
:param config: configuration object
|
|
@@ -420,7 +561,40 @@ class ServiceFactory:
|
|
|
420
561
|
)
|
|
421
562
|
|
|
422
563
|
@staticmethod
|
|
423
|
-
def
|
|
564
|
+
def build_word_matching_service(config: AttrDict) -> MatchingService:
|
|
565
|
+
"""Building a word matching service
|
|
566
|
+
|
|
567
|
+
:param config: configuration object
|
|
568
|
+
:return: MatchingService
|
|
569
|
+
"""
|
|
570
|
+
return ServiceFactory._build_word_matching_service(config)
|
|
571
|
+
|
|
572
|
+
@staticmethod
|
|
573
|
+
def _build_layout_link_matching_service(config: AttrDict) -> MatchingService:
|
|
574
|
+
"""Building a word matching service
|
|
575
|
+
|
|
576
|
+
:param config: configuration object
|
|
577
|
+
:return: MatchingService
|
|
578
|
+
"""
|
|
579
|
+
neighbor_matcher = NeighbourMatcher()
|
|
580
|
+
return MatchingService(
|
|
581
|
+
parent_categories=config.LAYOUT_LINK.PARENTAL_CATEGORIES,
|
|
582
|
+
child_categories=config.LAYOUT_LINK.CHILD_CATEGORIES,
|
|
583
|
+
matcher=neighbor_matcher,
|
|
584
|
+
relationship_key=Relationships.LAYOUT_LINK,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
@staticmethod
|
|
588
|
+
def build_layout_link_matching_service(config: AttrDict) -> MatchingService:
|
|
589
|
+
"""Building a word matching service
|
|
590
|
+
|
|
591
|
+
:param config: configuration object
|
|
592
|
+
:return: MatchingService
|
|
593
|
+
"""
|
|
594
|
+
return ServiceFactory._build_layout_link_matching_service(config)
|
|
595
|
+
|
|
596
|
+
@staticmethod
|
|
597
|
+
def _build_text_order_service(config: AttrDict) -> TextOrderService:
|
|
424
598
|
"""Building a text order service
|
|
425
599
|
|
|
426
600
|
:param config: configuration object
|
|
@@ -438,7 +612,16 @@ class ServiceFactory:
|
|
|
438
612
|
)
|
|
439
613
|
|
|
440
614
|
@staticmethod
|
|
441
|
-
def
|
|
615
|
+
def build_text_order_service(config: AttrDict) -> TextOrderService:
|
|
616
|
+
"""Building a text order service
|
|
617
|
+
|
|
618
|
+
:param config: configuration object
|
|
619
|
+
:return: TextOrderService instance
|
|
620
|
+
"""
|
|
621
|
+
return ServiceFactory._build_text_order_service(config)
|
|
622
|
+
|
|
623
|
+
@staticmethod
|
|
624
|
+
def _build_page_parsing_service(config: AttrDict) -> PageParsingService:
|
|
442
625
|
"""Building a page parsing service
|
|
443
626
|
|
|
444
627
|
:param config: configuration object
|
|
@@ -450,6 +633,15 @@ class ServiceFactory:
|
|
|
450
633
|
include_residual_text_container=config.TEXT_ORDERING.INCLUDE_RESIDUAL_TEXT_CONTAINER,
|
|
451
634
|
)
|
|
452
635
|
|
|
636
|
+
@staticmethod
|
|
637
|
+
def build_page_parsing_service(config: AttrDict) -> PageParsingService:
|
|
638
|
+
"""Building a page parsing service
|
|
639
|
+
|
|
640
|
+
:param config: configuration object
|
|
641
|
+
:return: PageParsingService instance
|
|
642
|
+
"""
|
|
643
|
+
return ServiceFactory._build_page_parsing_service(config)
|
|
644
|
+
|
|
453
645
|
@staticmethod
|
|
454
646
|
def build_analyzer(config: AttrDict) -> DoctectionPipe:
|
|
455
647
|
"""
|
|
@@ -517,6 +709,10 @@ class ServiceFactory:
|
|
|
517
709
|
text_order_service = ServiceFactory.build_text_order_service(config)
|
|
518
710
|
pipe_component_list.append(text_order_service)
|
|
519
711
|
|
|
712
|
+
if config.USE_LAYOUT_LINK:
|
|
713
|
+
layout_link_matching_service = ServiceFactory.build_layout_link_matching_service(config)
|
|
714
|
+
pipe_component_list.append(layout_link_matching_service)
|
|
715
|
+
|
|
520
716
|
page_parsing_service = ServiceFactory.build_page_parsing_service(config)
|
|
521
717
|
|
|
522
718
|
return DoctectionPipe(pipeline_component_list=pipe_component_list, page_parsing_service=page_parsing_service)
|
deepdoctection/datapoint/view.py
CHANGED
|
@@ -25,6 +25,7 @@ from copy import copy
|
|
|
25
25
|
from typing import Any, Mapping, Optional, Sequence, Type, TypedDict, Union, no_type_check
|
|
26
26
|
|
|
27
27
|
import numpy as np
|
|
28
|
+
from typing_extensions import LiteralString
|
|
28
29
|
|
|
29
30
|
from ..utils.error import AnnotationError, ImageError
|
|
30
31
|
from ..utils.logger import LoggingRecord, logger
|
|
@@ -40,10 +41,12 @@ from ..utils.settings import (
|
|
|
40
41
|
WordType,
|
|
41
42
|
get_type,
|
|
42
43
|
)
|
|
44
|
+
from ..utils.transform import ResizeTransform
|
|
43
45
|
from ..utils.types import HTML, AnnotationDict, Chunks, ImageDict, PathLikeOrStr, PixelValues, Text_, csv
|
|
44
46
|
from ..utils.viz import draw_boxes, interactive_imshow, viz_handler
|
|
45
47
|
from .annotation import CategoryAnnotation, ContainerAnnotation, ImageAnnotation, ann_from_dict
|
|
46
48
|
from .box import BoundingBox, crop_box_from_image
|
|
49
|
+
from .convert import box_to_point4, point4_to_box
|
|
47
50
|
from .image import Image
|
|
48
51
|
|
|
49
52
|
|
|
@@ -101,7 +104,7 @@ class ImageAnnotationBaseView(ImageAnnotation):
|
|
|
101
104
|
return np_image
|
|
102
105
|
raise AnnotationError(f"base_page.image is None for {self.annotation_id}")
|
|
103
106
|
|
|
104
|
-
def __getattr__(self, item: str) -> Optional[Union[str, int, list[str]]]:
|
|
107
|
+
def __getattr__(self, item: str) -> Optional[Union[str, int, list[str], list[ImageAnnotationBaseView]]]:
|
|
105
108
|
"""
|
|
106
109
|
Get attributes defined by registered `self.get_attribute_names()` in a multi step process:
|
|
107
110
|
|
|
@@ -126,6 +129,9 @@ class ImageAnnotationBaseView(ImageAnnotation):
|
|
|
126
129
|
if isinstance(sub_cat, ContainerAnnotation):
|
|
127
130
|
return sub_cat.value
|
|
128
131
|
return sub_cat.category_id
|
|
132
|
+
if item in self.relationships:
|
|
133
|
+
relationship_ids = self.get_relationship(get_type(item))
|
|
134
|
+
return self.base_page.get_annotation(annotation_ids=relationship_ids)
|
|
129
135
|
if self.image is not None:
|
|
130
136
|
if item in self.image.summary.sub_categories:
|
|
131
137
|
sub_cat = self.get_summary(get_type(item))
|
|
@@ -165,7 +171,11 @@ class Word(ImageAnnotationBaseView):
|
|
|
165
171
|
"""
|
|
166
172
|
|
|
167
173
|
def get_attribute_names(self) -> set[str]:
|
|
168
|
-
return
|
|
174
|
+
return (
|
|
175
|
+
set(WordType)
|
|
176
|
+
.union(super().get_attribute_names())
|
|
177
|
+
.union({Relationships.READING_ORDER, Relationships.LAYOUT_LINK})
|
|
178
|
+
)
|
|
169
179
|
|
|
170
180
|
|
|
171
181
|
class Layout(ImageAnnotationBaseView):
|
|
@@ -246,7 +256,11 @@ class Layout(ImageAnnotationBaseView):
|
|
|
246
256
|
}
|
|
247
257
|
|
|
248
258
|
def get_attribute_names(self) -> set[str]:
|
|
249
|
-
return
|
|
259
|
+
return (
|
|
260
|
+
{"words", "text"}
|
|
261
|
+
.union(super().get_attribute_names())
|
|
262
|
+
.union({Relationships.READING_ORDER, Relationships.LAYOUT_LINK})
|
|
263
|
+
)
|
|
250
264
|
|
|
251
265
|
def __len__(self) -> int:
|
|
252
266
|
"""len of text counted by number of characters"""
|
|
@@ -433,8 +447,8 @@ class ImageDefaults(TypedDict):
|
|
|
433
447
|
"""ImageDefaults"""
|
|
434
448
|
|
|
435
449
|
text_container: LayoutType
|
|
436
|
-
floating_text_block_categories: tuple[LayoutType, ...]
|
|
437
|
-
text_block_categories: tuple[LayoutType, ...]
|
|
450
|
+
floating_text_block_categories: tuple[Union[LayoutType, CellType], ...]
|
|
451
|
+
text_block_categories: tuple[Union[LayoutType, CellType], ...]
|
|
438
452
|
|
|
439
453
|
|
|
440
454
|
IMAGE_DEFAULTS: ImageDefaults = {
|
|
@@ -448,9 +462,13 @@ IMAGE_DEFAULTS: ImageDefaults = {
|
|
|
448
462
|
"text_block_categories": (
|
|
449
463
|
LayoutType.TEXT,
|
|
450
464
|
LayoutType.TITLE,
|
|
451
|
-
LayoutType.FIGURE,
|
|
452
465
|
LayoutType.LIST,
|
|
453
466
|
LayoutType.CELL,
|
|
467
|
+
LayoutType.FIGURE,
|
|
468
|
+
CellType.COLUMN_HEADER,
|
|
469
|
+
CellType.PROJECTED_ROW_HEADER,
|
|
470
|
+
CellType.SPANNING,
|
|
471
|
+
CellType.ROW_HEADER,
|
|
454
472
|
),
|
|
455
473
|
}
|
|
456
474
|
|
|
@@ -510,6 +528,8 @@ class Page(Image):
|
|
|
510
528
|
"document_id",
|
|
511
529
|
"page_number",
|
|
512
530
|
"angle",
|
|
531
|
+
"figures",
|
|
532
|
+
"residual_layouts",
|
|
513
533
|
}
|
|
514
534
|
include_residual_text_container: bool = True
|
|
515
535
|
|
|
@@ -608,6 +628,41 @@ class Page(Image):
|
|
|
608
628
|
"""
|
|
609
629
|
return self.get_annotation(category_names=LayoutType.TABLE)
|
|
610
630
|
|
|
631
|
+
@property
|
|
632
|
+
def figures(self) -> list[ImageAnnotationBaseView]:
|
|
633
|
+
"""
|
|
634
|
+
A list of a figures.
|
|
635
|
+
"""
|
|
636
|
+
return self.get_annotation(category_names=LayoutType.FIGURE)
|
|
637
|
+
|
|
638
|
+
@property
|
|
639
|
+
def residual_layouts(self) -> list[ImageAnnotationBaseView]:
|
|
640
|
+
"""
|
|
641
|
+
A list of all residual layouts. Residual layouts are all layouts that are
|
|
642
|
+
- not floating text blocks,
|
|
643
|
+
- not text containers,
|
|
644
|
+
- not tables,
|
|
645
|
+
- not figures
|
|
646
|
+
- not cells
|
|
647
|
+
- not rows
|
|
648
|
+
- not columns
|
|
649
|
+
"""
|
|
650
|
+
return self.get_annotation(category_names=self._get_residual_layout())
|
|
651
|
+
|
|
652
|
+
def _get_residual_layout(self) -> list[LiteralString]:
|
|
653
|
+
layouts = copy(list(self.floating_text_block_categories))
|
|
654
|
+
layouts.extend(
|
|
655
|
+
[
|
|
656
|
+
LayoutType.TABLE,
|
|
657
|
+
LayoutType.FIGURE,
|
|
658
|
+
self.text_container,
|
|
659
|
+
LayoutType.CELL,
|
|
660
|
+
LayoutType.ROW,
|
|
661
|
+
LayoutType.COLUMN,
|
|
662
|
+
]
|
|
663
|
+
)
|
|
664
|
+
return [layout for layout in LayoutType if layout not in layouts]
|
|
665
|
+
|
|
611
666
|
@classmethod
|
|
612
667
|
def from_image(
|
|
613
668
|
cls,
|
|
@@ -801,12 +856,15 @@ class Page(Image):
|
|
|
801
856
|
self,
|
|
802
857
|
show_tables: bool = True,
|
|
803
858
|
show_layouts: bool = True,
|
|
859
|
+
show_figures: bool = False,
|
|
860
|
+
show_residual_layouts: bool = False,
|
|
804
861
|
show_cells: bool = True,
|
|
805
862
|
show_table_structure: bool = True,
|
|
806
863
|
show_words: bool = False,
|
|
807
864
|
show_token_class: bool = True,
|
|
808
865
|
ignore_default_token_class: bool = False,
|
|
809
866
|
interactive: bool = False,
|
|
867
|
+
scaled_width: int = 600,
|
|
810
868
|
**debug_kwargs: str,
|
|
811
869
|
) -> Optional[PixelValues]:
|
|
812
870
|
"""
|
|
@@ -827,12 +885,14 @@ class Page(Image):
|
|
|
827
885
|
|
|
828
886
|
:param show_tables: Will display all tables boxes as well as cells, rows and columns
|
|
829
887
|
:param show_layouts: Will display all other layout components.
|
|
888
|
+
:param show_figures: Will display all figures
|
|
830
889
|
:param show_cells: Will display cells within tables. (Only available if `show_tables=True`)
|
|
831
890
|
:param show_table_structure: Will display rows and columns
|
|
832
891
|
:param show_words: Will display bounding boxes around words labeled with token class and bio tag (experimental)
|
|
833
892
|
:param show_token_class: Will display token class instead of token tags (i.e. token classes with tags)
|
|
834
893
|
:param interactive: If set to True will open an interactive image, otherwise it will return a numpy array that
|
|
835
894
|
can be displayed differently.
|
|
895
|
+
:param scaled_width: Width of the image to display
|
|
836
896
|
:param ignore_default_token_class: Will ignore displaying word bounding boxes with default or None token class
|
|
837
897
|
label
|
|
838
898
|
:return: If `interactive=False` will return a numpy array.
|
|
@@ -858,6 +918,11 @@ class Page(Image):
|
|
|
858
918
|
box_stack.append(item.bbox)
|
|
859
919
|
category_names_list.append(item.category_name.value)
|
|
860
920
|
|
|
921
|
+
if show_figures and not debug_kwargs:
|
|
922
|
+
for item in self.figures:
|
|
923
|
+
box_stack.append(item.bbox)
|
|
924
|
+
category_names_list.append(item.category_name.value)
|
|
925
|
+
|
|
861
926
|
if show_tables and not debug_kwargs:
|
|
862
927
|
for table in self.tables:
|
|
863
928
|
box_stack.append(table.bbox)
|
|
@@ -914,24 +979,34 @@ class Page(Image):
|
|
|
914
979
|
else:
|
|
915
980
|
category_names_list.append(word.token_tag.value if word.token_tag is not None else None)
|
|
916
981
|
|
|
982
|
+
if show_residual_layouts and not debug_kwargs:
|
|
983
|
+
for item in self.residual_layouts:
|
|
984
|
+
box_stack.append(item.bbox)
|
|
985
|
+
category_names_list.append(item.category_name.value)
|
|
986
|
+
|
|
917
987
|
if self.image is not None:
|
|
988
|
+
scale_fx = scaled_width / self.width
|
|
989
|
+
scaled_height = int(self.height * scale_fx)
|
|
990
|
+
img = viz_handler.resize(self.image, scaled_width, scaled_height, "VIZ")
|
|
991
|
+
|
|
918
992
|
if box_stack:
|
|
919
993
|
boxes = np.vstack(box_stack)
|
|
994
|
+
boxes = box_to_point4(boxes)
|
|
995
|
+
resizer = ResizeTransform(self.height, self.width, scaled_height, scaled_width, "VIZ")
|
|
996
|
+
boxes = resizer.apply_coords(boxes)
|
|
997
|
+
boxes = point4_to_box(boxes)
|
|
920
998
|
if show_words:
|
|
921
999
|
img = draw_boxes(
|
|
922
|
-
|
|
923
|
-
boxes,
|
|
924
|
-
category_names_list,
|
|
1000
|
+
np_image=img,
|
|
1001
|
+
boxes=boxes,
|
|
1002
|
+
category_names_list=category_names_list,
|
|
925
1003
|
font_scale=1.0,
|
|
926
1004
|
rectangle_thickness=4,
|
|
927
1005
|
)
|
|
928
1006
|
else:
|
|
929
|
-
img = draw_boxes(
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
img = viz_handler.resize(img, scaled_width, scaled_height, "VIZ")
|
|
933
|
-
else:
|
|
934
|
-
img = self.image
|
|
1007
|
+
img = draw_boxes(
|
|
1008
|
+
np_image=img, boxes=boxes, category_names_list=category_names_list, show_palette=False
|
|
1009
|
+
)
|
|
935
1010
|
|
|
936
1011
|
if interactive:
|
|
937
1012
|
interactive_imshow(img)
|
|
@@ -71,8 +71,8 @@ https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/cocoeva
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def _summarize( # type: ignore
|
|
74
|
-
self, ap: int = 1, iouThr: float = 0.9, areaRng: str = "all", maxDets: int = 100
|
|
75
|
-
) -> float:
|
|
74
|
+
self, ap: int = 1, iouThr: float = 0.9, areaRng: str = "all", maxDets: int = 100, per_category: bool = False
|
|
75
|
+
) -> Union[float, list[float]]:
|
|
76
76
|
# pylint: disable=C0103
|
|
77
77
|
p = self.params
|
|
78
78
|
iStr = " {:<18} {} @[ IoU={:<9} | area={:>6s} | maxDets={:>3d} ] = {:0.3f}"
|
|
@@ -86,6 +86,36 @@ def _summarize( # type: ignore
|
|
|
86
86
|
|
|
87
87
|
aind = [i for i, aRng in enumerate(p.areaRngLbl) if aRng == areaRng]
|
|
88
88
|
mind = [i for i, mDet in enumerate(p.maxDets) if mDet == maxDets]
|
|
89
|
+
if per_category:
|
|
90
|
+
if ap == 1:
|
|
91
|
+
s = self.eval["precision"]
|
|
92
|
+
num_classes = s.shape[2]
|
|
93
|
+
results_per_class = []
|
|
94
|
+
for idx in range(num_classes):
|
|
95
|
+
if iouThr is not None:
|
|
96
|
+
s = self.eval["precision"]
|
|
97
|
+
t = np.where(iouThr == p.iouThrs)[0]
|
|
98
|
+
s = s[t]
|
|
99
|
+
precision = s[:, :, idx, aind, mind]
|
|
100
|
+
precision = precision[precision > -1]
|
|
101
|
+
res = np.mean(precision) if precision.size else float("nan")
|
|
102
|
+
results_per_class.append(float(res))
|
|
103
|
+
print(f"Precision for class {idx+1}: @[ IoU={iouStr} | area={areaRng} | maxDets={maxDets} ] = {res}")
|
|
104
|
+
else:
|
|
105
|
+
s = self.eval["recall"]
|
|
106
|
+
num_classes = s.shape[1]
|
|
107
|
+
results_per_class = []
|
|
108
|
+
for idx in range(num_classes):
|
|
109
|
+
if iouThr is not None:
|
|
110
|
+
s = self.eval["recall"]
|
|
111
|
+
t = np.where(iouThr == p.iouThrs)[0]
|
|
112
|
+
s = s[t]
|
|
113
|
+
recall = s[:, idx, aind, mind]
|
|
114
|
+
recall = recall[recall > -1]
|
|
115
|
+
res = np.mean(recall) if recall.size else float("nan")
|
|
116
|
+
results_per_class.append(float(res))
|
|
117
|
+
print(f"Recall for class {idx+1}: @[ IoU={iouStr} | area={areaRng} | maxDets={maxDets} ] = {res}")
|
|
118
|
+
return results_per_class
|
|
89
119
|
if ap == 1:
|
|
90
120
|
# dimension of precision: [TxRxKxAxM]
|
|
91
121
|
s = self.eval["precision"]
|
|
@@ -124,6 +154,7 @@ class CocoMetric(MetricBase):
|
|
|
124
154
|
mapper = image_to_coco
|
|
125
155
|
_f1_score = None
|
|
126
156
|
_f1_iou = None
|
|
157
|
+
_per_category = False
|
|
127
158
|
_params: dict[str, Union[list[int], list[list[int]]]] = {}
|
|
128
159
|
|
|
129
160
|
@classmethod
|
|
@@ -176,18 +207,28 @@ class CocoMetric(MetricBase):
|
|
|
176
207
|
|
|
177
208
|
if cls._f1_score:
|
|
178
209
|
summary_bbox = [
|
|
179
|
-
metric.summarize_f1(1, cls._f1_iou, maxDets=metric.params.maxDets[2]),
|
|
180
|
-
metric.summarize_f1(0, cls._f1_iou, maxDets=metric.params.maxDets[2]),
|
|
210
|
+
metric.summarize_f1(1, cls._f1_iou, maxDets=metric.params.maxDets[2], per_category=cls._per_category),
|
|
211
|
+
metric.summarize_f1(0, cls._f1_iou, maxDets=metric.params.maxDets[2], per_category=cls._per_category),
|
|
181
212
|
]
|
|
182
213
|
else:
|
|
183
214
|
metric.summarize()
|
|
184
215
|
summary_bbox = metric.stats
|
|
185
216
|
|
|
186
217
|
results = []
|
|
187
|
-
|
|
218
|
+
|
|
219
|
+
default_parameters = cls.get_summary_default_parameters()
|
|
220
|
+
if cls._per_category:
|
|
221
|
+
default_parameters = default_parameters * len(summary_bbox[0])
|
|
222
|
+
summary_bbox = [item for pair in zip(*summary_bbox) for item in pair]
|
|
223
|
+
val = 0
|
|
224
|
+
for idx, (params, value) in enumerate(zip(default_parameters, summary_bbox)):
|
|
188
225
|
params = copy(params)
|
|
189
226
|
params["mode"] = "bbox"
|
|
190
227
|
params["val"] = value
|
|
228
|
+
if cls._per_category:
|
|
229
|
+
if idx % 2 == 0:
|
|
230
|
+
val += 1
|
|
231
|
+
params["category_id"] = val
|
|
191
232
|
results.append(params)
|
|
192
233
|
|
|
193
234
|
return results
|
|
@@ -201,15 +242,16 @@ class CocoMetric(MetricBase):
|
|
|
201
242
|
area range and maximum detections.
|
|
202
243
|
"""
|
|
203
244
|
if cls._f1_score:
|
|
245
|
+
for el, idx in zip(_F1_DEFAULTS, [2, 2]):
|
|
246
|
+
if cls._params:
|
|
247
|
+
if cls._params.get("maxDets") is not None:
|
|
248
|
+
el["maxDets"] = cls._params["maxDets"][idx]
|
|
249
|
+
el["iouThr"] = cls._f1_iou
|
|
250
|
+
return _F1_DEFAULTS
|
|
251
|
+
|
|
252
|
+
for el, idx in zip(_COCOEVAL_DEFAULTS, _MAX_DET_INDEX):
|
|
204
253
|
if cls._params:
|
|
205
254
|
if cls._params.get("maxDets") is not None:
|
|
206
|
-
for el, idx in zip(_F1_DEFAULTS, [2, 2]):
|
|
207
|
-
el["maxDets"] = cls._params["maxDets"][idx]
|
|
208
|
-
el["iouThr"] = cls._f1_iou
|
|
209
|
-
return _F1_DEFAULTS
|
|
210
|
-
if cls._params:
|
|
211
|
-
if cls._params.get("maxDets") is not None:
|
|
212
|
-
for el, idx in zip(_COCOEVAL_DEFAULTS, _MAX_DET_INDEX):
|
|
213
255
|
el["maxDets"] = cls._params["maxDets"][idx]
|
|
214
256
|
return _COCOEVAL_DEFAULTS
|
|
215
257
|
|
|
@@ -220,13 +262,16 @@ class CocoMetric(MetricBase):
|
|
|
220
262
|
area_range: Optional[list[list[int]]] = None,
|
|
221
263
|
f1_score: bool = False,
|
|
222
264
|
f1_iou: float = 0.9,
|
|
265
|
+
per_category: bool = False,
|
|
223
266
|
) -> None:
|
|
224
267
|
"""
|
|
225
268
|
Setting params for different coco metric modes.
|
|
226
269
|
|
|
227
270
|
:param max_detections: The maximum number of detections to consider
|
|
228
271
|
:param area_range: The area range to classify objects as "all", "small", "medium" and "large"
|
|
229
|
-
:param f1_score: Will use f1 score setting with default iouThr 0.9
|
|
272
|
+
:param f1_score: Will use f1 score setting with default iouThr 0.9. To be more precise it does not calculate
|
|
273
|
+
the f1 score but the precision and recall for a given iou threshold. Use the harmonic mean to
|
|
274
|
+
get the ultimate f1 score.
|
|
230
275
|
:param f1_iou: Use with f1_score True and reset the f1 iou threshold
|
|
231
276
|
"""
|
|
232
277
|
if max_detections is not None:
|
|
@@ -238,6 +283,7 @@ class CocoMetric(MetricBase):
|
|
|
238
283
|
|
|
239
284
|
cls._f1_score = f1_score
|
|
240
285
|
cls._f1_iou = f1_iou
|
|
286
|
+
cls._per_category = per_category
|
|
241
287
|
|
|
242
288
|
@classmethod
|
|
243
289
|
def get_requirements(cls) -> list[Requirement]:
|
deepdoctection/mapper/match.py
CHANGED
|
@@ -193,5 +193,7 @@ def match_anns_by_distance(
|
|
|
193
193
|
child_anns = dp.get_annotation(annotation_ids=child_ann_ids, category_names=child_ann_category_names)
|
|
194
194
|
child_centers = [block.get_bounding_box(dp.image_id).center for block in child_anns]
|
|
195
195
|
parent_centers = [block.get_bounding_box(dp.image_id).center for block in parent_anns]
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
if child_centers and parent_centers:
|
|
197
|
+
child_indices = distance.cdist(parent_centers, child_centers).argmin(axis=1)
|
|
198
|
+
return [(parent_anns[i], child_anns[j]) for i, j in enumerate(child_indices)]
|
|
199
|
+
return []
|
deepdoctection/utils/utils.py
CHANGED
|
@@ -155,3 +155,42 @@ def is_file_extension(file_name: PathLikeOrStr, extension: Union[str, Sequence[s
|
|
|
155
155
|
if isinstance(extension, str):
|
|
156
156
|
return os.path.splitext(file_name)[-1].lower() == extension
|
|
157
157
|
return os.path.splitext(file_name)[-1].lower() in extension
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def partition_list(base_list: list[str], stop_value: str) -> list[list[str]]:
|
|
161
|
+
"""
|
|
162
|
+
Partitions a list of strings into sublists, where each sublist starts with the first occurrence of the stop value.
|
|
163
|
+
Consecutive stop values are grouped together in the same sublist.
|
|
164
|
+
|
|
165
|
+
:param base_list: The list of strings to be partitioned.
|
|
166
|
+
:param stop_value: The string value that indicates the start of a new partition.
|
|
167
|
+
:return: A list of lists, where each sublist is a partition of the original list.
|
|
168
|
+
|
|
169
|
+
** Example:**
|
|
170
|
+
|
|
171
|
+
strings = ['a', 'a', 'c', 'c', 'b', 'd', 'c', 'c', 'a', 'b', 'a', 'b', 'a', 'a']
|
|
172
|
+
stop_string = 'a'
|
|
173
|
+
partition_list(strings, stop_string)
|
|
174
|
+
|
|
175
|
+
# Output [['a', 'a', 'c', 'c', 'b', 'd', 'c', 'c'], ['a', 'b'], ['a', 'b'], ['a', 'a']]
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
partitions = []
|
|
179
|
+
current_partition: list[str] = []
|
|
180
|
+
stop_found = False
|
|
181
|
+
|
|
182
|
+
for s in base_list:
|
|
183
|
+
if s == stop_value:
|
|
184
|
+
if not stop_found and current_partition:
|
|
185
|
+
partitions.append(current_partition)
|
|
186
|
+
current_partition = []
|
|
187
|
+
current_partition.append(s)
|
|
188
|
+
stop_found = True
|
|
189
|
+
else:
|
|
190
|
+
current_partition.append(s)
|
|
191
|
+
stop_found = False
|
|
192
|
+
|
|
193
|
+
if current_partition:
|
|
194
|
+
partitions.append(current_partition)
|
|
195
|
+
|
|
196
|
+
return partitions
|
deepdoctection/utils/viz.py
CHANGED
|
@@ -205,6 +205,7 @@ def draw_boxes(
|
|
|
205
205
|
font_scale: float = 1.0,
|
|
206
206
|
rectangle_thickness: int = 4,
|
|
207
207
|
box_color_by_category: bool = True,
|
|
208
|
+
show_palette: bool = True,
|
|
208
209
|
) -> PixelValues:
|
|
209
210
|
"""
|
|
210
211
|
Dray bounding boxes with category names into image.
|
|
@@ -216,6 +217,7 @@ def draw_boxes(
|
|
|
216
217
|
:param font_scale: Font scale of text box
|
|
217
218
|
:param rectangle_thickness: Thickness of bounding box
|
|
218
219
|
:param box_color_by_category:
|
|
220
|
+
:param show_palette: Whether to show a color palette of the categories
|
|
219
221
|
:return: A new image np.ndarray
|
|
220
222
|
"""
|
|
221
223
|
if color is not None:
|
|
@@ -261,19 +263,20 @@ def draw_boxes(
|
|
|
261
263
|
)
|
|
262
264
|
|
|
263
265
|
# draw a (very ugly) color palette
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
np_image
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
266
|
+
if show_palette:
|
|
267
|
+
y_0 = np_image.shape[0]
|
|
268
|
+
for category, col in category_to_color.items():
|
|
269
|
+
if category is not None:
|
|
270
|
+
np_image = viz_handler.draw_text(
|
|
271
|
+
np_image,
|
|
272
|
+
(np_image.shape[1], y_0),
|
|
273
|
+
category,
|
|
274
|
+
color=col,
|
|
275
|
+
font_scale=font_scale,
|
|
276
|
+
rectangle_thickness=rectangle_thickness,
|
|
277
|
+
)
|
|
278
|
+
_, text_h = viz_handler.get_text_size(category, font_scale * 2)
|
|
279
|
+
y_0 = y_0 - int(1 * text_h)
|
|
277
280
|
|
|
278
281
|
return np_image
|
|
279
282
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: deepdoctection
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.36
|
|
4
4
|
Summary: Repository for Document AI
|
|
5
5
|
Home-page: https://github.com/deepdoctection/deepdoctection
|
|
6
6
|
Author: Dr. Janis Meyer
|
|
@@ -16,117 +16,117 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: catalogue
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist: importlib-metadata
|
|
22
|
-
Requires-Dist: jsonlines
|
|
23
|
-
Requires-Dist: lazy-imports
|
|
24
|
-
Requires-Dist: mock
|
|
25
|
-
Requires-Dist: networkx
|
|
26
|
-
Requires-Dist: numpy
|
|
27
|
-
Requires-Dist: packaging
|
|
28
|
-
Requires-Dist: Pillow
|
|
29
|
-
Requires-Dist: pypdf
|
|
30
|
-
Requires-Dist: pypdfium2
|
|
31
|
-
Requires-Dist: pyyaml
|
|
32
|
-
Requires-Dist: pyzmq
|
|
33
|
-
Requires-Dist: scipy
|
|
34
|
-
Requires-Dist: termcolor
|
|
35
|
-
Requires-Dist: tabulate
|
|
36
|
-
Requires-Dist: tqdm
|
|
37
|
-
Provides-Extra:
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist:
|
|
41
|
-
Requires-Dist:
|
|
42
|
-
Requires-Dist:
|
|
43
|
-
Requires-Dist:
|
|
44
|
-
Requires-Dist:
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist:
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist:
|
|
52
|
-
|
|
53
|
-
Requires-Dist:
|
|
54
|
-
Requires-Dist:
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist:
|
|
57
|
-
Requires-Dist:
|
|
58
|
-
Requires-Dist:
|
|
59
|
-
Requires-Dist:
|
|
60
|
-
Requires-Dist:
|
|
61
|
-
Requires-Dist:
|
|
62
|
-
Requires-Dist:
|
|
63
|
-
Requires-Dist:
|
|
64
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: catalogue==2.0.10
|
|
20
|
+
Requires-Dist: huggingface_hub<0.26,>=0.12.0
|
|
21
|
+
Requires-Dist: importlib-metadata>=5.0.0
|
|
22
|
+
Requires-Dist: jsonlines==3.1.0
|
|
23
|
+
Requires-Dist: lazy-imports==0.3.1
|
|
24
|
+
Requires-Dist: mock==4.0.3
|
|
25
|
+
Requires-Dist: networkx>=2.7.1
|
|
26
|
+
Requires-Dist: numpy<2.0,>=1.21
|
|
27
|
+
Requires-Dist: packaging>=20.0
|
|
28
|
+
Requires-Dist: Pillow>=10.0.0
|
|
29
|
+
Requires-Dist: pypdf>=3.16.0
|
|
30
|
+
Requires-Dist: pypdfium2>=4.30.0
|
|
31
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
32
|
+
Requires-Dist: pyzmq>=16
|
|
33
|
+
Requires-Dist: scipy>=1.13.1
|
|
34
|
+
Requires-Dist: termcolor>=1.1
|
|
35
|
+
Requires-Dist: tabulate>=0.7.7
|
|
36
|
+
Requires-Dist: tqdm==4.64.0
|
|
37
|
+
Provides-Extra: tf
|
|
38
|
+
Requires-Dist: catalogue==2.0.10; extra == "tf"
|
|
39
|
+
Requires-Dist: huggingface_hub<0.26,>=0.12.0; extra == "tf"
|
|
40
|
+
Requires-Dist: importlib-metadata>=5.0.0; extra == "tf"
|
|
41
|
+
Requires-Dist: jsonlines==3.1.0; extra == "tf"
|
|
42
|
+
Requires-Dist: lazy-imports==0.3.1; extra == "tf"
|
|
43
|
+
Requires-Dist: mock==4.0.3; extra == "tf"
|
|
44
|
+
Requires-Dist: networkx>=2.7.1; extra == "tf"
|
|
45
|
+
Requires-Dist: numpy<2.0,>=1.21; extra == "tf"
|
|
46
|
+
Requires-Dist: packaging>=20.0; extra == "tf"
|
|
47
|
+
Requires-Dist: Pillow>=10.0.0; extra == "tf"
|
|
48
|
+
Requires-Dist: pypdf>=3.16.0; extra == "tf"
|
|
49
|
+
Requires-Dist: pypdfium2>=4.30.0; extra == "tf"
|
|
50
|
+
Requires-Dist: pyyaml>=6.0.1; extra == "tf"
|
|
51
|
+
Requires-Dist: pyzmq>=16; extra == "tf"
|
|
52
|
+
Requires-Dist: scipy>=1.13.1; extra == "tf"
|
|
53
|
+
Requires-Dist: termcolor>=1.1; extra == "tf"
|
|
54
|
+
Requires-Dist: tabulate>=0.7.7; extra == "tf"
|
|
55
|
+
Requires-Dist: tqdm==4.64.0; extra == "tf"
|
|
56
|
+
Requires-Dist: tensorpack==0.11; extra == "tf"
|
|
57
|
+
Requires-Dist: protobuf==3.20.1; extra == "tf"
|
|
58
|
+
Requires-Dist: tensorflow-addons>=0.17.1; extra == "tf"
|
|
59
|
+
Requires-Dist: tf2onnx>=1.9.2; extra == "tf"
|
|
60
|
+
Requires-Dist: python-doctr==0.8.1; extra == "tf"
|
|
61
|
+
Requires-Dist: pycocotools>=2.0.2; extra == "tf"
|
|
62
|
+
Requires-Dist: boto3==1.34.102; extra == "tf"
|
|
63
|
+
Requires-Dist: pdfplumber>=0.11.0; extra == "tf"
|
|
64
|
+
Requires-Dist: fasttext==0.9.2; extra == "tf"
|
|
65
|
+
Requires-Dist: jdeskew>=0.2.2; extra == "tf"
|
|
66
|
+
Requires-Dist: apted==1.0.3; extra == "tf"
|
|
67
|
+
Requires-Dist: distance==0.1.3; extra == "tf"
|
|
68
|
+
Requires-Dist: lxml>=4.9.1; extra == "tf"
|
|
65
69
|
Provides-Extra: pt
|
|
66
|
-
Requires-Dist: catalogue
|
|
67
|
-
Requires-Dist:
|
|
68
|
-
Requires-Dist: importlib-metadata
|
|
69
|
-
Requires-Dist: jsonlines
|
|
70
|
-
Requires-Dist: lazy-imports
|
|
71
|
-
Requires-Dist: mock
|
|
72
|
-
Requires-Dist: networkx
|
|
73
|
-
Requires-Dist: numpy
|
|
74
|
-
Requires-Dist: packaging
|
|
75
|
-
Requires-Dist: Pillow
|
|
76
|
-
Requires-Dist: pypdf
|
|
77
|
-
Requires-Dist: pypdfium2
|
|
78
|
-
Requires-Dist: pyyaml
|
|
79
|
-
Requires-Dist: pyzmq
|
|
80
|
-
Requires-Dist: scipy
|
|
81
|
-
Requires-Dist: termcolor
|
|
82
|
-
Requires-Dist: tabulate
|
|
83
|
-
Requires-Dist: tqdm
|
|
84
|
-
Requires-Dist: timm
|
|
85
|
-
Requires-Dist: transformers
|
|
86
|
-
Requires-Dist: accelerate
|
|
87
|
-
Requires-Dist: python-doctr
|
|
88
|
-
Requires-Dist: boto3
|
|
89
|
-
Requires-Dist: pdfplumber
|
|
90
|
-
Requires-Dist: fasttext
|
|
91
|
-
Requires-Dist: jdeskew
|
|
92
|
-
Requires-Dist: apted
|
|
93
|
-
Requires-Dist: distance
|
|
94
|
-
Requires-Dist: lxml
|
|
70
|
+
Requires-Dist: catalogue==2.0.10; extra == "pt"
|
|
71
|
+
Requires-Dist: huggingface_hub<0.26,>=0.12.0; extra == "pt"
|
|
72
|
+
Requires-Dist: importlib-metadata>=5.0.0; extra == "pt"
|
|
73
|
+
Requires-Dist: jsonlines==3.1.0; extra == "pt"
|
|
74
|
+
Requires-Dist: lazy-imports==0.3.1; extra == "pt"
|
|
75
|
+
Requires-Dist: mock==4.0.3; extra == "pt"
|
|
76
|
+
Requires-Dist: networkx>=2.7.1; extra == "pt"
|
|
77
|
+
Requires-Dist: numpy<2.0,>=1.21; extra == "pt"
|
|
78
|
+
Requires-Dist: packaging>=20.0; extra == "pt"
|
|
79
|
+
Requires-Dist: Pillow>=10.0.0; extra == "pt"
|
|
80
|
+
Requires-Dist: pypdf>=3.16.0; extra == "pt"
|
|
81
|
+
Requires-Dist: pypdfium2>=4.30.0; extra == "pt"
|
|
82
|
+
Requires-Dist: pyyaml>=6.0.1; extra == "pt"
|
|
83
|
+
Requires-Dist: pyzmq>=16; extra == "pt"
|
|
84
|
+
Requires-Dist: scipy>=1.13.1; extra == "pt"
|
|
85
|
+
Requires-Dist: termcolor>=1.1; extra == "pt"
|
|
86
|
+
Requires-Dist: tabulate>=0.7.7; extra == "pt"
|
|
87
|
+
Requires-Dist: tqdm==4.64.0; extra == "pt"
|
|
88
|
+
Requires-Dist: timm>=0.9.16; extra == "pt"
|
|
89
|
+
Requires-Dist: transformers>=4.36.0; extra == "pt"
|
|
90
|
+
Requires-Dist: accelerate>=0.29.1; extra == "pt"
|
|
91
|
+
Requires-Dist: python-doctr==0.8.1; extra == "pt"
|
|
92
|
+
Requires-Dist: boto3==1.34.102; extra == "pt"
|
|
93
|
+
Requires-Dist: pdfplumber>=0.11.0; extra == "pt"
|
|
94
|
+
Requires-Dist: fasttext==0.9.2; extra == "pt"
|
|
95
|
+
Requires-Dist: jdeskew>=0.2.2; extra == "pt"
|
|
96
|
+
Requires-Dist: apted==1.0.3; extra == "pt"
|
|
97
|
+
Requires-Dist: distance==0.1.3; extra == "pt"
|
|
98
|
+
Requires-Dist: lxml>=4.9.1; extra == "pt"
|
|
99
|
+
Provides-Extra: docs
|
|
100
|
+
Requires-Dist: tensorpack==0.11; extra == "docs"
|
|
101
|
+
Requires-Dist: boto3==1.34.102; extra == "docs"
|
|
102
|
+
Requires-Dist: transformers>=4.36.0; extra == "docs"
|
|
103
|
+
Requires-Dist: accelerate>=0.29.1; extra == "docs"
|
|
104
|
+
Requires-Dist: pdfplumber>=0.11.0; extra == "docs"
|
|
105
|
+
Requires-Dist: lxml>=4.9.1; extra == "docs"
|
|
106
|
+
Requires-Dist: lxml-stubs>=0.5.1; extra == "docs"
|
|
107
|
+
Requires-Dist: jdeskew>=0.2.2; extra == "docs"
|
|
108
|
+
Requires-Dist: jinja2==3.0.3; extra == "docs"
|
|
109
|
+
Requires-Dist: mkdocs-material; extra == "docs"
|
|
110
|
+
Requires-Dist: mkdocstrings-python; extra == "docs"
|
|
111
|
+
Requires-Dist: griffe==0.25.0; extra == "docs"
|
|
112
|
+
Provides-Extra: dev
|
|
113
|
+
Requires-Dist: python-dotenv==1.0.0; extra == "dev"
|
|
114
|
+
Requires-Dist: click; extra == "dev"
|
|
115
|
+
Requires-Dist: black==23.7.0; extra == "dev"
|
|
116
|
+
Requires-Dist: isort==5.13.2; extra == "dev"
|
|
117
|
+
Requires-Dist: pylint==2.17.4; extra == "dev"
|
|
118
|
+
Requires-Dist: mypy==1.4.1; extra == "dev"
|
|
119
|
+
Requires-Dist: wandb; extra == "dev"
|
|
120
|
+
Requires-Dist: types-PyYAML>=6.0.12.12; extra == "dev"
|
|
121
|
+
Requires-Dist: types-termcolor>=1.1.3; extra == "dev"
|
|
122
|
+
Requires-Dist: types-tabulate>=0.9.0.3; extra == "dev"
|
|
123
|
+
Requires-Dist: types-tqdm>=4.66.0.5; extra == "dev"
|
|
124
|
+
Requires-Dist: lxml-stubs>=0.5.1; extra == "dev"
|
|
125
|
+
Requires-Dist: types-Pillow>=10.2.0.20240406; extra == "dev"
|
|
126
|
+
Requires-Dist: types-urllib3>=1.26.25.14; extra == "dev"
|
|
95
127
|
Provides-Extra: test
|
|
96
|
-
Requires-Dist: pytest
|
|
97
|
-
Requires-Dist: pytest-cov
|
|
98
|
-
Provides-Extra: tf
|
|
99
|
-
Requires-Dist: catalogue ==2.0.10 ; extra == 'tf'
|
|
100
|
-
Requires-Dist: huggingface-hub <0.26,>=0.12.0 ; extra == 'tf'
|
|
101
|
-
Requires-Dist: importlib-metadata >=5.0.0 ; extra == 'tf'
|
|
102
|
-
Requires-Dist: jsonlines ==3.1.0 ; extra == 'tf'
|
|
103
|
-
Requires-Dist: lazy-imports ==0.3.1 ; extra == 'tf'
|
|
104
|
-
Requires-Dist: mock ==4.0.3 ; extra == 'tf'
|
|
105
|
-
Requires-Dist: networkx >=2.7.1 ; extra == 'tf'
|
|
106
|
-
Requires-Dist: numpy <2.0,>=1.21 ; extra == 'tf'
|
|
107
|
-
Requires-Dist: packaging >=20.0 ; extra == 'tf'
|
|
108
|
-
Requires-Dist: Pillow >=10.0.0 ; extra == 'tf'
|
|
109
|
-
Requires-Dist: pypdf >=3.16.0 ; extra == 'tf'
|
|
110
|
-
Requires-Dist: pypdfium2 >=4.30.0 ; extra == 'tf'
|
|
111
|
-
Requires-Dist: pyyaml >=6.0.1 ; extra == 'tf'
|
|
112
|
-
Requires-Dist: pyzmq >=16 ; extra == 'tf'
|
|
113
|
-
Requires-Dist: scipy >=1.13.1 ; extra == 'tf'
|
|
114
|
-
Requires-Dist: termcolor >=1.1 ; extra == 'tf'
|
|
115
|
-
Requires-Dist: tabulate >=0.7.7 ; extra == 'tf'
|
|
116
|
-
Requires-Dist: tqdm ==4.64.0 ; extra == 'tf'
|
|
117
|
-
Requires-Dist: tensorpack ==0.11 ; extra == 'tf'
|
|
118
|
-
Requires-Dist: protobuf ==3.20.1 ; extra == 'tf'
|
|
119
|
-
Requires-Dist: tensorflow-addons >=0.17.1 ; extra == 'tf'
|
|
120
|
-
Requires-Dist: tf2onnx >=1.9.2 ; extra == 'tf'
|
|
121
|
-
Requires-Dist: python-doctr ==0.8.1 ; extra == 'tf'
|
|
122
|
-
Requires-Dist: pycocotools >=2.0.2 ; extra == 'tf'
|
|
123
|
-
Requires-Dist: boto3 ==1.34.102 ; extra == 'tf'
|
|
124
|
-
Requires-Dist: pdfplumber >=0.11.0 ; extra == 'tf'
|
|
125
|
-
Requires-Dist: fasttext ==0.9.2 ; extra == 'tf'
|
|
126
|
-
Requires-Dist: jdeskew >=0.2.2 ; extra == 'tf'
|
|
127
|
-
Requires-Dist: apted ==1.0.3 ; extra == 'tf'
|
|
128
|
-
Requires-Dist: distance ==0.1.3 ; extra == 'tf'
|
|
129
|
-
Requires-Dist: lxml >=4.9.1 ; extra == 'tf'
|
|
128
|
+
Requires-Dist: pytest==8.0.2; extra == "test"
|
|
129
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
<p align="center">
|
|
@@ -176,12 +176,16 @@ pipelines. Its core function does not depend on any specific deep learning libra
|
|
|
176
176
|
[**Torchscript**](https://pytorch.org/docs/stable/jit.html) (CPU) as well and [**Detectron2**](https://github.com/facebookresearch/detectron2/tree/main/detectron2) is not required
|
|
177
177
|
anymore for basic inference.
|
|
178
178
|
- More angle predictors for determining the rotation of a document based on [**Tesseract**](https://github.com/tesseract-ocr/tesseract) and [**DocTr**](https://github.com/mindee/doctr)
|
|
179
|
-
(not contained in the built-in Analyzer).
|
|
180
179
|
- Token classification with [**LiLT**](https://github.com/jpWang/LiLT) via
|
|
181
180
|
[**transformers**](https://github.com/huggingface/transformers).
|
|
182
181
|
We have added a model wrapper for token classification with LiLT and added a some LiLT models to the model catalog
|
|
183
182
|
that seem to look promising, especially if you want to train a model on non-english data. The training script for
|
|
184
|
-
LayoutLM can be used for LiLT as well
|
|
183
|
+
LayoutLM can be used for LiLT as well.
|
|
184
|
+
- [**new**] There are two notebooks available that show, how to write a
|
|
185
|
+
[custom predictor](https://github.com/deepdoctection/notebooks/blob/main/Doclaynet_Analyzer_Config.ipynb) based on
|
|
186
|
+
a third party library that has not been supported yet and how to use
|
|
187
|
+
[advanced configuration](https://github.com/deepdoctection/notebooks/blob/main/Doclaynet_Analyzer_Config.ipynb) to
|
|
188
|
+
get links between layout segments e.g. captions and tables or figures.
|
|
185
189
|
|
|
186
190
|
**deep**doctection provides on top of that methods for pre-processing inputs to models like cropping or resizing and to
|
|
187
191
|
post-process results, like validating duplicate outputs, relating words to detected layout segments or ordering words
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
deepdoctection/__init__.py,sha256=
|
|
1
|
+
deepdoctection/__init__.py,sha256=fNUbaFAlK1JUXgPCmTu2UOLUMqW4HIgkaW4uOUYjYYg,12571
|
|
2
2
|
deepdoctection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
deepdoctection/analyzer/__init__.py,sha256=icClxrd20XutD6LxLgEPIWceSs4j_QfI3szCE-9BL2w,729
|
|
4
|
-
deepdoctection/analyzer/_config.py,sha256=
|
|
4
|
+
deepdoctection/analyzer/_config.py,sha256=NZl_REM8Ge2xfxvHN-mZR5KURcHfZii3xfMlKQwckbA,4864
|
|
5
5
|
deepdoctection/analyzer/dd.py,sha256=DUOhOtwipHw5nabYqn3WGR9aZcgP0ma_bi_tjf9xscw,5973
|
|
6
|
-
deepdoctection/analyzer/factory.py,sha256=
|
|
6
|
+
deepdoctection/analyzer/factory.py,sha256=xmo5F9X7I6lp0ZWJv8QavpMyG8UWYLvMi4qogsZV1_s,31507
|
|
7
7
|
deepdoctection/configs/__init__.py,sha256=TX_P6tqDOF1LK1mi9ruAl7x0mtv1Asm8cYWCz3Pe2dk,646
|
|
8
|
-
deepdoctection/configs/conf_dd_one.yaml,sha256=
|
|
8
|
+
deepdoctection/configs/conf_dd_one.yaml,sha256=td7XsyVhdXkhh5Pie7sT_WNjGTaxBOWgpxhkobHd1H0,2325
|
|
9
9
|
deepdoctection/configs/conf_tesseract.yaml,sha256=oF6szDyoi15FHvq7yFUNIEjfA_jNLhGxoowiRsz_zY4,35
|
|
10
10
|
deepdoctection/dataflow/__init__.py,sha256=CWRHMpmJaPk4xY_oIIFubCt-z11SguWrMWxHZ7rdrvY,845
|
|
11
11
|
deepdoctection/dataflow/base.py,sha256=z4DCComSj5wStEPjtk0093cNNGfUMiDqx8dqz36nS_o,6221
|
|
@@ -20,7 +20,7 @@ deepdoctection/datapoint/annotation.py,sha256=FEgz4COxVDfjic0gG7kS6iHnWLBIgFnquQ
|
|
|
20
20
|
deepdoctection/datapoint/box.py,sha256=tkFuVM6xfx2jL7W4UED4qHXV572LSRdIsVJbrEiyIxI,23524
|
|
21
21
|
deepdoctection/datapoint/convert.py,sha256=Gw2IjNiEotPu1yuMZqrIYB0mCAwafKt-VgMnrHj6S7U,6808
|
|
22
22
|
deepdoctection/datapoint/image.py,sha256=EvZlVwJjMAcL1z8RNPBvZ8fwdJvkGuGpcFxCP1y26Go,33045
|
|
23
|
-
deepdoctection/datapoint/view.py,sha256=
|
|
23
|
+
deepdoctection/datapoint/view.py,sha256=1rVMuqucCrI5zlwyXMADJQBV38V_zSNFqFyBi3cMA1E,44914
|
|
24
24
|
deepdoctection/datasets/__init__.py,sha256=-A3aR90aDsHPmVM35JavfnQ2itYSCn3ujl4krRni1QU,1076
|
|
25
25
|
deepdoctection/datasets/adapter.py,sha256=Ly_vbOAgVI73V41FUccnSX1ECTOyesW_qsuvQuvOZbw,7796
|
|
26
26
|
deepdoctection/datasets/base.py,sha256=DT4i-d74sIEiUNC6UspIHNJuHSK0t1dBv7qwadg4rLw,22341
|
|
@@ -44,7 +44,7 @@ deepdoctection/datasets/instances/xsl/pascal_voc.xsl,sha256=DlzFV2P8NtQKXVe96i-m
|
|
|
44
44
|
deepdoctection/eval/__init__.py,sha256=rbns4tSEQ30QLj8h0mm3A0dCaKuN9LDxxpVypKKSXSE,932
|
|
45
45
|
deepdoctection/eval/accmetric.py,sha256=4bND-xz9AZu9ACYRkEzn9V6Jn8MEiqnF7kxSp4k_baE,19655
|
|
46
46
|
deepdoctection/eval/base.py,sha256=gCvhTdwEaCKplYTWPMjGvtB_0Vbq2KBJWFHq8mMlLPA,4814
|
|
47
|
-
deepdoctection/eval/cocometric.py,sha256=
|
|
47
|
+
deepdoctection/eval/cocometric.py,sha256=4cpNmF3xZjInCOWOoVU_7itQxLI-zr0O6suNjPU2xWc,11020
|
|
48
48
|
deepdoctection/eval/eval.py,sha256=B9PUZBjj6KzXHLOxUVn3QHiOcBQogfJmp9mjopbMo9k,19721
|
|
49
49
|
deepdoctection/eval/registry.py,sha256=v4mp-s67vBVRu1nQzuGlYPViQnMSeIXEcF_WmvfUCoU,1051
|
|
50
50
|
deepdoctection/eval/tedsmetric.py,sha256=rKw-734Y9CpBtIfkBSPQF2vAZxnIdWrI9Zc723P7RxI,9529
|
|
@@ -94,7 +94,7 @@ deepdoctection/mapper/d2struct.py,sha256=Dx-YnycsIQH4a5-9Gn_yMhiQ-gOFgMueNeH3rhX
|
|
|
94
94
|
deepdoctection/mapper/hfstruct.py,sha256=2PjGKsYturVJBimLT1CahYh09KSRAFEHz_QNtC162kQ,5551
|
|
95
95
|
deepdoctection/mapper/laylmstruct.py,sha256=abMZkYU2W0e_VcCm_c0ZXNFuv-lfMFWcTedcZS5EYvE,42935
|
|
96
96
|
deepdoctection/mapper/maputils.py,sha256=eI6ZcDg9W5uB6xQNBZpMIdEd86HlCxTtkJuyROdTqiw,8146
|
|
97
|
-
deepdoctection/mapper/match.py,sha256=
|
|
97
|
+
deepdoctection/mapper/match.py,sha256=pCWZpz2R8JahiKXCw7dxKRTLiPgJXeVDgkddDPLy_c0,9643
|
|
98
98
|
deepdoctection/mapper/misc.py,sha256=rCqHOcsCfVPXs36AWK0rZ2kk0CUM3yXV370_zyIGBJ4,6518
|
|
99
99
|
deepdoctection/mapper/pascalstruct.py,sha256=TzVU1p0oiw0nOuxTFFbEB9vXJxH1v6VUvTJ7MD0manU,3828
|
|
100
100
|
deepdoctection/mapper/prodigystruct.py,sha256=Re4Sd_zAp6qOvbXZLmMJeG0IGEfMQxebuyDeZgMcTa8,6827
|
|
@@ -139,10 +139,10 @@ deepdoctection/utils/settings.py,sha256=k6OyuWbj-IPeaO9zT9RZ-5Yad1wNhWGYqGLZdtgX
|
|
|
139
139
|
deepdoctection/utils/tqdm.py,sha256=cBUtR0L1x0KMeYrLP2rrzyzCamCjpQAKroHXLv81_pk,1820
|
|
140
140
|
deepdoctection/utils/transform.py,sha256=3kCgsEeRkG1efCdkfvj7tUFMs-e2jbjbflq826F2GPU,8502
|
|
141
141
|
deepdoctection/utils/types.py,sha256=_3dmPdCIZNLbgU5QP5k_c5phDf18xLe1kYL6t2nM45s,2953
|
|
142
|
-
deepdoctection/utils/utils.py,sha256=
|
|
143
|
-
deepdoctection/utils/viz.py,sha256=
|
|
144
|
-
deepdoctection-0.
|
|
145
|
-
deepdoctection-0.
|
|
146
|
-
deepdoctection-0.
|
|
147
|
-
deepdoctection-0.
|
|
148
|
-
deepdoctection-0.
|
|
142
|
+
deepdoctection/utils/utils.py,sha256=csVs_VvCq4QBETPoE2JdTTL4MFYnD4xh-Js5vRb612g,6492
|
|
143
|
+
deepdoctection/utils/viz.py,sha256=Mok1d0V7NwlhAvO1S1Iq5YitKpVmOfH_XHTSlRelCB0,25902
|
|
144
|
+
deepdoctection-0.36.dist-info/LICENSE,sha256=GQ0rUvuGdrMNEI3iHK5UQx6dIMU1QwAuyXsxUHn5MEQ,11351
|
|
145
|
+
deepdoctection-0.36.dist-info/METADATA,sha256=E-zXgx0bTdSqbd88D_abscR_poEJaKJGIwlv2RFbQs8,19543
|
|
146
|
+
deepdoctection-0.36.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
147
|
+
deepdoctection-0.36.dist-info/top_level.txt,sha256=hs2DdoOL9h4mnHhmO82BT4pz4QATIoOZ20PZmlnxFI8,15
|
|
148
|
+
deepdoctection-0.36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|