deepdoctection 0.40.0__py3-none-any.whl → 0.41.0__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 +5 -3
- deepdoctection/analyzer/factory.py +1 -1
- deepdoctection/datapoint/convert.py +0 -24
- deepdoctection/datapoint/view.py +1 -2
- deepdoctection/datasets/base.py +3 -1
- deepdoctection/extern/base.py +108 -1
- deepdoctection/extern/deskew.py +1 -1
- deepdoctection/extern/doctrocr.py +2 -1
- deepdoctection/extern/tessocr.py +1 -1
- deepdoctection/extern/tp/tpfrcnn/preproc.py +1 -1
- deepdoctection/mapper/laylmstruct.py +1 -2
- deepdoctection/mapper/match.py +2 -2
- deepdoctection/pipe/common.py +3 -2
- deepdoctection/pipe/sub_layout.py +8 -4
- deepdoctection/pipe/transform.py +38 -16
- deepdoctection/utils/settings.py +5 -0
- deepdoctection/utils/transform.py +173 -38
- {deepdoctection-0.40.0.dist-info → deepdoctection-0.41.0.dist-info}/METADATA +1 -1
- {deepdoctection-0.40.0.dist-info → deepdoctection-0.41.0.dist-info}/RECORD +22 -22
- {deepdoctection-0.40.0.dist-info → deepdoctection-0.41.0.dist-info}/WHEEL +0 -0
- {deepdoctection-0.40.0.dist-info → deepdoctection-0.41.0.dist-info}/licenses/LICENSE +0 -0
- {deepdoctection-0.40.0.dist-info → deepdoctection-0.41.0.dist-info}/top_level.txt +0 -0
deepdoctection/__init__.py
CHANGED
|
@@ -25,7 +25,7 @@ from .utils.logger import LoggingRecord, logger
|
|
|
25
25
|
|
|
26
26
|
# pylint: enable=wrong-import-position
|
|
27
27
|
|
|
28
|
-
__version__ = "0.
|
|
28
|
+
__version__ = "0.41.0"
|
|
29
29
|
|
|
30
30
|
_IMPORT_STRUCTURE = {
|
|
31
31
|
"analyzer": ["config_sanity_checks", "get_dd_analyzer", "ServiceFactory"],
|
|
@@ -90,8 +90,6 @@ _IMPORT_STRUCTURE = {
|
|
|
90
90
|
"convert_np_array_to_b64_b",
|
|
91
91
|
"convert_bytes_to_np_array",
|
|
92
92
|
"convert_pdf_bytes_to_np_array_v2",
|
|
93
|
-
"box_to_point4",
|
|
94
|
-
"point4_to_box",
|
|
95
93
|
"as_dict",
|
|
96
94
|
"ImageAnnotationBaseView",
|
|
97
95
|
"Image",
|
|
@@ -164,6 +162,7 @@ _IMPORT_STRUCTURE = {
|
|
|
164
162
|
"LMSequenceClassifier",
|
|
165
163
|
"LanguageDetector",
|
|
166
164
|
"ImageTransformer",
|
|
165
|
+
"DeterministicImageTransformer",
|
|
167
166
|
"InferenceResize",
|
|
168
167
|
"D2FrcnnDetector",
|
|
169
168
|
"D2FrcnnTracingDetector",
|
|
@@ -401,11 +400,14 @@ _IMPORT_STRUCTURE = {
|
|
|
401
400
|
"get_type",
|
|
402
401
|
"get_tqdm",
|
|
403
402
|
"get_tqdm_default_kwargs",
|
|
403
|
+
"box_to_point4",
|
|
404
|
+
"point4_to_box",
|
|
404
405
|
"ResizeTransform",
|
|
405
406
|
"InferenceResize",
|
|
406
407
|
"normalize_image",
|
|
407
408
|
"pad_image",
|
|
408
409
|
"PadTransform",
|
|
410
|
+
"RotationTransform",
|
|
409
411
|
"delete_keys_from_dict",
|
|
410
412
|
"split_string",
|
|
411
413
|
"string_to_dict",
|
|
@@ -197,7 +197,7 @@ class ServiceFactory:
|
|
|
197
197
|
getattr(config.PT, mode).PAD.BOTTOM,
|
|
198
198
|
getattr(config.PT, mode).PAD.LEFT,
|
|
199
199
|
)
|
|
200
|
-
return PadTransform(
|
|
200
|
+
return PadTransform(pad_top=top, pad_right=right, pad_bottom=bottom, pad_left=left) #
|
|
201
201
|
|
|
202
202
|
@staticmethod
|
|
203
203
|
def build_padder(config: AttrDict, mode: str) -> PadTransform:
|
|
@@ -27,7 +27,6 @@ from typing import Any, Optional, Union, no_type_check
|
|
|
27
27
|
|
|
28
28
|
import numpy as np
|
|
29
29
|
from numpy import uint8
|
|
30
|
-
from numpy.typing import NDArray
|
|
31
30
|
from pypdf import PdfReader
|
|
32
31
|
|
|
33
32
|
from ..utils.develop import deprecated
|
|
@@ -42,8 +41,6 @@ __all__ = [
|
|
|
42
41
|
"convert_np_array_to_b64_b",
|
|
43
42
|
"convert_bytes_to_np_array",
|
|
44
43
|
"convert_pdf_bytes_to_np_array_v2",
|
|
45
|
-
"box_to_point4",
|
|
46
|
-
"point4_to_box",
|
|
47
44
|
"as_dict",
|
|
48
45
|
]
|
|
49
46
|
|
|
@@ -187,24 +184,3 @@ def convert_pdf_bytes_to_np_array_v2(
|
|
|
187
184
|
width = shape[2] - shape[0]
|
|
188
185
|
return pdf_to_np_array(pdf_bytes, size=(int(width), int(height))) # type: ignore
|
|
189
186
|
return pdf_to_np_array(pdf_bytes, dpi=dpi)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def box_to_point4(boxes: NDArray[np.float32]) -> NDArray[np.float32]:
|
|
193
|
-
"""
|
|
194
|
-
:param boxes: nx4
|
|
195
|
-
:return: (nx4)x2
|
|
196
|
-
"""
|
|
197
|
-
box = boxes[:, [0, 1, 2, 3, 0, 3, 2, 1]]
|
|
198
|
-
box = box.reshape((-1, 2))
|
|
199
|
-
return box
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def point4_to_box(points: NDArray[np.float32]) -> NDArray[np.float32]:
|
|
203
|
-
"""
|
|
204
|
-
:param points: (nx4)x2
|
|
205
|
-
:return: nx4 boxes (x1y1x2y2)
|
|
206
|
-
"""
|
|
207
|
-
points = points.reshape((-1, 4, 2))
|
|
208
|
-
min_xy = points.min(axis=1) # nx2
|
|
209
|
-
max_xy = points.max(axis=1) # nx2
|
|
210
|
-
return np.concatenate((min_xy, max_xy), axis=1)
|
deepdoctection/datapoint/view.py
CHANGED
|
@@ -41,12 +41,11 @@ from ..utils.settings import (
|
|
|
41
41
|
WordType,
|
|
42
42
|
get_type,
|
|
43
43
|
)
|
|
44
|
-
from ..utils.transform import ResizeTransform
|
|
44
|
+
from ..utils.transform import ResizeTransform, box_to_point4, point4_to_box
|
|
45
45
|
from ..utils.types import HTML, AnnotationDict, Chunks, ImageDict, PathLikeOrStr, PixelValues, Text_, csv
|
|
46
46
|
from ..utils.viz import draw_boxes, interactive_imshow, viz_handler
|
|
47
47
|
from .annotation import CategoryAnnotation, ContainerAnnotation, ImageAnnotation, ann_from_dict
|
|
48
48
|
from .box import BoundingBox, crop_box_from_image
|
|
49
|
-
from .convert import box_to_point4, point4_to_box
|
|
50
49
|
from .image import Image
|
|
51
50
|
|
|
52
51
|
|
deepdoctection/datasets/base.py
CHANGED
|
@@ -369,7 +369,9 @@ class MergeDataset(DatasetBase):
|
|
|
369
369
|
self.buffer_datasets(**dataflow_build_kwargs)
|
|
370
370
|
split_defaultdict = defaultdict(list)
|
|
371
371
|
for image in self.datapoint_list: # type: ignore
|
|
372
|
-
|
|
372
|
+
maybe_image_id = ann_id_to_split.get(image.image_id)
|
|
373
|
+
if maybe_image_id is not None:
|
|
374
|
+
split_defaultdict[maybe_image_id].append(image)
|
|
373
375
|
train_dataset = split_defaultdict["train"]
|
|
374
376
|
val_dataset = split_defaultdict["val"]
|
|
375
377
|
test_dataset = split_defaultdict["test"]
|
deepdoctection/extern/base.py
CHANGED
|
@@ -26,6 +26,7 @@ from dataclasses import dataclass, field
|
|
|
26
26
|
from types import MappingProxyType
|
|
27
27
|
from typing import TYPE_CHECKING, Any, Literal, Mapping, Optional, Sequence, Union, overload
|
|
28
28
|
|
|
29
|
+
import numpy as np
|
|
29
30
|
from lazy_imports import try_import
|
|
30
31
|
|
|
31
32
|
from ..utils.identifier import get_uuid_from_str
|
|
@@ -38,6 +39,7 @@ from ..utils.settings import (
|
|
|
38
39
|
token_class_tag_to_token_class_with_tag,
|
|
39
40
|
token_class_with_tag_to_token_class_and_tag,
|
|
40
41
|
)
|
|
42
|
+
from ..utils.transform import BaseTransform, box_to_point4, point4_to_box
|
|
41
43
|
from ..utils.types import JsonDict, PixelValues, Requirement
|
|
42
44
|
|
|
43
45
|
if TYPE_CHECKING:
|
|
@@ -621,7 +623,7 @@ class ImageTransformer(PredictorBase, ABC):
|
|
|
621
623
|
"""
|
|
622
624
|
|
|
623
625
|
@abstractmethod
|
|
624
|
-
def
|
|
626
|
+
def transform_image(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
|
|
625
627
|
"""
|
|
626
628
|
Abstract method transform
|
|
627
629
|
"""
|
|
@@ -641,3 +643,108 @@ class ImageTransformer(PredictorBase, ABC):
|
|
|
641
643
|
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
642
644
|
"""returns category names"""
|
|
643
645
|
raise NotImplementedError()
|
|
646
|
+
|
|
647
|
+
def transform_coords(self, detect_results: Sequence[DetectionResult]) -> Sequence[DetectionResult]:
|
|
648
|
+
"""
|
|
649
|
+
Transform coordinates aligned with the transform_image method.
|
|
650
|
+
|
|
651
|
+
:param detect_results: List of DetectionResults
|
|
652
|
+
:return: List of DetectionResults. If you pass uuid it is possible to track the transformed bounding boxes.
|
|
653
|
+
"""
|
|
654
|
+
|
|
655
|
+
raise NotImplementedError()
|
|
656
|
+
|
|
657
|
+
def inverse_transform_coords(self, detect_results: Sequence[DetectionResult]) -> Sequence[DetectionResult]:
|
|
658
|
+
"""
|
|
659
|
+
Inverse transform coordinates aligned with the transform_image method. Composing transform_coords with
|
|
660
|
+
inverse_transform_coords should return the original coordinates.
|
|
661
|
+
|
|
662
|
+
:param detect_results: List of DetectionResults
|
|
663
|
+
:return: List of DetectionResults. If you pass uuid it is possible to track the transformed bounding boxes.
|
|
664
|
+
"""
|
|
665
|
+
|
|
666
|
+
raise NotImplementedError()
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class DeterministicImageTransformer(ImageTransformer):
|
|
670
|
+
"""
|
|
671
|
+
A wrapper for BaseTransform classes that implements the ImageTransformer interface.
|
|
672
|
+
|
|
673
|
+
This class provides a bridge between the BaseTransform system (which handles image and coordinate
|
|
674
|
+
transformations like rotation, padding, etc.) and the predictors framework by implementing the
|
|
675
|
+
ImageTransformer interface. It allows BaseTransform objects to be used within pipelines that
|
|
676
|
+
expect ImageTransformer components.
|
|
677
|
+
|
|
678
|
+
The transformer performs deterministic transformations on images and their associated coordinates,
|
|
679
|
+
enabling operations like padding, rotation, and other geometric transformations while maintaining
|
|
680
|
+
the relationship between image content and annotation coordinates.
|
|
681
|
+
|
|
682
|
+
:param base_transform: A BaseTransform instance that defines the actual transformation operations
|
|
683
|
+
to be applied to images and coordinates.
|
|
684
|
+
"""
|
|
685
|
+
|
|
686
|
+
def __init__(self, base_transform: BaseTransform):
|
|
687
|
+
"""
|
|
688
|
+
Initialize the DeterministicImageTransformer with a BaseTransform instance.
|
|
689
|
+
|
|
690
|
+
:param base_transform: A BaseTransform instance that defines the actual transformation operations
|
|
691
|
+
"""
|
|
692
|
+
self.base_transform = base_transform
|
|
693
|
+
self.name = base_transform.__class__.__name__
|
|
694
|
+
self.model_id = self.get_model_id()
|
|
695
|
+
|
|
696
|
+
def transform_image(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
|
|
697
|
+
return self.base_transform.apply_image(np_img)
|
|
698
|
+
|
|
699
|
+
def transform_coords(self, detect_results: Sequence[DetectionResult]) -> Sequence[DetectionResult]:
|
|
700
|
+
boxes = np.array([detect_result.box for detect_result in detect_results])
|
|
701
|
+
# boxes = box_to_point4(boxes)
|
|
702
|
+
boxes = self.base_transform.apply_coords(boxes)
|
|
703
|
+
# boxes = point4_to_box(boxes)
|
|
704
|
+
detection_results = []
|
|
705
|
+
for idx, detect_result in enumerate(detect_results):
|
|
706
|
+
detection_results.append(
|
|
707
|
+
DetectionResult(
|
|
708
|
+
box=boxes[idx, :].tolist(),
|
|
709
|
+
class_name=detect_result.class_name,
|
|
710
|
+
class_id=detect_result.class_id,
|
|
711
|
+
score=detect_result.score,
|
|
712
|
+
absolute_coords=detect_result.absolute_coords,
|
|
713
|
+
uuid=detect_result.uuid,
|
|
714
|
+
)
|
|
715
|
+
)
|
|
716
|
+
return detection_results
|
|
717
|
+
|
|
718
|
+
def inverse_transform_coords(self, detect_results: Sequence[DetectionResult]) -> Sequence[DetectionResult]:
|
|
719
|
+
boxes = np.array([detect_result.box for detect_result in detect_results])
|
|
720
|
+
boxes = box_to_point4(boxes)
|
|
721
|
+
boxes = self.base_transform.inverse_apply_coords(boxes)
|
|
722
|
+
boxes = point4_to_box(boxes)
|
|
723
|
+
detection_results = []
|
|
724
|
+
for idx, detect_result in enumerate(detect_results):
|
|
725
|
+
detection_results.append(
|
|
726
|
+
DetectionResult(
|
|
727
|
+
box=boxes[idx, :].tolist(),
|
|
728
|
+
class_id=detect_result.class_id,
|
|
729
|
+
score=detect_result.score,
|
|
730
|
+
absolute_coords=detect_result.absolute_coords,
|
|
731
|
+
uuid=detect_result.uuid,
|
|
732
|
+
)
|
|
733
|
+
)
|
|
734
|
+
return detection_results
|
|
735
|
+
|
|
736
|
+
def clone(self) -> DeterministicImageTransformer:
|
|
737
|
+
return self.__class__(self.base_transform)
|
|
738
|
+
|
|
739
|
+
def predict(self, np_img: PixelValues) -> DetectionResult:
|
|
740
|
+
detect_result = DetectionResult()
|
|
741
|
+
for init_arg in self.base_transform.get_init_args():
|
|
742
|
+
setattr(detect_result, init_arg, getattr(self.base_transform, init_arg))
|
|
743
|
+
return detect_result
|
|
744
|
+
|
|
745
|
+
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
746
|
+
return self.base_transform.get_category_names()
|
|
747
|
+
|
|
748
|
+
@classmethod
|
|
749
|
+
def get_requirements(cls) -> list[Requirement]:
|
|
750
|
+
return []
|
deepdoctection/extern/deskew.py
CHANGED
|
@@ -43,7 +43,7 @@ class Jdeskewer(ImageTransformer):
|
|
|
43
43
|
self.model_id = self.get_model_id()
|
|
44
44
|
self.min_angle_rotation = min_angle_rotation
|
|
45
45
|
|
|
46
|
-
def
|
|
46
|
+
def transform_image(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
|
|
47
47
|
"""
|
|
48
48
|
Rotation of the image according to the angle determined by the jdeskew estimator.
|
|
49
49
|
|
|
@@ -514,8 +514,9 @@ class DocTrRotationTransformer(ImageTransformer):
|
|
|
514
514
|
self.number_contours = number_contours
|
|
515
515
|
self.ratio_threshold_for_lines = ratio_threshold_for_lines
|
|
516
516
|
self.name = "doctr_rotation_transformer"
|
|
517
|
+
self.model_id = self.get_model_id()
|
|
517
518
|
|
|
518
|
-
def
|
|
519
|
+
def transform_image(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
|
|
519
520
|
"""
|
|
520
521
|
Applies the predicted rotation to the image, effectively rotating the image backwards.
|
|
521
522
|
This method uses either the Pillow library or OpenCV for the rotation operation, depending on the configuration.
|
deepdoctection/extern/tessocr.py
CHANGED
|
@@ -423,7 +423,7 @@ class TesseractRotationTransformer(ImageTransformer):
|
|
|
423
423
|
self.categories = ModelCategories(init_categories={1: PageType.ANGLE})
|
|
424
424
|
self.model_id = self.get_model_id()
|
|
425
425
|
|
|
426
|
-
def
|
|
426
|
+
def transform_image(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
|
|
427
427
|
"""
|
|
428
428
|
Applies the predicted rotation to the image, effectively rotating the image backwards.
|
|
429
429
|
This method uses either the Pillow library or OpenCV for the rotation operation, depending on the configuration.
|
|
@@ -15,9 +15,9 @@ from typing import Any, List, Optional, Tuple
|
|
|
15
15
|
import numpy as np
|
|
16
16
|
from lazy_imports import try_import
|
|
17
17
|
|
|
18
|
-
from ....datapoint.convert import box_to_point4, point4_to_box
|
|
19
18
|
from ....utils.error import MalformedData
|
|
20
19
|
from ....utils.logger import log_once
|
|
20
|
+
from ....utils.transform import box_to_point4, point4_to_box
|
|
21
21
|
from ....utils.types import JsonDict, PixelValues
|
|
22
22
|
from .common import filter_boxes_inside_shape, np_iou
|
|
23
23
|
from .modeling.model_fpn import get_all_anchors_fpn
|
|
@@ -31,11 +31,10 @@ import numpy.typing as npt
|
|
|
31
31
|
from lazy_imports import try_import
|
|
32
32
|
|
|
33
33
|
from ..datapoint.annotation import ContainerAnnotation
|
|
34
|
-
from ..datapoint.convert import box_to_point4, point4_to_box
|
|
35
34
|
from ..datapoint.image import Image
|
|
36
35
|
from ..datapoint.view import Page
|
|
37
36
|
from ..utils.settings import DatasetType, LayoutType, PageType, Relationships, WordType
|
|
38
|
-
from ..utils.transform import ResizeTransform, normalize_image
|
|
37
|
+
from ..utils.transform import ResizeTransform, box_to_point4, normalize_image, point4_to_box
|
|
39
38
|
from ..utils.types import JsonDict
|
|
40
39
|
from .maputils import curry
|
|
41
40
|
|
deepdoctection/mapper/match.py
CHANGED
|
@@ -157,8 +157,8 @@ def match_anns_by_intersection(
|
|
|
157
157
|
|
|
158
158
|
def match_anns_by_distance(
|
|
159
159
|
dp: Image,
|
|
160
|
-
parent_ann_category_names:
|
|
161
|
-
child_ann_category_names:
|
|
160
|
+
parent_ann_category_names: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]] = None,
|
|
161
|
+
child_ann_category_names: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]] = None,
|
|
162
162
|
parent_ann_ids: Optional[Union[Sequence[str], str]] = None,
|
|
163
163
|
child_ann_ids: Optional[Union[str, Sequence[str]]] = None,
|
|
164
164
|
parent_ann_service_ids: Optional[Union[str, Sequence[str]]] = None,
|
deepdoctection/pipe/common.py
CHANGED
|
@@ -51,8 +51,9 @@ class ImageCroppingService(PipelineComponent):
|
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
def __init__(
|
|
54
|
-
self,
|
|
55
|
-
|
|
54
|
+
self,
|
|
55
|
+
category_names: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]] = None,
|
|
56
|
+
service_ids: Optional[Sequence[str]] = None,
|
|
56
57
|
) -> None:
|
|
57
58
|
"""
|
|
58
59
|
:param category_names: A single name or a list of category names to crop
|
|
@@ -153,8 +153,8 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
153
153
|
**Example**
|
|
154
154
|
|
|
155
155
|
detect_result_generator = DetectResultGenerator(categories_items)
|
|
156
|
-
d_items = TPFrcnnDetector(item_config_path, item_weights_path, {
|
|
157
|
-
|
|
156
|
+
d_items = TPFrcnnDetector(item_config_path, item_weights_path, {1: LayoutType.row,
|
|
157
|
+
2: LayoutType.column})
|
|
158
158
|
item_component = SubImageLayoutService(d_items, LayoutType.table, detect_result_generator)
|
|
159
159
|
"""
|
|
160
160
|
|
|
@@ -162,6 +162,7 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
162
162
|
self,
|
|
163
163
|
sub_image_detector: ObjectDetector,
|
|
164
164
|
sub_image_names: Union[str, Sequence[TypeOrStr]],
|
|
165
|
+
service_ids: Optional[Sequence[str]] = None,
|
|
165
166
|
detect_result_generator: Optional[DetectResultGenerator] = None,
|
|
166
167
|
padder: Optional[PadTransform] = None,
|
|
167
168
|
):
|
|
@@ -170,7 +171,8 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
170
171
|
:param sub_image_names: Category names of ImageAnnotations to be presented to the detector.
|
|
171
172
|
Attention: The selected ImageAnnotations must have: attr:`image` and: attr:`image.image`
|
|
172
173
|
not None.
|
|
173
|
-
:param
|
|
174
|
+
:param service_ids: List of service ids to be used for filtering the ImageAnnotations. If None, all
|
|
175
|
+
ImageAnnotations will be used.
|
|
174
176
|
:param detect_result_generator: 'DetectResultGenerator' instance. 'categories' attribute has to be the same as
|
|
175
177
|
the 'categories' attribute of the 'sub_image_detector'. The generator will be
|
|
176
178
|
responsible to create 'DetectionResult' for some categories, if they have not
|
|
@@ -184,6 +186,7 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
184
186
|
if isinstance(sub_image_names, str)
|
|
185
187
|
else tuple((get_type(cat) for cat in sub_image_names))
|
|
186
188
|
)
|
|
189
|
+
self.service_ids = service_ids
|
|
187
190
|
self.detect_result_generator = detect_result_generator
|
|
188
191
|
self.padder = padder
|
|
189
192
|
self.predictor = sub_image_detector
|
|
@@ -205,7 +208,7 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
205
208
|
- Optionally invoke the DetectResultGenerator
|
|
206
209
|
- Generate ImageAnnotations and dump to parent image and sub image.
|
|
207
210
|
"""
|
|
208
|
-
sub_image_anns = dp.get_annotation(category_names=self.sub_image_name)
|
|
211
|
+
sub_image_anns = dp.get_annotation(category_names=self.sub_image_name, service_ids=self.service_ids)
|
|
209
212
|
for sub_image_ann in sub_image_anns:
|
|
210
213
|
np_image = self.prepare_np_image(sub_image_ann)
|
|
211
214
|
detect_result_list = self.predictor.predict(np_image)
|
|
@@ -246,6 +249,7 @@ class SubImageLayoutService(PipelineComponent):
|
|
|
246
249
|
return self.__class__(
|
|
247
250
|
predictor,
|
|
248
251
|
self.sub_image_name,
|
|
252
|
+
self.service_ids,
|
|
249
253
|
self.detect_result_generator,
|
|
250
254
|
padder_clone,
|
|
251
255
|
)
|
deepdoctection/pipe/transform.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
# File:
|
|
2
|
+
# File: test_transform.py
|
|
3
3
|
|
|
4
4
|
# Copyright 2022 Dr. Janis Meyer. All rights reserved.
|
|
5
5
|
#
|
|
@@ -22,6 +22,7 @@ on images (e.g. deskew, de-noising or more general GAN like operations.
|
|
|
22
22
|
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
|
+
from .. import DetectionResult
|
|
25
26
|
from ..datapoint.image import Image
|
|
26
27
|
from ..extern.base import ImageTransformer
|
|
27
28
|
from .base import MetaAnnotation, PipelineComponent
|
|
@@ -49,25 +50,46 @@ class SimpleTransformService(PipelineComponent):
|
|
|
49
50
|
super().__init__(self._get_name(transform_predictor.name), self.transform_predictor.model_id)
|
|
50
51
|
|
|
51
52
|
def serve(self, dp: Image) -> None:
|
|
52
|
-
if dp.annotations:
|
|
53
|
-
raise RuntimeError(
|
|
54
|
-
"SimpleTransformService receives datapoints with ÌmageAnnotations. This violates the "
|
|
55
|
-
"pipeline building API but this can currently be catched only at runtime. "
|
|
56
|
-
"Please make sure that this component is the first one in the pipeline."
|
|
57
|
-
)
|
|
58
|
-
|
|
59
53
|
if dp.image is not None:
|
|
60
54
|
detection_result = self.transform_predictor.predict(dp.image)
|
|
61
|
-
transformed_image = self.transform_predictor.
|
|
55
|
+
transformed_image = self.transform_predictor.transform_image(dp.image, detection_result)
|
|
62
56
|
self.dp_manager.datapoint.clear_image(True)
|
|
63
57
|
self.dp_manager.datapoint.image = transformed_image
|
|
64
|
-
self.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
for category in self.transform_predictor.get_category_names():
|
|
59
|
+
self.dp_manager.set_summary_annotation(
|
|
60
|
+
summary_key=category,
|
|
61
|
+
summary_name=category,
|
|
62
|
+
summary_number=None,
|
|
63
|
+
summary_value=getattr(detection_result, category.value, None),
|
|
64
|
+
summary_score=detection_result.score,
|
|
65
|
+
)
|
|
66
|
+
detect_results = []
|
|
67
|
+
for ann in dp.get_annotation():
|
|
68
|
+
box = ann.get_bounding_box()
|
|
69
|
+
if not box.absolute_coords:
|
|
70
|
+
box = box.transform(dp.width, dp.height)
|
|
71
|
+
detect_results.append(
|
|
72
|
+
DetectionResult(
|
|
73
|
+
box=box.to_list(mode="xyxy"),
|
|
74
|
+
class_name=ann.category_name, # type: ignore
|
|
75
|
+
score=ann.score,
|
|
76
|
+
class_id=ann.category_id,
|
|
77
|
+
uuid=ann.annotation_id,
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
output_detect_results = self.transform_predictor.transform_coords(detect_results)
|
|
81
|
+
for detect_result in output_detect_results:
|
|
82
|
+
ann = dp.get_annotation(annotation_ids=detect_result.uuid)[0]
|
|
83
|
+
transformed_ann_id = self.dp_manager.set_image_annotation(detect_result)
|
|
84
|
+
if transformed_ann_id is None:
|
|
85
|
+
print("here")
|
|
86
|
+
transformed_ann = self.dp_manager.datapoint.get_annotation(annotation_ids=transformed_ann_id)[0]
|
|
87
|
+
|
|
88
|
+
for key, sub_ann in ann.sub_categories.items():
|
|
89
|
+
transformed_ann.dump_sub_category(key, sub_ann)
|
|
90
|
+
if ann.image is not None:
|
|
91
|
+
dp.image_ann_to_image(transformed_ann.annotation_id, ann.image.image is not None)
|
|
92
|
+
ann.deactivate()
|
|
71
93
|
|
|
72
94
|
def clone(self) -> SimpleTransformService:
|
|
73
95
|
return self.__class__(self.transform_predictor)
|
deepdoctection/utils/settings.py
CHANGED
|
@@ -67,6 +67,11 @@ class PageType(ObjectTypes):
|
|
|
67
67
|
DOCUMENT_TYPE = "document_type"
|
|
68
68
|
LANGUAGE = "language"
|
|
69
69
|
ANGLE = "angle"
|
|
70
|
+
SIZE = "size"
|
|
71
|
+
PAD_TOP = "pad_top"
|
|
72
|
+
PAD_BOTTOM = "pad_bottom"
|
|
73
|
+
PAD_LEFT = "pad_left"
|
|
74
|
+
PAD_RIGHT = "pad_right"
|
|
70
75
|
|
|
71
76
|
|
|
72
77
|
@object_types_registry.register("SummaryType")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
# File:
|
|
2
|
+
# File: test_transform.py
|
|
3
3
|
|
|
4
4
|
# Copyright 2022 Dr. Janis Meyer. All rights reserved.
|
|
5
5
|
#
|
|
@@ -23,17 +23,50 @@ of coordinates. Most have the ideas have been taken from
|
|
|
23
23
|
|
|
24
24
|
from __future__ import annotations
|
|
25
25
|
|
|
26
|
+
import inspect
|
|
26
27
|
from abc import ABC, abstractmethod
|
|
27
|
-
from typing import Literal, Optional, Union
|
|
28
|
+
from typing import Literal, Optional, Set, Union
|
|
28
29
|
|
|
29
30
|
import numpy as np
|
|
30
31
|
import numpy.typing as npt
|
|
31
32
|
from numpy import float32
|
|
32
33
|
|
|
34
|
+
from .settings import ObjectTypes, PageType
|
|
33
35
|
from .types import PixelValues
|
|
34
36
|
from .viz import viz_handler
|
|
35
37
|
|
|
36
|
-
__all__ = [
|
|
38
|
+
__all__ = [
|
|
39
|
+
"point4_to_box",
|
|
40
|
+
"box_to_point4",
|
|
41
|
+
"ResizeTransform",
|
|
42
|
+
"InferenceResize",
|
|
43
|
+
"PadTransform",
|
|
44
|
+
"normalize_image",
|
|
45
|
+
"pad_image",
|
|
46
|
+
"BaseTransform",
|
|
47
|
+
"RotationTransform",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def box_to_point4(boxes: npt.NDArray[np.float32]) -> npt.NDArray[np.float32]:
|
|
52
|
+
"""
|
|
53
|
+
:param boxes: nx4
|
|
54
|
+
:return: (nx4)x2
|
|
55
|
+
"""
|
|
56
|
+
box = boxes[:, [0, 1, 2, 3, 0, 3, 2, 1]]
|
|
57
|
+
box = box.reshape((-1, 2))
|
|
58
|
+
return box
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def point4_to_box(points: npt.NDArray[np.float32]) -> npt.NDArray[np.float32]:
|
|
62
|
+
"""
|
|
63
|
+
:param points: (nx4)x2
|
|
64
|
+
:return: nx4 boxes (x1y1x2y2)
|
|
65
|
+
"""
|
|
66
|
+
points = points.reshape((-1, 4, 2))
|
|
67
|
+
min_xy = points.min(axis=1) # nx2
|
|
68
|
+
max_xy = points.max(axis=1) # nx2
|
|
69
|
+
return np.concatenate((min_xy, max_xy), axis=1)
|
|
37
70
|
|
|
38
71
|
|
|
39
72
|
class BaseTransform(ABC):
|
|
@@ -51,6 +84,33 @@ class BaseTransform(ABC):
|
|
|
51
84
|
"""The transformation that should be applied to the image"""
|
|
52
85
|
raise NotImplementedError()
|
|
53
86
|
|
|
87
|
+
@abstractmethod
|
|
88
|
+
def apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
89
|
+
"""Transformation that should be applied to coordinates. Coords are supposed to to be passed as like
|
|
90
|
+
|
|
91
|
+
np.array([[ulx_0,uly_0,lrx_0,lry_0],[ulx_1,uly_1,lrx_1,lry_1],...])
|
|
92
|
+
"""
|
|
93
|
+
raise NotImplementedError()
|
|
94
|
+
|
|
95
|
+
@abstractmethod
|
|
96
|
+
def inverse_apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
97
|
+
"""Inverse transformation going back from coordinates of transformed image to original image. Coords are
|
|
98
|
+
supposed to to be passed as like
|
|
99
|
+
|
|
100
|
+
np.array([[ulx_0,uly_0,lrx_0,lry_0],[ulx_1,uly_1,lrx_1,lry_1],...])
|
|
101
|
+
"""
|
|
102
|
+
raise NotImplementedError()
|
|
103
|
+
|
|
104
|
+
@abstractmethod
|
|
105
|
+
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
106
|
+
"""Get category names"""
|
|
107
|
+
raise NotImplementedError()
|
|
108
|
+
|
|
109
|
+
def get_init_args(self) -> Set[str]:
|
|
110
|
+
"""Return the names of the arguments of the constructor."""
|
|
111
|
+
args = inspect.signature(self.__init__).parameters.keys() # type: ignore
|
|
112
|
+
return {arg for arg in args if arg != "self"}
|
|
113
|
+
|
|
54
114
|
|
|
55
115
|
class ResizeTransform(BaseTransform):
|
|
56
116
|
"""
|
|
@@ -93,6 +153,16 @@ class ResizeTransform(BaseTransform):
|
|
|
93
153
|
coords[:, 1] = coords[:, 1] * (self.new_h * 1.0 / self.h)
|
|
94
154
|
return coords
|
|
95
155
|
|
|
156
|
+
def inverse_apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
157
|
+
"""Inverse transformation going back from coordinates of resized image to original image"""
|
|
158
|
+
coords[:, 0] = coords[:, 0] * (self.w * 1.0 / self.new_w)
|
|
159
|
+
coords[:, 1] = coords[:, 1] * (self.h * 1.0 / self.new_h)
|
|
160
|
+
return coords
|
|
161
|
+
|
|
162
|
+
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
163
|
+
"""Get category names"""
|
|
164
|
+
return (PageType.SIZE,)
|
|
165
|
+
|
|
96
166
|
|
|
97
167
|
class InferenceResize:
|
|
98
168
|
"""
|
|
@@ -155,7 +225,7 @@ def pad_image(image: PixelValues, top: int, right: int, bottom: int, left: int)
|
|
|
155
225
|
:param bottom: Bottom pixel value to pad
|
|
156
226
|
:param left: Left pixel value to pad
|
|
157
227
|
"""
|
|
158
|
-
return np.pad(image, ((
|
|
228
|
+
return np.pad(image, ((top, bottom), (left, right), (0, 0)), "constant", constant_values=255)
|
|
159
229
|
|
|
160
230
|
|
|
161
231
|
class PadTransform(BaseTransform):
|
|
@@ -165,60 +235,125 @@ class PadTransform(BaseTransform):
|
|
|
165
235
|
|
|
166
236
|
def __init__(
|
|
167
237
|
self,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
mode: Literal["xyxy", "xywh"] = "xyxy",
|
|
238
|
+
pad_top: int,
|
|
239
|
+
pad_right: int,
|
|
240
|
+
pad_bottom: int,
|
|
241
|
+
pad_left: int,
|
|
173
242
|
):
|
|
174
243
|
"""
|
|
175
|
-
:param
|
|
176
|
-
:param
|
|
177
|
-
:param
|
|
178
|
-
:param
|
|
179
|
-
:param mode: bounding box mode. Needed for transforming coordinates.
|
|
244
|
+
:param pad_top: padding top image side
|
|
245
|
+
:param pad_right: padding right image side
|
|
246
|
+
:param pad_bottom: padding bottom image side
|
|
247
|
+
:param pad_left: padding left image side
|
|
180
248
|
"""
|
|
181
|
-
self.
|
|
182
|
-
self.
|
|
183
|
-
self.
|
|
184
|
-
self.
|
|
249
|
+
self.pad_top = pad_top
|
|
250
|
+
self.pad_right = pad_right
|
|
251
|
+
self.pad_bottom = pad_bottom
|
|
252
|
+
self.pad_left = pad_left
|
|
185
253
|
self.image_width: Optional[int] = None
|
|
186
254
|
self.image_height: Optional[int] = None
|
|
187
|
-
self.mode = mode
|
|
188
255
|
|
|
189
256
|
def apply_image(self, img: PixelValues) -> PixelValues:
|
|
190
257
|
"""Apply padding to image"""
|
|
191
258
|
self.image_width = img.shape[1]
|
|
192
259
|
self.image_height = img.shape[0]
|
|
193
|
-
return pad_image(img, self.
|
|
260
|
+
return pad_image(img, self.pad_top, self.pad_right, self.pad_bottom, self.pad_left)
|
|
194
261
|
|
|
195
262
|
def apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
196
263
|
"""Transformation that should be applied to coordinates"""
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
coords[:, 3] = coords[:, 3] + self.top
|
|
202
|
-
else:
|
|
203
|
-
coords[:, 0] = coords[:, 0] + self.left
|
|
204
|
-
coords[:, 1] = coords[:, 1] + self.top
|
|
264
|
+
coords[:, 0] = coords[:, 0] + self.pad_left
|
|
265
|
+
coords[:, 1] = coords[:, 1] + self.pad_top
|
|
266
|
+
coords[:, 2] = coords[:, 2] + self.pad_left
|
|
267
|
+
coords[:, 3] = coords[:, 3] + self.pad_top
|
|
205
268
|
return coords
|
|
206
269
|
|
|
207
270
|
def inverse_apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
208
271
|
"""Inverse transformation going back from coordinates of padded image to original image"""
|
|
209
272
|
if self.image_height is None or self.image_width is None:
|
|
210
273
|
raise ValueError("Initialize image_width and image_height first")
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
coords[:, 2] = np.minimum(coords[:, 2] - self.left, np.ones(coords[:, 2].shape) * self.image_width)
|
|
216
|
-
coords[:, 3] = np.minimum(coords[:, 3] - self.top, np.ones(coords[:, 3].shape) * self.image_height)
|
|
217
|
-
else:
|
|
218
|
-
coords[:, 0] = np.maximum(coords[:, 0] - self.left, np.zeros(coords[:, 0].shape))
|
|
219
|
-
coords[:, 1] = np.maximum(coords[:, 1] - self.top, np.zeros(coords[:, 1].shape))
|
|
274
|
+
coords[:, 0] = np.maximum(coords[:, 0] - self.pad_left, np.zeros(coords[:, 0].shape))
|
|
275
|
+
coords[:, 1] = np.maximum(coords[:, 1] - self.pad_top, np.zeros(coords[:, 1].shape))
|
|
276
|
+
coords[:, 2] = np.minimum(coords[:, 2] - self.pad_left, np.ones(coords[:, 2].shape) * self.image_width)
|
|
277
|
+
coords[:, 3] = np.minimum(coords[:, 3] - self.pad_top, np.ones(coords[:, 3].shape) * self.image_height)
|
|
220
278
|
return coords
|
|
221
279
|
|
|
222
280
|
def clone(self) -> PadTransform:
|
|
223
281
|
"""clone"""
|
|
224
|
-
return self.__class__(self.
|
|
282
|
+
return self.__class__(self.pad_top, self.pad_right, self.pad_bottom, self.pad_left)
|
|
283
|
+
|
|
284
|
+
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
285
|
+
"""Get category names"""
|
|
286
|
+
return (
|
|
287
|
+
PageType.PAD_TOP,
|
|
288
|
+
PageType.PAD_RIGHT,
|
|
289
|
+
PageType.PAD_LEFT,
|
|
290
|
+
PageType.PAD_BOTTOM,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class RotationTransform(BaseTransform):
|
|
295
|
+
"""
|
|
296
|
+
A transform for rotating images by 90, 180, 270, or 360 degrees.
|
|
297
|
+
"""
|
|
298
|
+
|
|
299
|
+
def __init__(self, angle: Literal[90, 180, 270, 360]):
|
|
300
|
+
"""
|
|
301
|
+
:param angle: angle to rotate the image. Must be one of 90, 180, 270, or 360 degrees.
|
|
302
|
+
:param mode: coordinate format - "xyxy" (bounding box), "xywh" (width/height), "poly" (polygon points)
|
|
303
|
+
"""
|
|
304
|
+
self.angle = angle
|
|
305
|
+
self.image_width: Optional[int] = None
|
|
306
|
+
self.image_height: Optional[int] = None
|
|
307
|
+
|
|
308
|
+
def apply_image(self, img: PixelValues) -> PixelValues:
|
|
309
|
+
"""Apply rotation to image"""
|
|
310
|
+
self.image_width = img.shape[1]
|
|
311
|
+
self.image_height = img.shape[0]
|
|
312
|
+
return viz_handler.rotate_image(img, self.angle)
|
|
313
|
+
|
|
314
|
+
def apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
315
|
+
"""Transformation that should be applied to coordinates"""
|
|
316
|
+
if self.image_width is None or self.image_height is None:
|
|
317
|
+
raise ValueError("Initialize image_width and image_height first")
|
|
318
|
+
|
|
319
|
+
if self.angle == 90:
|
|
320
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [1, 0, 3, 2]]
|
|
321
|
+
coords[:, [1, 3]] = self.image_width - coords[:, [1, 3]]
|
|
322
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [0, 3, 2, 1]]
|
|
323
|
+
elif self.angle == 180:
|
|
324
|
+
coords[:, [0, 2]] = self.image_width - coords[:, [0, 2]]
|
|
325
|
+
coords[:, [1, 3]] = self.image_height - coords[:, [1, 3]]
|
|
326
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [2, 3, 0, 1]]
|
|
327
|
+
elif self.angle == 270:
|
|
328
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [1, 0, 3, 2]]
|
|
329
|
+
coords[:, [0, 2]] = self.image_height - coords[:, [0, 2]]
|
|
330
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [2, 1, 0, 3]]
|
|
331
|
+
|
|
332
|
+
return coords
|
|
333
|
+
|
|
334
|
+
def inverse_apply_coords(self, coords: npt.NDArray[float32]) -> npt.NDArray[float32]:
|
|
335
|
+
"""Inverse transformation going back from coordinates of rotated image to original image"""
|
|
336
|
+
if self.image_width is None or self.image_height is None:
|
|
337
|
+
raise ValueError("Initialize image_width and image_height first")
|
|
338
|
+
|
|
339
|
+
if self.angle == 90:
|
|
340
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [1, 0, 3, 2]]
|
|
341
|
+
coords[:, [0, 2]] = self.image_width - coords[:, [0, 2]]
|
|
342
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [2, 1, 0, 3]]
|
|
343
|
+
elif self.angle == 180:
|
|
344
|
+
coords[:, [0, 2]] = self.image_width - coords[:, [0, 2]]
|
|
345
|
+
coords[:, [1, 3]] = self.image_height - coords[:, [1, 3]]
|
|
346
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [2, 3, 0, 1]]
|
|
347
|
+
elif self.angle == 270:
|
|
348
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [1, 0, 3, 2]]
|
|
349
|
+
coords[:, [1, 3]] = self.image_height - coords[:, [1, 3]]
|
|
350
|
+
coords[:, [0, 1, 2, 3]] = coords[:, [0, 3, 2, 1]]
|
|
351
|
+
return coords
|
|
352
|
+
|
|
353
|
+
def clone(self) -> RotationTransform:
|
|
354
|
+
"""clone"""
|
|
355
|
+
return self.__class__(self.angle)
|
|
356
|
+
|
|
357
|
+
def get_category_names(self) -> tuple[ObjectTypes, ...]:
|
|
358
|
+
"""Get category names"""
|
|
359
|
+
return (PageType.ANGLE,)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
deepdoctection/__init__.py,sha256=
|
|
1
|
+
deepdoctection/__init__.py,sha256=cr4wBN6EV5-nllpbHfU9jPaHa-L0QfPKcdqFThHeJFc,12850
|
|
2
2
|
deepdoctection/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
deepdoctection/analyzer/__init__.py,sha256=icClxrd20XutD6LxLgEPIWceSs4j_QfI3szCE-9BL2w,729
|
|
4
4
|
deepdoctection/analyzer/_config.py,sha256=kxQzDQvl2ygH84VTnumbRF7JLGM6VeJoBzv1xssm6H4,5019
|
|
5
5
|
deepdoctection/analyzer/dd.py,sha256=bfR7e1JV7BwUNDRLu0jYZU7qQXnyA_vbRAJl2Ylrq5o,5905
|
|
6
|
-
deepdoctection/analyzer/factory.py,sha256=
|
|
6
|
+
deepdoctection/analyzer/factory.py,sha256=aw6Nrqfjcg3M0Qy6214nX-oBv3GKTv62Wnz6WRTw2c8,33267
|
|
7
7
|
deepdoctection/configs/__init__.py,sha256=TX_P6tqDOF1LK1mi9ruAl7x0mtv1Asm8cYWCz3Pe2dk,646
|
|
8
8
|
deepdoctection/configs/conf_dd_one.yaml,sha256=qnrDAST1PHBtdIKE_hdkZexW22FqVvNTI-PEo9wvinM,3025
|
|
9
9
|
deepdoctection/configs/conf_tesseract.yaml,sha256=oF6szDyoi15FHvq7yFUNIEjfA_jNLhGxoowiRsz_zY4,35
|
|
@@ -18,12 +18,12 @@ deepdoctection/dataflow/stats.py,sha256=Bsr6v7lcesKXUYtO9wjqlzx_Yq_uyIF3Lel-tQ0i
|
|
|
18
18
|
deepdoctection/datapoint/__init__.py,sha256=3K406GbOPhoEp8koVaSbMocmSsmWifnSZ1SPb7C1lOY,1643
|
|
19
19
|
deepdoctection/datapoint/annotation.py,sha256=FEgz4COxVDfjic0gG7kS6iHnWLBIgFnquQ63Cbj2a4Y,22531
|
|
20
20
|
deepdoctection/datapoint/box.py,sha256=XPhC_xHqLZJjzafg1pIS_CxnVB5-0_yk-twsZZ3ncUU,30093
|
|
21
|
-
deepdoctection/datapoint/convert.py,sha256=
|
|
21
|
+
deepdoctection/datapoint/convert.py,sha256=h3ky-Qn6YA8Qoyy5SMUkjJq___cK0hbcwFygDyqqm-4,7123
|
|
22
22
|
deepdoctection/datapoint/image.py,sha256=_jN46UJUsOi6GC6VEUcp3L_vLL-iYRW05RKcFLWb6Dc,34048
|
|
23
|
-
deepdoctection/datapoint/view.py,sha256
|
|
23
|
+
deepdoctection/datapoint/view.py,sha256=-4EygREbqQ0gNwS_LUWBX9svmug8wAE2vPA3k4zyyc4,50762
|
|
24
24
|
deepdoctection/datasets/__init__.py,sha256=-A3aR90aDsHPmVM35JavfnQ2itYSCn3ujl4krRni1QU,1076
|
|
25
25
|
deepdoctection/datasets/adapter.py,sha256=Ly_vbOAgVI73V41FUccnSX1ECTOyesW_qsuvQuvOZbw,7796
|
|
26
|
-
deepdoctection/datasets/base.py,sha256=
|
|
26
|
+
deepdoctection/datasets/base.py,sha256=X5Sr0yyal9x8rqWaWYr5mA_bE11UzN1iFXmWu605q2Y,22713
|
|
27
27
|
deepdoctection/datasets/dataflow_builder.py,sha256=cYU2zV3gZW2bFvMHimlO9VIl3BAUaCwML08cCIQ8Em4,4107
|
|
28
28
|
deepdoctection/datasets/info.py,sha256=sC1QCOdLWFMooVmiShZ43sLUpAi3FK4d0fsLyl_9-gA,20548
|
|
29
29
|
deepdoctection/datasets/registry.py,sha256=utiB-PnE6vc5HvjcudO0O4Urp2BC3snqswY6d8uPQAo,3388
|
|
@@ -50,17 +50,17 @@ deepdoctection/eval/registry.py,sha256=v4mp-s67vBVRu1nQzuGlYPViQnMSeIXEcF_WmvfUC
|
|
|
50
50
|
deepdoctection/eval/tedsmetric.py,sha256=rKw-734Y9CpBtIfkBSPQF2vAZxnIdWrI9Zc723P7RxI,9529
|
|
51
51
|
deepdoctection/eval/tp_eval_callback.py,sha256=SXsXumoyxq-MIH9Cep5eUOwnNshMbKmC6mYOGwCg0pM,5283
|
|
52
52
|
deepdoctection/extern/__init__.py,sha256=9Iks9b4Q_LynjcV167TVCoK8YsQRUcA2jjmAmDNA_X8,1056
|
|
53
|
-
deepdoctection/extern/base.py,sha256=
|
|
53
|
+
deepdoctection/extern/base.py,sha256=oRuoAduVchsR3H7Ddm-KAe_smt0N6PlQftPqJ75FWfA,28944
|
|
54
54
|
deepdoctection/extern/d2detect.py,sha256=zrKv1yurApnjD7QZIZk_8LYCahjmN82MQUjHjv8zvkQ,22127
|
|
55
|
-
deepdoctection/extern/deskew.py,sha256=
|
|
56
|
-
deepdoctection/extern/doctrocr.py,sha256=
|
|
55
|
+
deepdoctection/extern/deskew.py,sha256=iax1ztkguGDfD4KQMDyuvanR4J2VgpCRuVWWDTwViu4,3083
|
|
56
|
+
deepdoctection/extern/doctrocr.py,sha256=iUww7PuhCioEEv8ModrAElPPeEBa32zwUEa6OQf_y_c,24672
|
|
57
57
|
deepdoctection/extern/fastlang.py,sha256=F4gK-SEwcCujjxH327ZDzMGWToJ49xS_dCKcePQ9IlY,4780
|
|
58
58
|
deepdoctection/extern/hfdetr.py,sha256=JzHrrTyzS9qh6T2TsvKboAGZkIhno2txmSoLQ5Vd-lo,12077
|
|
59
59
|
deepdoctection/extern/hflayoutlm.py,sha256=tFaf90FRbZzhSycdp8rGkeiPywQa6UcTEEwbayIXkr0,57023
|
|
60
60
|
deepdoctection/extern/hflm.py,sha256=kwS6kcSlY_2m9u0RzBLTRq-UMM7c1PhyUaDTvSdejus,9217
|
|
61
61
|
deepdoctection/extern/model.py,sha256=lbVwDa3vD6VwCD_dsozcI8b4xDZs4KJ1628SxaDdtHQ,55378
|
|
62
62
|
deepdoctection/extern/pdftext.py,sha256=KS_t27SUiYn_IOS_J2lF9lSSo22vLagxmxvYCY3CqXA,7228
|
|
63
|
-
deepdoctection/extern/tessocr.py,sha256=
|
|
63
|
+
deepdoctection/extern/tessocr.py,sha256=gRYJsk0jBRMG_ZLXbuJeRYPSPuVjXNwThs4op1hHpoA,17450
|
|
64
64
|
deepdoctection/extern/texocr.py,sha256=yMt5ZzKtsjd7ogrcNXba7zccGGGF9LXK194EtER6YNQ,5804
|
|
65
65
|
deepdoctection/extern/tpdetect.py,sha256=yAk1duQdoX-_pHLHgvhU7OOSiDy863q6XUMpjpYR734,8477
|
|
66
66
|
deepdoctection/extern/pt/__init__.py,sha256=3Cu0ZHjbYsJomru7-RQXEHihEQLegZrmLetlHiqS58I,742
|
|
@@ -72,7 +72,7 @@ deepdoctection/extern/tp/tpcompat.py,sha256=rPW_JrYtz9PbV20dZiMKm6DTrjS1A3rAdhrh
|
|
|
72
72
|
deepdoctection/extern/tp/tpfrcnn/__init__.py,sha256=OzDaR5A8HGz9a4VwjLiR9rN1Nf1cSebv8DVEMxStFOw,703
|
|
73
73
|
deepdoctection/extern/tp/tpfrcnn/common.py,sha256=fCxwi2u752ZlI_DtIkLC_x9j9tyo1nnirAi2PmnziD4,3830
|
|
74
74
|
deepdoctection/extern/tp/tpfrcnn/predict.py,sha256=957dnhCByS-FZH13efFWADhodaV4lKto-ikLPetfvEQ,4338
|
|
75
|
-
deepdoctection/extern/tp/tpfrcnn/preproc.py,sha256=
|
|
75
|
+
deepdoctection/extern/tp/tpfrcnn/preproc.py,sha256=oHN9keBurjdNQqXmsb5BgURB5nl-eEp0KHvO1DPRQL4,12009
|
|
76
76
|
deepdoctection/extern/tp/tpfrcnn/config/__init__.py,sha256=RhJiXId6vUSw_Pi49SPwj0jrf61VxxptXoGeBKtT42M,705
|
|
77
77
|
deepdoctection/extern/tp/tpfrcnn/config/config.py,sha256=-T8AwNAIPR-_5OL1oEqm-Qe9GbN6JjAPVUuUw_XfMVc,11405
|
|
78
78
|
deepdoctection/extern/tp/tpfrcnn/modeling/__init__.py,sha256=RhJiXId6vUSw_Pi49SPwj0jrf61VxxptXoGeBKtT42M,705
|
|
@@ -92,9 +92,9 @@ deepdoctection/mapper/cats.py,sha256=O06WGkpOIlSNMCy5VESl2HYOFDTuT9ls4aZIaWUv9VU
|
|
|
92
92
|
deepdoctection/mapper/cocostruct.py,sha256=GcbUpPFUg67pcOHQluWBFOFcGaYnlZcTmwBDERBVgCA,5978
|
|
93
93
|
deepdoctection/mapper/d2struct.py,sha256=Dx-YnycsIQH4a5-9Gn_yMhiQ-gOFgMueNeH3rhXjuCU,8555
|
|
94
94
|
deepdoctection/mapper/hfstruct.py,sha256=2PjGKsYturVJBimLT1CahYh09KSRAFEHz_QNtC162kQ,5551
|
|
95
|
-
deepdoctection/mapper/laylmstruct.py,sha256=
|
|
95
|
+
deepdoctection/mapper/laylmstruct.py,sha256=Es_aQOsfCkereJLOd1yaXhNAEEFJkODRuThUJ-d6hHU,42904
|
|
96
96
|
deepdoctection/mapper/maputils.py,sha256=eI6ZcDg9W5uB6xQNBZpMIdEd86HlCxTtkJuyROdTqiw,8146
|
|
97
|
-
deepdoctection/mapper/match.py,sha256=
|
|
97
|
+
deepdoctection/mapper/match.py,sha256=TBc2yAWdQbM3sS64TerOJZwhPPMxk9cmfSXctKdwIU8,10269
|
|
98
98
|
deepdoctection/mapper/misc.py,sha256=vX-fV420Te00eD-cqTiWBV2twHqdBcBV2_7rAFRgPRg,7164
|
|
99
99
|
deepdoctection/mapper/pascalstruct.py,sha256=TzVU1p0oiw0nOuxTFFbEB9vXJxH1v6VUvTJ7MD0manU,3828
|
|
100
100
|
deepdoctection/mapper/prodigystruct.py,sha256=Re4Sd_zAp6qOvbXZLmMJeG0IGEfMQxebuyDeZgMcTa8,6827
|
|
@@ -104,7 +104,7 @@ deepdoctection/mapper/xfundstruct.py,sha256=_3r3c0K82fnF2h1HxA85h-9ETYrHwcERa6MN
|
|
|
104
104
|
deepdoctection/pipe/__init__.py,sha256=ywTVoetftdL6plXg2YlBzMfmqBZupq7yXblSVyvvkcQ,1127
|
|
105
105
|
deepdoctection/pipe/anngen.py,sha256=7wvp7eghDwrgcIyu1vjRxmVy4SADPbn-k4ud8y2bgjU,15338
|
|
106
106
|
deepdoctection/pipe/base.py,sha256=wlza9aDOKnHKrXmaz8MLyLz0nMqqcIWQ-6Lu944aicE,15390
|
|
107
|
-
deepdoctection/pipe/common.py,sha256=
|
|
107
|
+
deepdoctection/pipe/common.py,sha256=lY4kvQ5iOxp1NtdZf1KPrWXHMjU7Px8NtEBdUTDl9RQ,21032
|
|
108
108
|
deepdoctection/pipe/concurrency.py,sha256=AAKRsVgaBEYNluntbDa46SBF1JZ_XqnWLDSWrNvAzEo,9657
|
|
109
109
|
deepdoctection/pipe/doctectionpipe.py,sha256=bGW3ugky-fb-nEe-3bvO6Oc_4_6w82cQboGM_6p2eIo,12530
|
|
110
110
|
deepdoctection/pipe/language.py,sha256=5zI0UQC6Fh12_r2pfVL42HoCGz2hpHrOhpXAn5m-rYw,5451
|
|
@@ -114,9 +114,9 @@ deepdoctection/pipe/order.py,sha256=0KNiMinedjfuDVVHxJSaDL1yl4Sub-miMPcEC4gGwPA,
|
|
|
114
114
|
deepdoctection/pipe/refine.py,sha256=dTfI396xydPdbzpfo4yqFcuxl3UAB1y-WbSQn1o76ec,22367
|
|
115
115
|
deepdoctection/pipe/registry.py,sha256=aFx-Tn0xhVA5l5H18duNW5QoTNKQltybsEUEzsMgUfg,902
|
|
116
116
|
deepdoctection/pipe/segment.py,sha256=sny59GuP7dxLGX3YjHF0wllPxSiXL1GNQEhMGKcF8ZU,59594
|
|
117
|
-
deepdoctection/pipe/sub_layout.py,sha256=
|
|
117
|
+
deepdoctection/pipe/sub_layout.py,sha256=D73H5b2Zl35fN58TaY0_nGhwI9Nwj3wqDdDPz8ce9Fg,13538
|
|
118
118
|
deepdoctection/pipe/text.py,sha256=tLlJtneM__WsrAvp4pQFqwNlmq2RLqKqiPXlJ2lkniU,10483
|
|
119
|
-
deepdoctection/pipe/transform.py,sha256=
|
|
119
|
+
deepdoctection/pipe/transform.py,sha256=eCSRbyxHLz11owOHFA9UDX7tOJPZG2eiPWIGJv2odbk,4890
|
|
120
120
|
deepdoctection/train/__init__.py,sha256=YFTRAZF1F7cEAKTdAIi1BLyYb6rSRcwq09Ui5Lu8d6E,1071
|
|
121
121
|
deepdoctection/train/d2_frcnn_train.py,sha256=sFc_G-mEpaM8d1CCE0_6Gl4nBh11X2RYRBA3p_ylFJQ,16000
|
|
122
122
|
deepdoctection/train/hf_detr_train.py,sha256=uBkkRyxrJF5UF__KbYvIlmb-HRWQ9TY6LiJr1Rm56kI,12043
|
|
@@ -135,14 +135,14 @@ deepdoctection/utils/logger.py,sha256=J0OVKiXP_2A82MWbbJoOeMEJ-75aZu5npgaS_yI6mV
|
|
|
135
135
|
deepdoctection/utils/metacfg.py,sha256=hD76KQ_RnD_5B02qLI2Zxf3WfnsnXhEI_KUTKpw91RI,5711
|
|
136
136
|
deepdoctection/utils/mocks.py,sha256=IkN3-IzAl4eX0ibgKIHg8IY7ykVw6BnpF6XnxKnKaZI,2389
|
|
137
137
|
deepdoctection/utils/pdf_utils.py,sha256=Fi0eZ2GbnO7N61Rd8b8YRKRff4dalHAzkcn3zpGPoic,13119
|
|
138
|
-
deepdoctection/utils/settings.py,sha256=
|
|
138
|
+
deepdoctection/utils/settings.py,sha256=nmA7aqzHTMrAhodNbPjr-afLRt2EWjpx8ipQeE-bqqs,12590
|
|
139
139
|
deepdoctection/utils/tqdm.py,sha256=cBUtR0L1x0KMeYrLP2rrzyzCamCjpQAKroHXLv81_pk,1820
|
|
140
|
-
deepdoctection/utils/transform.py,sha256=
|
|
140
|
+
deepdoctection/utils/transform.py,sha256=5mY5D6hhk6cKFp0T1LJ2_jMjjBxJopcFZffAN5PKvFU,13699
|
|
141
141
|
deepdoctection/utils/types.py,sha256=ti4WdtIJSg3TGK_YPkkoY9PYGMnR2tTX6Xfik8U1pNk,2986
|
|
142
142
|
deepdoctection/utils/utils.py,sha256=csVs_VvCq4QBETPoE2JdTTL4MFYnD4xh-Js5vRb612g,6492
|
|
143
143
|
deepdoctection/utils/viz.py,sha256=Jf8ePNYWlpuyaS6SeTYQ4OyA3eNhtgjvAQZnGNdgHC0,27051
|
|
144
|
-
deepdoctection-0.
|
|
145
|
-
deepdoctection-0.
|
|
146
|
-
deepdoctection-0.
|
|
147
|
-
deepdoctection-0.
|
|
148
|
-
deepdoctection-0.
|
|
144
|
+
deepdoctection-0.41.0.dist-info/licenses/LICENSE,sha256=GQ0rUvuGdrMNEI3iHK5UQx6dIMU1QwAuyXsxUHn5MEQ,11351
|
|
145
|
+
deepdoctection-0.41.0.dist-info/METADATA,sha256=-okfYzsN5uUB9BR6j3eKaLZtzxCr9lRWsoyvf-RgXwM,19763
|
|
146
|
+
deepdoctection-0.41.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
147
|
+
deepdoctection-0.41.0.dist-info/top_level.txt,sha256=hs2DdoOL9h4mnHhmO82BT4pz4QATIoOZ20PZmlnxFI8,15
|
|
148
|
+
deepdoctection-0.41.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|