doc-page-extractor 0.2.4__cp310-cp310-macosx_15_0_arm64.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 doc-page-extractor might be problematic. Click here for more details.

Files changed (34) hide show
  1. doc_page_extractor/__init__.py +16 -0
  2. doc_page_extractor/clipper.py +119 -0
  3. doc_page_extractor/downloader.py +16 -0
  4. doc_page_extractor/extractor.py +218 -0
  5. doc_page_extractor/latex.py +33 -0
  6. doc_page_extractor/layout_order.py +239 -0
  7. doc_page_extractor/layoutreader.py +126 -0
  8. doc_page_extractor/model.py +133 -0
  9. doc_page_extractor/ocr.py +196 -0
  10. doc_page_extractor/ocr_corrector.py +126 -0
  11. doc_page_extractor/onnxocr/__init__.py +1 -0
  12. doc_page_extractor/onnxocr/cls_postprocess.py +26 -0
  13. doc_page_extractor/onnxocr/db_postprocess.py +246 -0
  14. doc_page_extractor/onnxocr/imaug.py +32 -0
  15. doc_page_extractor/onnxocr/operators.py +187 -0
  16. doc_page_extractor/onnxocr/predict_base.py +57 -0
  17. doc_page_extractor/onnxocr/predict_cls.py +109 -0
  18. doc_page_extractor/onnxocr/predict_det.py +139 -0
  19. doc_page_extractor/onnxocr/predict_rec.py +344 -0
  20. doc_page_extractor/onnxocr/predict_system.py +97 -0
  21. doc_page_extractor/onnxocr/rec_postprocess.py +896 -0
  22. doc_page_extractor/onnxocr/utils.py +71 -0
  23. doc_page_extractor/overlap.py +167 -0
  24. doc_page_extractor/plot.py +93 -0
  25. doc_page_extractor/raw_optimizer.py +104 -0
  26. doc_page_extractor/rectangle.py +72 -0
  27. doc_page_extractor/rotation.py +158 -0
  28. doc_page_extractor/table.py +60 -0
  29. doc_page_extractor/types.py +68 -0
  30. doc_page_extractor/utils.py +32 -0
  31. doc_page_extractor-0.2.4.dist-info/LICENSE +661 -0
  32. doc_page_extractor-0.2.4.dist-info/METADATA +88 -0
  33. doc_page_extractor-0.2.4.dist-info/RECORD +34 -0
  34. doc_page_extractor-0.2.4.dist-info/WHEEL +4 -0
@@ -0,0 +1,60 @@
1
+ import torch
2
+
3
+ from typing import Literal, Any
4
+ from PIL.Image import Image
5
+ from .types import TableLayoutParsedFormat
6
+ from .model import Model
7
+ from .utils import expand_image
8
+
9
+
10
+ OutputFormat = Literal["latex", "markdown", "html"]
11
+
12
+ class Table:
13
+ def __init__(self, device: Literal["cpu", "cuda"], model: Model) -> None:
14
+ self._model: Model = model
15
+ self._table_model: Any | None = None
16
+ self._ban: bool = False
17
+ if device == "cpu":
18
+ self._ban = True
19
+
20
+ def predict(self, image: Image, format: TableLayoutParsedFormat) -> str | None:
21
+ if self._ban:
22
+ print("CUDA is not available. You cannot parse table from image.")
23
+ return None
24
+
25
+ output_format: str
26
+ if format == TableLayoutParsedFormat.LATEX:
27
+ output_format = "latex"
28
+ elif format == TableLayoutParsedFormat.MARKDOWN:
29
+ output_format = "markdown"
30
+ elif format == TableLayoutParsedFormat.HTML:
31
+ output_format = "html"
32
+ else:
33
+ raise ValueError(f"Table format {format} is not supported.")
34
+
35
+ image = expand_image(image, 0.1)
36
+ model = self._get_model()
37
+
38
+ with torch.no_grad():
39
+ results = model([image], output_format=output_format)
40
+
41
+ if len(results) == 0:
42
+ return None
43
+
44
+ return results[0]
45
+
46
+ def _get_model(self) -> Any:
47
+ if self._table_model is None:
48
+ from .struct_eqtable import build_model
49
+ model_path = self._model.get_struct_eqtable_path()
50
+ table_model = build_model(
51
+ model_ckpt=str(model_path),
52
+ max_new_tokens=1024,
53
+ max_time=30,
54
+ lmdeploy=False,
55
+ flash_attn=True,
56
+ batch_size=1,
57
+ local_files_only=False,
58
+ )
59
+ self._table_model = table_model.cuda()
60
+ return self._table_model
@@ -0,0 +1,68 @@
1
+ from dataclasses import dataclass
2
+ from typing import Literal
3
+ from enum import auto, Enum
4
+ from PIL.Image import Image
5
+ from .rectangle import Rectangle
6
+
7
+
8
+ @dataclass
9
+ class OCRFragment:
10
+ order: int
11
+ text: str
12
+ rank: float
13
+ rect: Rectangle
14
+
15
+ class LayoutClass(Enum):
16
+ TITLE = 0
17
+ PLAIN_TEXT = 1
18
+ ABANDON = 2
19
+ FIGURE = 3
20
+ FIGURE_CAPTION = 4
21
+ TABLE = 5
22
+ TABLE_CAPTION = 6
23
+ TABLE_FOOTNOTE = 7
24
+ ISOLATE_FORMULA = 8
25
+ FORMULA_CAPTION = 9
26
+
27
+ class TableLayoutParsedFormat(Enum):
28
+ LATEX = auto()
29
+ MARKDOWN = auto()
30
+ HTML = auto()
31
+
32
+ @dataclass
33
+ class BaseLayout:
34
+ rect: Rectangle
35
+ fragments: list[OCRFragment]
36
+
37
+ @dataclass
38
+ class PlainLayout(BaseLayout):
39
+ cls: Literal[
40
+ LayoutClass.TITLE,
41
+ LayoutClass.PLAIN_TEXT,
42
+ LayoutClass.ABANDON,
43
+ LayoutClass.FIGURE,
44
+ LayoutClass.FIGURE_CAPTION,
45
+ LayoutClass.TABLE_CAPTION,
46
+ LayoutClass.TABLE_FOOTNOTE,
47
+ LayoutClass.FORMULA_CAPTION,
48
+ ]
49
+
50
+ @dataclass
51
+ class TableLayout(BaseLayout):
52
+ parsed: tuple[str, TableLayoutParsedFormat] | None
53
+ cls: Literal[LayoutClass.TABLE]
54
+
55
+ @dataclass
56
+ class FormulaLayout(BaseLayout):
57
+ latex: str | None
58
+ cls: Literal[LayoutClass.ISOLATE_FORMULA]
59
+
60
+ Layout = PlainLayout | TableLayout | FormulaLayout
61
+
62
+
63
+ @dataclass
64
+ class ExtractedResult:
65
+ rotation: float
66
+ layouts: list[Layout]
67
+ extracted_image: Image | None
68
+ adjusted_image: Image | None
@@ -0,0 +1,32 @@
1
+ import os
2
+ import re
3
+
4
+ from math import ceil
5
+ from PIL.Image import Image
6
+ from PIL.ImageOps import expand
7
+
8
+
9
+ def ensure_dir(path: str) -> str:
10
+ path = os.path.abspath(path)
11
+ os.makedirs(path, exist_ok=True)
12
+ return path
13
+
14
+ def is_space_text(text: str) -> bool:
15
+ return bool(re.match(r"^\s*$", text))
16
+
17
+ def expand_image(image: Image, percent: float):
18
+ width, height = image.size
19
+ border_width = ceil(width * percent)
20
+ border_height = ceil(height * percent)
21
+ fill_color: tuple[int, ...]
22
+
23
+ if image.mode == "RGBA":
24
+ fill_color = (255, 255, 255, 255)
25
+ else:
26
+ fill_color = (255, 255, 255)
27
+
28
+ return expand(
29
+ image=image,
30
+ border=(border_width, border_height),
31
+ fill=fill_color,
32
+ )