deepdoctection 0.39.7__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 +6 -3
- deepdoctection/analyzer/_config.py +0 -1
- deepdoctection/analyzer/factory.py +35 -14
- deepdoctection/datapoint/convert.py +0 -24
- deepdoctection/datapoint/image.py +5 -5
- deepdoctection/datapoint/view.py +6 -7
- 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 +28 -8
- deepdoctection/pipe/anngen.py +1 -25
- deepdoctection/pipe/common.py +92 -38
- deepdoctection/pipe/layout.py +26 -13
- deepdoctection/pipe/order.py +6 -22
- deepdoctection/pipe/segment.py +36 -43
- deepdoctection/pipe/sub_layout.py +9 -14
- deepdoctection/pipe/text.py +5 -14
- deepdoctection/pipe/transform.py +38 -16
- deepdoctection/train/hf_detr_train.py +1 -0
- deepdoctection/utils/settings.py +5 -0
- deepdoctection/utils/transform.py +173 -38
- {deepdoctection-0.39.7.dist-info → deepdoctection-0.41.0.dist-info}/METADATA +1 -1
- {deepdoctection-0.39.7.dist-info → deepdoctection-0.41.0.dist-info}/RECORD +30 -30
- {deepdoctection-0.39.7.dist-info → deepdoctection-0.41.0.dist-info}/WHEEL +1 -1
- {deepdoctection-0.39.7.dist-info → deepdoctection-0.41.0.dist-info}/licenses/LICENSE +0 -0
- {deepdoctection-0.39.7.dist-info → deepdoctection-0.41.0.dist-info}/top_level.txt +0 -0
deepdoctection/pipe/text.py
CHANGED
|
@@ -70,7 +70,6 @@ class TextExtractionService(PipelineComponent):
|
|
|
70
70
|
text_extract_detector: Union[ObjectDetector, PdfMiner, TextRecognizer],
|
|
71
71
|
extract_from_roi: Optional[Union[Sequence[TypeOrStr], TypeOrStr]] = None,
|
|
72
72
|
run_time_ocr_language_selection: bool = False,
|
|
73
|
-
skip_if_text_extracted: bool = False,
|
|
74
73
|
):
|
|
75
74
|
"""
|
|
76
75
|
:param text_extract_detector: ObjectDetector
|
|
@@ -79,8 +78,6 @@ class TextExtractionService(PipelineComponent):
|
|
|
79
78
|
multiple language selections. Also requires that a language detection
|
|
80
79
|
pipeline component ran before. It will select the expert language OCR
|
|
81
80
|
model based on the determined language.
|
|
82
|
-
:param skip_if_text_extracted: Set to `True` if text has already been extracted in a previous pipeline component
|
|
83
|
-
and should not be extracted again. Use-case: A PDF with some scanned images.
|
|
84
81
|
"""
|
|
85
82
|
|
|
86
83
|
if extract_from_roi is None:
|
|
@@ -104,11 +101,6 @@ class TextExtractionService(PipelineComponent):
|
|
|
104
101
|
raise TypeError("Only TesseractOcrDetector supports multiple languages")
|
|
105
102
|
|
|
106
103
|
self.run_time_ocr_language_selection = run_time_ocr_language_selection
|
|
107
|
-
self.skip_if_text_extracted = skip_if_text_extracted
|
|
108
|
-
if self.skip_if_text_extracted and isinstance(self.predictor, TextRecognizer):
|
|
109
|
-
raise ValueError(
|
|
110
|
-
"skip_if_text_extracted=True and TextRecognizer in TextExtractionService is not compatible"
|
|
111
|
-
)
|
|
112
104
|
|
|
113
105
|
def serve(self, dp: Image) -> None:
|
|
114
106
|
maybe_batched_text_rois = self.get_text_rois(dp)
|
|
@@ -154,11 +146,6 @@ class TextExtractionService(PipelineComponent):
|
|
|
154
146
|
well `get_text_rois` will return an empty list.
|
|
155
147
|
:return: list of ImageAnnotation or Image
|
|
156
148
|
"""
|
|
157
|
-
if self.skip_if_text_extracted:
|
|
158
|
-
text_categories = self.predictor.get_category_names()
|
|
159
|
-
text_anns = dp.get_annotation(category_names=text_categories)
|
|
160
|
-
if text_anns:
|
|
161
|
-
return []
|
|
162
149
|
|
|
163
150
|
if self.extract_from_category:
|
|
164
151
|
if self.predictor.accepts_batch:
|
|
@@ -223,7 +210,11 @@ class TextExtractionService(PipelineComponent):
|
|
|
223
210
|
predictor = self.predictor.clone()
|
|
224
211
|
if not isinstance(predictor, (ObjectDetector, PdfMiner, TextRecognizer)):
|
|
225
212
|
raise ImageError(f"predictor must be of type ObjectDetector or PdfMiner, but is of type {type(predictor)}")
|
|
226
|
-
return self.__class__(
|
|
213
|
+
return self.__class__(
|
|
214
|
+
text_extract_detector=predictor,
|
|
215
|
+
extract_from_roi=deepcopy(self.extract_from_category),
|
|
216
|
+
run_time_ocr_language_selection=self.run_time_ocr_language_selection,
|
|
217
|
+
)
|
|
227
218
|
|
|
228
219
|
def clear_predictor(self) -> None:
|
|
229
220
|
self.predictor.clear_model()
|
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
|
-
deepdoctection/analyzer/_config.py,sha256=
|
|
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=
|
|
22
|
-
deepdoctection/datapoint/image.py,sha256=
|
|
23
|
-
deepdoctection/datapoint/view.py,sha256
|
|
21
|
+
deepdoctection/datapoint/convert.py,sha256=h3ky-Qn6YA8Qoyy5SMUkjJq___cK0hbcwFygDyqqm-4,7123
|
|
22
|
+
deepdoctection/datapoint/image.py,sha256=_jN46UJUsOi6GC6VEUcp3L_vLL-iYRW05RKcFLWb6Dc,34048
|
|
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
|
|
@@ -102,24 +102,24 @@ deepdoctection/mapper/pubstruct.py,sha256=PAJ2N1HSPNS6F2ZrIwlD7PiBhIM-rJscK_Ti8O
|
|
|
102
102
|
deepdoctection/mapper/tpstruct.py,sha256=YNABRibvcISD5Lavg3jouoE4FMdqXEJoM-hNoB_rnww,4481
|
|
103
103
|
deepdoctection/mapper/xfundstruct.py,sha256=_3r3c0K82fnF2h1HxA85h-9ETYrHwcERa6MNc6Ko6Z8,8807
|
|
104
104
|
deepdoctection/pipe/__init__.py,sha256=ywTVoetftdL6plXg2YlBzMfmqBZupq7yXblSVyvvkcQ,1127
|
|
105
|
-
deepdoctection/pipe/anngen.py,sha256=
|
|
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
|
|
111
|
-
deepdoctection/pipe/layout.py,sha256=
|
|
111
|
+
deepdoctection/pipe/layout.py,sha256=ThULc0b1f9KyaXYk9z0qbuJ0nhIodah9PcrEq2xKpAY,5670
|
|
112
112
|
deepdoctection/pipe/lm.py,sha256=x9NoYpivdjQF1r76a7PPrUuBEmuHP7ZukuXFDkXhXBc,17572
|
|
113
|
-
deepdoctection/pipe/order.py,sha256=
|
|
113
|
+
deepdoctection/pipe/order.py,sha256=0KNiMinedjfuDVVHxJSaDL1yl4Sub-miMPcEC4gGwPA,39423
|
|
114
114
|
deepdoctection/pipe/refine.py,sha256=dTfI396xydPdbzpfo4yqFcuxl3UAB1y-WbSQn1o76ec,22367
|
|
115
115
|
deepdoctection/pipe/registry.py,sha256=aFx-Tn0xhVA5l5H18duNW5QoTNKQltybsEUEzsMgUfg,902
|
|
116
|
-
deepdoctection/pipe/segment.py,sha256=
|
|
117
|
-
deepdoctection/pipe/sub_layout.py,sha256=
|
|
118
|
-
deepdoctection/pipe/text.py,sha256=
|
|
119
|
-
deepdoctection/pipe/transform.py,sha256=
|
|
116
|
+
deepdoctection/pipe/segment.py,sha256=sny59GuP7dxLGX3YjHF0wllPxSiXL1GNQEhMGKcF8ZU,59594
|
|
117
|
+
deepdoctection/pipe/sub_layout.py,sha256=D73H5b2Zl35fN58TaY0_nGhwI9Nwj3wqDdDPz8ce9Fg,13538
|
|
118
|
+
deepdoctection/pipe/text.py,sha256=tLlJtneM__WsrAvp4pQFqwNlmq2RLqKqiPXlJ2lkniU,10483
|
|
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
|
-
deepdoctection/train/hf_detr_train.py,sha256=
|
|
122
|
+
deepdoctection/train/hf_detr_train.py,sha256=uBkkRyxrJF5UF__KbYvIlmb-HRWQ9TY6LiJr1Rm56kI,12043
|
|
123
123
|
deepdoctection/train/hf_layoutlm_train.py,sha256=8kiGp_8GEyqCkLgeMgCJOLJWSVoKWkUBHsZtDjZOcRk,22556
|
|
124
124
|
deepdoctection/train/tp_frcnn_train.py,sha256=pEpXokSVGveqo82pRnhnAmHPmjQ_8wQWpqM4ZyNHJgs,13049
|
|
125
125
|
deepdoctection/utils/__init__.py,sha256=brBceRWeov9WXMiJTjyJOF2rHMP8trGGRRjhMdZ61nI,2371
|
|
@@ -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
|