doc-page-extractor 0.0.10__py3-none-any.whl → 0.1.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 doc-page-extractor might be problematic. Click here for more details.
- doc_page_extractor/__init__.py +12 -2
- doc_page_extractor/extractor.py +53 -10
- doc_page_extractor/latex.py +57 -0
- doc_page_extractor/struct_eqtable/__init__.py +49 -0
- doc_page_extractor/struct_eqtable/internvl/__init__.py +2 -0
- doc_page_extractor/struct_eqtable/internvl/conversation.py +394 -0
- doc_page_extractor/struct_eqtable/internvl/internvl.py +198 -0
- doc_page_extractor/struct_eqtable/internvl/internvl_lmdeploy.py +81 -0
- doc_page_extractor/struct_eqtable/pix2s/__init__.py +3 -0
- doc_page_extractor/struct_eqtable/pix2s/pix2s.py +76 -0
- doc_page_extractor/struct_eqtable/pix2s/pix2s_trt.py +1047 -0
- doc_page_extractor/table.py +71 -0
- doc_page_extractor/types.py +34 -3
- doc_page_extractor/utils.py +23 -1
- {doc_page_extractor-0.0.10.dist-info → doc_page_extractor-0.1.0.dist-info}/METADATA +6 -2
- {doc_page_extractor-0.0.10.dist-info → doc_page_extractor-0.1.0.dist-info}/RECORD +19 -9
- {doc_page_extractor-0.0.10.dist-info → doc_page_extractor-0.1.0.dist-info}/WHEEL +0 -0
- {doc_page_extractor-0.0.10.dist-info → doc_page_extractor-0.1.0.dist-info}/licenses/LICENSE +0 -0
- {doc_page_extractor-0.0.10.dist-info → doc_page_extractor-0.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import torch
|
|
3
|
+
|
|
4
|
+
from typing import Literal, Any
|
|
5
|
+
from PIL.Image import Image
|
|
6
|
+
from .types import TableLayoutParsedFormat
|
|
7
|
+
from .utils import expand_image
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
OutputFormat = Literal["latex", "markdown", "html"]
|
|
11
|
+
|
|
12
|
+
class Table:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
device: Literal["cpu", "cuda"],
|
|
16
|
+
model_path: str,
|
|
17
|
+
):
|
|
18
|
+
self._model: Any | None = None
|
|
19
|
+
self._model_path: str = model_path
|
|
20
|
+
self._ban: bool = False
|
|
21
|
+
if device == "cpu" or not torch.cuda.is_available():
|
|
22
|
+
self._ban = True
|
|
23
|
+
|
|
24
|
+
def predict(self, image: Image, format: TableLayoutParsedFormat) -> str | None:
|
|
25
|
+
if self._ban:
|
|
26
|
+
print("CUDA is not available. You cannot parse table from image.")
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
output_format: str
|
|
30
|
+
if format == TableLayoutParsedFormat.LATEX:
|
|
31
|
+
output_format = "latex"
|
|
32
|
+
elif format == TableLayoutParsedFormat.MARKDOWN:
|
|
33
|
+
output_format = "markdown"
|
|
34
|
+
elif format == TableLayoutParsedFormat.HTML:
|
|
35
|
+
output_format = "html"
|
|
36
|
+
else:
|
|
37
|
+
raise ValueError(f"Table format {format} is not supported.")
|
|
38
|
+
|
|
39
|
+
image = expand_image(image, 0.1)
|
|
40
|
+
model = self._get_model()
|
|
41
|
+
|
|
42
|
+
with torch.no_grad():
|
|
43
|
+
results = model([image], output_format=output_format)
|
|
44
|
+
|
|
45
|
+
if len(results) == 0:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
return results[0]
|
|
49
|
+
|
|
50
|
+
def _get_model(self):
|
|
51
|
+
if self._model is None:
|
|
52
|
+
local_files_only: bool
|
|
53
|
+
if os.path.exists(self._model_path):
|
|
54
|
+
local_files_only = True
|
|
55
|
+
else:
|
|
56
|
+
local_files_only = False
|
|
57
|
+
os.makedirs(self._model_path)
|
|
58
|
+
|
|
59
|
+
from .struct_eqtable import build_model
|
|
60
|
+
model = build_model(
|
|
61
|
+
model_ckpt="U4R/StructTable-InternVL2-1B",
|
|
62
|
+
max_new_tokens=1024,
|
|
63
|
+
max_time=30,
|
|
64
|
+
lmdeploy=False,
|
|
65
|
+
flash_attn=True,
|
|
66
|
+
batch_size=1,
|
|
67
|
+
cache_dir=self._model_path,
|
|
68
|
+
local_files_only=local_files_only,
|
|
69
|
+
)
|
|
70
|
+
self._model = model.cuda()
|
|
71
|
+
return self._model
|
doc_page_extractor/types.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from
|
|
2
|
+
from typing import Literal
|
|
3
|
+
from enum import auto, Enum
|
|
3
4
|
from PIL.Image import Image
|
|
4
5
|
from .rectangle import Rectangle
|
|
5
6
|
|
|
7
|
+
|
|
6
8
|
@dataclass
|
|
7
9
|
class OCRFragment:
|
|
8
10
|
order: int
|
|
@@ -22,12 +24,41 @@ class LayoutClass(Enum):
|
|
|
22
24
|
ISOLATE_FORMULA = 8
|
|
23
25
|
FORMULA_CAPTION = 9
|
|
24
26
|
|
|
27
|
+
class TableLayoutParsedFormat(Enum):
|
|
28
|
+
LATEX = auto()
|
|
29
|
+
MARKDOWN = auto()
|
|
30
|
+
HTML = auto()
|
|
31
|
+
|
|
25
32
|
@dataclass
|
|
26
|
-
class
|
|
27
|
-
cls: LayoutClass
|
|
33
|
+
class BaseLayout:
|
|
28
34
|
rect: Rectangle
|
|
29
35
|
fragments: list[OCRFragment]
|
|
30
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: LayoutClass.TABLE
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class FormulaLayout(BaseLayout):
|
|
57
|
+
latex: str | None
|
|
58
|
+
cls: LayoutClass.ISOLATE_FORMULA
|
|
59
|
+
|
|
60
|
+
Layout = PlainLayout | TableLayout | FormulaLayout
|
|
61
|
+
|
|
31
62
|
@dataclass
|
|
32
63
|
class ExtractedResult:
|
|
33
64
|
rotation: float
|
doc_page_extractor/utils.py
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
|
+
from math import ceil
|
|
5
|
+
from PIL.Image import Image
|
|
6
|
+
from PIL.ImageOps import expand
|
|
7
|
+
|
|
8
|
+
|
|
4
9
|
def ensure_dir(path: str) -> str:
|
|
5
10
|
path = os.path.abspath(path)
|
|
6
11
|
os.makedirs(path, exist_ok=True)
|
|
7
12
|
return path
|
|
8
13
|
|
|
9
14
|
def is_space_text(text: str) -> bool:
|
|
10
|
-
return re.match(r"^\s*$", text)
|
|
15
|
+
return 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
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: doc-page-extractor
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: doc page extractor can identify text and format in images and return structured data.
|
|
5
5
|
Home-page: https://github.com/Moskize91/doc-page-extractor
|
|
6
6
|
Author: Tao Zeyu
|
|
@@ -12,8 +12,10 @@ Requires-Dist: pillow<11.0,>=10.3
|
|
|
12
12
|
Requires-Dist: pyclipper<2.0,>=1.2.0
|
|
13
13
|
Requires-Dist: numpy<2.0,>=1.24.0
|
|
14
14
|
Requires-Dist: shapely<3.0,>=2.0.0
|
|
15
|
-
Requires-Dist: transformers
|
|
15
|
+
Requires-Dist: transformers<=4.47,>=4.42.4
|
|
16
16
|
Requires-Dist: doclayout_yolo>=0.0.3
|
|
17
|
+
Requires-Dist: pix2tex<=0.2.0,>=0.1.4
|
|
18
|
+
Requires-Dist: accelerate<2.0,>=1.6.0
|
|
17
19
|
Dynamic: author
|
|
18
20
|
Dynamic: author-email
|
|
19
21
|
Dynamic: description
|
|
@@ -78,3 +80,5 @@ The code of `doc_page_extractor/onnxocr` in this repo comes from [OnnxOCR](https
|
|
|
78
80
|
- [DocLayout-YOLO](https://github.com/opendatalab/DocLayout-YOLO)
|
|
79
81
|
- [OnnxOCR](https://github.com/jingsongliujing/OnnxOCR)
|
|
80
82
|
- [layoutreader](https://github.com/ppaanngggg/layoutreader)
|
|
83
|
+
- [StructEqTable](https://github.com/Alpha-Innovator/StructEqTable-Deploy)
|
|
84
|
+
- [LaTeX-OCR](https://github.com/lukas-blecher/LaTeX-OCR)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
doc_page_extractor/__init__.py,sha256=
|
|
1
|
+
doc_page_extractor/__init__.py,sha256=9rWKSMTgzP7Xv15zA4upsyPaR8S8JeNpMyhWElRCW0M,311
|
|
2
2
|
doc_page_extractor/clipper.py,sha256=5S1TI0aqMebwlPv_Ih4Nxpp6MchEjOih-CiZfMWUAhI,3201
|
|
3
3
|
doc_page_extractor/downloader.py,sha256=NbGN9ARnER8-gd4T1uc3W98WMEClVxMrqnShq8HibTw,455
|
|
4
|
-
doc_page_extractor/extractor.py,sha256=
|
|
4
|
+
doc_page_extractor/extractor.py,sha256=njLl8VdOgm-noWPDYTfjIAUU1giNc-wLvCSR1pHkfS8,7267
|
|
5
|
+
doc_page_extractor/latex.py,sha256=W_zAcksNRuru-WjCq4CSn07s_SWrDhikadJSy_Cg3Do,1954
|
|
5
6
|
doc_page_extractor/layout_order.py,sha256=NwMzTPr4xsriz4slCwqwhw2-vrMu-qfwtcFsDu8d1yM,7426
|
|
6
7
|
doc_page_extractor/layoutreader.py,sha256=BdC4oPbtpXoLmYhjuSFrKn6SNoT2zWw_gi95sGAUwrk,4031
|
|
7
8
|
doc_page_extractor/ocr.py,sha256=KJ5PqtBa4_n8LAfMLGApUVNPUS1DBEwVKcC-zck283I,5161
|
|
@@ -11,8 +12,9 @@ doc_page_extractor/plot.py,sha256=4uibjS_x1SyEyjaJJd0YsBbzkgldDOCct4Ry2cOhdXU,25
|
|
|
11
12
|
doc_page_extractor/raw_optimizer.py,sha256=1KghECq_rJwuZZITTLQnGTKYivFKg_qDvMLN9g17sks,2844
|
|
12
13
|
doc_page_extractor/rectangle.py,sha256=Tp__NPiY6JlYwYxejST7BUXhv_bl8tkmDXi4JgHCK6E,1539
|
|
13
14
|
doc_page_extractor/rotation.py,sha256=QCZ-HqfDxIhnQw8KRHki2myj6-UusvNY7Mpjsu-wI-4,4334
|
|
14
|
-
doc_page_extractor/
|
|
15
|
-
doc_page_extractor/
|
|
15
|
+
doc_page_extractor/table.py,sha256=AWymTRbOet55uImW8QJqb90Qs_v2V2U1mZv0U6rSz3c,1891
|
|
16
|
+
doc_page_extractor/types.py,sha256=7blT8YNKrOsc4qQdAhM7J7MEQjFcBwE0QV8-lipZBeQ,1305
|
|
17
|
+
doc_page_extractor/utils.py,sha256=ZlQVOLPUg_v5J8u6SoD8XtMG_JkF-ERgjubc4LO5_Lg,688
|
|
16
18
|
doc_page_extractor/onnxocr/__init__.py,sha256=BK4YpX4pU0nRxbcI5f5cbIVfdBEsx4W980QYmpNQaH0,38
|
|
17
19
|
doc_page_extractor/onnxocr/cls_postprocess.py,sha256=o879Ned0RMUERYLviuToZ0xTvhn2UsYAb-yPC5gj8h4,822
|
|
18
20
|
doc_page_extractor/onnxocr/db_postprocess.py,sha256=R3yXXfReiQgLaYIvvfnrFfshI202LjHMvcZwcLpjmTY,7913
|
|
@@ -25,10 +27,18 @@ doc_page_extractor/onnxocr/predict_rec.py,sha256=qQrCs5jzCf5PYp-iEKJ53pcx_xRoJdJ
|
|
|
25
27
|
doc_page_extractor/onnxocr/predict_system.py,sha256=yoqXunAsoboPsWe7qQjvQf2_SMW1T1QMriEoiGdX3BM,2721
|
|
26
28
|
doc_page_extractor/onnxocr/rec_postprocess.py,sha256=qZt5Ripal7z9hniKq5e7azOkD9e6NR1ylWpRpznhweg,29556
|
|
27
29
|
doc_page_extractor/onnxocr/utils.py,sha256=AQoHgQyv-jpPo4BsVzq3r7_ze698EZ-a7LJobm2fwUI,1864
|
|
28
|
-
doc_page_extractor
|
|
30
|
+
doc_page_extractor/struct_eqtable/__init__.py,sha256=QoTsNuJfpNSrMIMd6Cot1jJqWk88_lDqFP_C2rcVJO4,1329
|
|
31
|
+
doc_page_extractor/struct_eqtable/internvl/__init__.py,sha256=2aOsU-aHkFv_gjdP8LeUXjj_9-0d4x79iyxh4cCzaEw,79
|
|
32
|
+
doc_page_extractor/struct_eqtable/internvl/conversation.py,sha256=s7DceRlM6JtHmxgyuE6vqu5XVT1fHzhzCL_I6r8MI1c,15129
|
|
33
|
+
doc_page_extractor/struct_eqtable/internvl/internvl.py,sha256=ovVZG-PuBrsj_9lEoNPOygJ-2en3v6gPzRfWjDpWNOM,7678
|
|
34
|
+
doc_page_extractor/struct_eqtable/internvl/internvl_lmdeploy.py,sha256=ACHxFntxS38G43PzE955Nv4fjKk_-Oz4y_o9JEjQwlg,2608
|
|
35
|
+
doc_page_extractor/struct_eqtable/pix2s/__init__.py,sha256=cXRo4eg6u1-TXktZ8rQf0HIzLmmScIwYQhbxMKl-MyA,76
|
|
36
|
+
doc_page_extractor/struct_eqtable/pix2s/pix2s.py,sha256=fCNve8PNeJ3-AWJIhSeGtp-mYKoMXfW0CIpszkQnAaA,2535
|
|
37
|
+
doc_page_extractor/struct_eqtable/pix2s/pix2s_trt.py,sha256=zSGw45JhWdZ3iuJel5Chsy-NzsOHx9QyPQIUAzzCjFE,43880
|
|
38
|
+
doc_page_extractor-0.1.0.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
|
|
29
39
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
40
|
tests/test_history_bus.py,sha256=WaCUW3U75SESMcLq0f5FKnpVUVRDvmfxLFE7Zo83e48,2517
|
|
31
|
-
doc_page_extractor-0.0.
|
|
32
|
-
doc_page_extractor-0.0.
|
|
33
|
-
doc_page_extractor-0.0.
|
|
34
|
-
doc_page_extractor-0.0.
|
|
41
|
+
doc_page_extractor-0.1.0.dist-info/METADATA,sha256=8AM05x2gY75j70rD2HNi5zyaKE1okNJG7Pw5iLuIlnQ,2436
|
|
42
|
+
doc_page_extractor-0.1.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
43
|
+
doc_page_extractor-0.1.0.dist-info/top_level.txt,sha256=ErNybD_lBzAmw8mVBAK4htsAH_hp14jioZVex-tUqvM,25
|
|
44
|
+
doc_page_extractor-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|