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.

@@ -25,7 +25,7 @@ from .utils.logger import LoggingRecord, logger
25
25
 
26
26
  # pylint: enable=wrong-import-position
27
27
 
28
- __version__ = "0.40.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(top=top, right=right, bottom=bottom, left=left) #
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)
@@ -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
 
@@ -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
- split_defaultdict[ann_id_to_split[image.image_id]].append(image)
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"]
@@ -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 transform(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
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 []
@@ -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 transform(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
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 transform(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
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.
@@ -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 transform(self, np_img: PixelValues, specification: DetectionResult) -> PixelValues:
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
 
@@ -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: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]]=None,
161
- child_ann_category_names: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]]=None,
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,
@@ -51,8 +51,9 @@ class ImageCroppingService(PipelineComponent):
51
51
  """
52
52
 
53
53
  def __init__(
54
- self, category_names: Optional[Union[TypeOrStr, Sequence[TypeOrStr]]] = None,
55
- service_ids: Optional[Sequence[str]] = None
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, {"1": LayoutType.row,
157
- "2": LayoutType.column})
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 category_id_mapping: Mapping of category IDs. Usually, the category ids start with 1.
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
  )
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # File: transform.py
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.transform(dp.image, detection_result)
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.dp_manager.set_summary_annotation(
65
- summary_key=self.transform_predictor.get_category_names()[0],
66
- summary_name=self.transform_predictor.get_category_names()[0],
67
- summary_number=None,
68
- summary_value=getattr(detection_result, self.transform_predictor.get_category_names()[0].value, None),
69
- summary_score=detection_result.score,
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)
@@ -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: transform.py
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__ = ["ResizeTransform", "InferenceResize", "PadTransform", "normalize_image"]
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, ((left, right), (top, bottom), (0, 0)), "constant", constant_values=255)
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
- top: int,
169
- right: int,
170
- bottom: int,
171
- left: int,
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 top: padding top image side
176
- :param right: padding right image side
177
- :param bottom: padding bottom image side
178
- :param left: padding left image side
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.top = top
182
- self.right = right
183
- self.bottom = bottom
184
- self.left = left
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.top, self.right, self.bottom, self.left)
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
- if self.mode == "xyxy":
198
- coords[:, 0] = coords[:, 0] + self.left
199
- coords[:, 1] = coords[:, 1] + self.top
200
- coords[:, 2] = coords[:, 2] + self.left
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
- if self.mode == "xyxy":
213
- coords[:, 0] = np.maximum(coords[:, 0] - self.left, np.zeros(coords[:, 0].shape))
214
- coords[:, 1] = np.maximum(coords[:, 1] - self.top, np.zeros(coords[:, 1].shape))
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.top, self.right, self.bottom, self.left, self.mode)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepdoctection
3
- Version: 0.40.0
3
+ Version: 0.41.0
4
4
  Summary: Repository for Document AI
5
5
  Home-page: https://github.com/deepdoctection/deepdoctection
6
6
  Author: Dr. Janis Meyer
@@ -1,9 +1,9 @@
1
- deepdoctection/__init__.py,sha256=Onsg4vkNNIGYytDmH96KsxYt3xQLxcAbyYHCeOqThR8,12780
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=sXGL_faLkKCUBfq5YIpmzV5cWuvWChYy-zP5OtdaM4Y,33251
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=Be2FvmRXt-5prZ1vwa5fG6VjgEQ_31hiQ13hAoXoaes,7740
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=iZiHMc2hkk6vWn87LK0Qf-toZU_kocW3m7Wq8M4IS2E,50782
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=AZx-hw8Mchzb7FiOASt7zCbiybFNsM_diBzKXyC-auU,22618
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=ONPgappl_P5HSwQr42FatuRnwMTvUPecPsCztDTN0Hw,24108
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=sPoixu8S9he-0wbs-jgxtPE2V9BiP4-3uZlb6F5Y1SA,3077
56
- deepdoctection/extern/doctrocr.py,sha256=R1PgKBFxVr_1-frkGvGL2ZBS19jpiktPQ4sJz_nBiNs,24622
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=tG7etMvZ-jHFdq-jJAHYMJii3ujDjMfAFYUsjBp3nKI,17444
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=rMciBHGzNLRax8zpRrCv16lMnDHGimovIqLTp853WtA,12011
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=abMZkYU2W0e_VcCm_c0ZXNFuv-lfMFWcTedcZS5EYvE,42935
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=RDTYSGtbtT8ph3L83PyHIkezJ2K82MwNerSM72uTMxM,10267
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=S6-NKvR0sqBfqjN-mH76uVgM_aHOZvhPe_ore36UPZA,21028
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=OLKvCYJynoFpo7bf2b3HzY0k-TJDLc0PHveWKcDbqZI,13324
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=9Om7X7hJeL4jgUwHM1CHa4sb5v7Qo1PtVG0ls_3nI7w,3798
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=hDD6yDX_4pQXwR5ILVwJIj6hb7NXA0-ifnC25ldcUjA,12464
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=3kCgsEeRkG1efCdkfvj7tUFMs-e2jbjbflq826F2GPU,8502
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.40.0.dist-info/licenses/LICENSE,sha256=GQ0rUvuGdrMNEI3iHK5UQx6dIMU1QwAuyXsxUHn5MEQ,11351
145
- deepdoctection-0.40.0.dist-info/METADATA,sha256=YyPBlJBcUfAQP_cW7Mhq3eNs2-924o4BMS4X6Sn0Xwo,19763
146
- deepdoctection-0.40.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
147
- deepdoctection-0.40.0.dist-info/top_level.txt,sha256=hs2DdoOL9h4mnHhmO82BT4pz4QATIoOZ20PZmlnxFI8,15
148
- deepdoctection-0.40.0.dist-info/RECORD,,
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,,