docling 2.69.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 docling might be problematic. Click here for more details.

Files changed (138) hide show
  1. docling/__init__.py +0 -0
  2. docling/backend/__init__.py +0 -0
  3. docling/backend/abstract_backend.py +84 -0
  4. docling/backend/asciidoc_backend.py +443 -0
  5. docling/backend/csv_backend.py +125 -0
  6. docling/backend/docling_parse_backend.py +237 -0
  7. docling/backend/docling_parse_v2_backend.py +276 -0
  8. docling/backend/docling_parse_v4_backend.py +260 -0
  9. docling/backend/docx/__init__.py +0 -0
  10. docling/backend/docx/drawingml/utils.py +131 -0
  11. docling/backend/docx/latex/__init__.py +0 -0
  12. docling/backend/docx/latex/latex_dict.py +274 -0
  13. docling/backend/docx/latex/omml.py +459 -0
  14. docling/backend/html_backend.py +1502 -0
  15. docling/backend/image_backend.py +188 -0
  16. docling/backend/json/__init__.py +0 -0
  17. docling/backend/json/docling_json_backend.py +58 -0
  18. docling/backend/md_backend.py +618 -0
  19. docling/backend/mets_gbs_backend.py +399 -0
  20. docling/backend/msexcel_backend.py +686 -0
  21. docling/backend/mspowerpoint_backend.py +398 -0
  22. docling/backend/msword_backend.py +1663 -0
  23. docling/backend/noop_backend.py +51 -0
  24. docling/backend/pdf_backend.py +82 -0
  25. docling/backend/pypdfium2_backend.py +417 -0
  26. docling/backend/webvtt_backend.py +572 -0
  27. docling/backend/xml/__init__.py +0 -0
  28. docling/backend/xml/jats_backend.py +819 -0
  29. docling/backend/xml/uspto_backend.py +1905 -0
  30. docling/chunking/__init__.py +12 -0
  31. docling/cli/__init__.py +0 -0
  32. docling/cli/main.py +974 -0
  33. docling/cli/models.py +196 -0
  34. docling/cli/tools.py +17 -0
  35. docling/datamodel/__init__.py +0 -0
  36. docling/datamodel/accelerator_options.py +69 -0
  37. docling/datamodel/asr_model_specs.py +494 -0
  38. docling/datamodel/backend_options.py +102 -0
  39. docling/datamodel/base_models.py +493 -0
  40. docling/datamodel/document.py +699 -0
  41. docling/datamodel/extraction.py +39 -0
  42. docling/datamodel/layout_model_specs.py +91 -0
  43. docling/datamodel/pipeline_options.py +457 -0
  44. docling/datamodel/pipeline_options_asr_model.py +78 -0
  45. docling/datamodel/pipeline_options_vlm_model.py +136 -0
  46. docling/datamodel/settings.py +65 -0
  47. docling/datamodel/vlm_model_specs.py +365 -0
  48. docling/document_converter.py +559 -0
  49. docling/document_extractor.py +327 -0
  50. docling/exceptions.py +10 -0
  51. docling/experimental/__init__.py +5 -0
  52. docling/experimental/datamodel/__init__.py +1 -0
  53. docling/experimental/datamodel/table_crops_layout_options.py +13 -0
  54. docling/experimental/datamodel/threaded_layout_vlm_pipeline_options.py +45 -0
  55. docling/experimental/models/__init__.py +3 -0
  56. docling/experimental/models/table_crops_layout_model.py +114 -0
  57. docling/experimental/pipeline/__init__.py +1 -0
  58. docling/experimental/pipeline/threaded_layout_vlm_pipeline.py +439 -0
  59. docling/models/__init__.py +0 -0
  60. docling/models/base_layout_model.py +39 -0
  61. docling/models/base_model.py +230 -0
  62. docling/models/base_ocr_model.py +241 -0
  63. docling/models/base_table_model.py +45 -0
  64. docling/models/extraction/__init__.py +0 -0
  65. docling/models/extraction/nuextract_transformers_model.py +305 -0
  66. docling/models/factories/__init__.py +47 -0
  67. docling/models/factories/base_factory.py +122 -0
  68. docling/models/factories/layout_factory.py +7 -0
  69. docling/models/factories/ocr_factory.py +11 -0
  70. docling/models/factories/picture_description_factory.py +11 -0
  71. docling/models/factories/table_factory.py +7 -0
  72. docling/models/picture_description_base_model.py +149 -0
  73. docling/models/plugins/__init__.py +0 -0
  74. docling/models/plugins/defaults.py +60 -0
  75. docling/models/stages/__init__.py +0 -0
  76. docling/models/stages/code_formula/__init__.py +0 -0
  77. docling/models/stages/code_formula/code_formula_model.py +342 -0
  78. docling/models/stages/layout/__init__.py +0 -0
  79. docling/models/stages/layout/layout_model.py +249 -0
  80. docling/models/stages/ocr/__init__.py +0 -0
  81. docling/models/stages/ocr/auto_ocr_model.py +132 -0
  82. docling/models/stages/ocr/easyocr_model.py +200 -0
  83. docling/models/stages/ocr/ocr_mac_model.py +145 -0
  84. docling/models/stages/ocr/rapid_ocr_model.py +328 -0
  85. docling/models/stages/ocr/tesseract_ocr_cli_model.py +331 -0
  86. docling/models/stages/ocr/tesseract_ocr_model.py +262 -0
  87. docling/models/stages/page_assemble/__init__.py +0 -0
  88. docling/models/stages/page_assemble/page_assemble_model.py +156 -0
  89. docling/models/stages/page_preprocessing/__init__.py +0 -0
  90. docling/models/stages/page_preprocessing/page_preprocessing_model.py +145 -0
  91. docling/models/stages/picture_classifier/__init__.py +0 -0
  92. docling/models/stages/picture_classifier/document_picture_classifier.py +246 -0
  93. docling/models/stages/picture_description/__init__.py +0 -0
  94. docling/models/stages/picture_description/picture_description_api_model.py +66 -0
  95. docling/models/stages/picture_description/picture_description_vlm_model.py +123 -0
  96. docling/models/stages/reading_order/__init__.py +0 -0
  97. docling/models/stages/reading_order/readingorder_model.py +431 -0
  98. docling/models/stages/table_structure/__init__.py +0 -0
  99. docling/models/stages/table_structure/table_structure_model.py +305 -0
  100. docling/models/utils/__init__.py +0 -0
  101. docling/models/utils/generation_utils.py +157 -0
  102. docling/models/utils/hf_model_download.py +45 -0
  103. docling/models/vlm_pipeline_models/__init__.py +1 -0
  104. docling/models/vlm_pipeline_models/api_vlm_model.py +180 -0
  105. docling/models/vlm_pipeline_models/hf_transformers_model.py +391 -0
  106. docling/models/vlm_pipeline_models/mlx_model.py +325 -0
  107. docling/models/vlm_pipeline_models/vllm_model.py +344 -0
  108. docling/pipeline/__init__.py +0 -0
  109. docling/pipeline/asr_pipeline.py +431 -0
  110. docling/pipeline/base_extraction_pipeline.py +72 -0
  111. docling/pipeline/base_pipeline.py +326 -0
  112. docling/pipeline/extraction_vlm_pipeline.py +207 -0
  113. docling/pipeline/legacy_standard_pdf_pipeline.py +262 -0
  114. docling/pipeline/simple_pipeline.py +55 -0
  115. docling/pipeline/standard_pdf_pipeline.py +859 -0
  116. docling/pipeline/threaded_standard_pdf_pipeline.py +5 -0
  117. docling/pipeline/vlm_pipeline.py +416 -0
  118. docling/py.typed +1 -0
  119. docling/utils/__init__.py +0 -0
  120. docling/utils/accelerator_utils.py +97 -0
  121. docling/utils/api_image_request.py +205 -0
  122. docling/utils/deepseekocr_utils.py +388 -0
  123. docling/utils/export.py +146 -0
  124. docling/utils/glm_utils.py +361 -0
  125. docling/utils/layout_postprocessor.py +683 -0
  126. docling/utils/locks.py +3 -0
  127. docling/utils/model_downloader.py +168 -0
  128. docling/utils/ocr_utils.py +69 -0
  129. docling/utils/orientation.py +65 -0
  130. docling/utils/profiling.py +65 -0
  131. docling/utils/utils.py +65 -0
  132. docling/utils/visualization.py +85 -0
  133. docling-2.69.0.dist-info/METADATA +237 -0
  134. docling-2.69.0.dist-info/RECORD +138 -0
  135. docling-2.69.0.dist-info/WHEEL +5 -0
  136. docling-2.69.0.dist-info/entry_points.txt +6 -0
  137. docling-2.69.0.dist-info/licenses/LICENSE +21 -0
  138. docling-2.69.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,132 @@
1
+ import logging
2
+ import sys
3
+ from collections.abc import Iterable
4
+ from pathlib import Path
5
+ from typing import Optional, Type
6
+
7
+ from docling.datamodel.accelerator_options import AcceleratorOptions
8
+ from docling.datamodel.base_models import Page
9
+ from docling.datamodel.document import ConversionResult
10
+ from docling.datamodel.pipeline_options import (
11
+ EasyOcrOptions,
12
+ OcrAutoOptions,
13
+ OcrMacOptions,
14
+ OcrOptions,
15
+ RapidOcrOptions,
16
+ )
17
+ from docling.models.base_ocr_model import BaseOcrModel
18
+ from docling.models.stages.ocr.easyocr_model import EasyOcrModel
19
+ from docling.models.stages.ocr.ocr_mac_model import OcrMacModel
20
+ from docling.models.stages.ocr.rapid_ocr_model import RapidOcrModel
21
+
22
+ _log = logging.getLogger(__name__)
23
+
24
+
25
+ class OcrAutoModel(BaseOcrModel):
26
+ def __init__(
27
+ self,
28
+ enabled: bool,
29
+ artifacts_path: Optional[Path],
30
+ options: OcrAutoOptions,
31
+ accelerator_options: AcceleratorOptions,
32
+ ):
33
+ super().__init__(
34
+ enabled=enabled,
35
+ artifacts_path=artifacts_path,
36
+ options=options,
37
+ accelerator_options=accelerator_options,
38
+ )
39
+ self.options: OcrAutoOptions
40
+
41
+ self._engine: Optional[BaseOcrModel] = None
42
+ if self.enabled:
43
+ if "darwin" == sys.platform:
44
+ try:
45
+ from ocrmac import ocrmac
46
+
47
+ self._engine = OcrMacModel(
48
+ enabled=self.enabled,
49
+ artifacts_path=artifacts_path,
50
+ options=OcrMacOptions(
51
+ bitmap_area_threshold=self.options.bitmap_area_threshold,
52
+ force_full_page_ocr=self.options.force_full_page_ocr,
53
+ ),
54
+ accelerator_options=accelerator_options,
55
+ )
56
+ _log.info("Auto OCR model selected ocrmac.")
57
+ except ImportError:
58
+ _log.info("ocrmac cannot be used because ocrmac is not installed.")
59
+
60
+ if self._engine is None:
61
+ try:
62
+ import onnxruntime
63
+ from rapidocr import EngineType, RapidOCR # type: ignore
64
+
65
+ self._engine = RapidOcrModel(
66
+ enabled=self.enabled,
67
+ artifacts_path=artifacts_path,
68
+ options=RapidOcrOptions(
69
+ backend="onnxruntime",
70
+ bitmap_area_threshold=self.options.bitmap_area_threshold,
71
+ force_full_page_ocr=self.options.force_full_page_ocr,
72
+ ),
73
+ accelerator_options=accelerator_options,
74
+ )
75
+ _log.info("Auto OCR model selected rapidocr with onnxruntime.")
76
+ except ImportError:
77
+ _log.info(
78
+ "rapidocr cannot be used because onnxruntime is not installed."
79
+ )
80
+
81
+ if self._engine is None:
82
+ try:
83
+ import easyocr
84
+
85
+ self._engine = EasyOcrModel(
86
+ enabled=self.enabled,
87
+ artifacts_path=artifacts_path,
88
+ options=EasyOcrOptions(
89
+ bitmap_area_threshold=self.options.bitmap_area_threshold,
90
+ force_full_page_ocr=self.options.force_full_page_ocr,
91
+ ),
92
+ accelerator_options=accelerator_options,
93
+ )
94
+ _log.info("Auto OCR model selected easyocr.")
95
+ except ImportError:
96
+ _log.info("easyocr cannot be used because it is not installed.")
97
+
98
+ if self._engine is None:
99
+ try:
100
+ import torch
101
+ from rapidocr import EngineType, RapidOCR # type: ignore
102
+
103
+ self._engine = RapidOcrModel(
104
+ enabled=self.enabled,
105
+ artifacts_path=artifacts_path,
106
+ options=RapidOcrOptions(
107
+ backend="torch",
108
+ bitmap_area_threshold=self.options.bitmap_area_threshold,
109
+ force_full_page_ocr=self.options.force_full_page_ocr,
110
+ ),
111
+ accelerator_options=accelerator_options,
112
+ )
113
+ _log.info("Auto OCR model selected rapidocr with torch.")
114
+ except ImportError:
115
+ _log.info(
116
+ "rapidocr cannot be used because rapidocr or torch is not installed."
117
+ )
118
+
119
+ if self._engine is None:
120
+ _log.warning("No OCR engine found. Please review the install details.")
121
+
122
+ def __call__(
123
+ self, conv_res: ConversionResult, page_batch: Iterable[Page]
124
+ ) -> Iterable[Page]:
125
+ if not self.enabled or self._engine is None:
126
+ yield from page_batch
127
+ return
128
+ yield from self._engine(conv_res, page_batch)
129
+
130
+ @classmethod
131
+ def get_options_type(cls) -> Type[OcrOptions]:
132
+ return OcrAutoOptions
@@ -0,0 +1,200 @@
1
+ import logging
2
+ import warnings
3
+ import zipfile
4
+ from collections.abc import Iterable
5
+ from pathlib import Path
6
+ from typing import List, Optional, Type
7
+
8
+ import numpy
9
+ from docling_core.types.doc import BoundingBox, CoordOrigin
10
+ from docling_core.types.doc.page import BoundingRectangle, TextCell
11
+
12
+ from docling.datamodel.accelerator_options import AcceleratorDevice, AcceleratorOptions
13
+ from docling.datamodel.base_models import Page
14
+ from docling.datamodel.document import ConversionResult
15
+ from docling.datamodel.pipeline_options import (
16
+ EasyOcrOptions,
17
+ OcrOptions,
18
+ )
19
+ from docling.datamodel.settings import settings
20
+ from docling.models.base_ocr_model import BaseOcrModel
21
+ from docling.utils.accelerator_utils import decide_device
22
+ from docling.utils.profiling import TimeRecorder
23
+ from docling.utils.utils import download_url_with_progress
24
+
25
+ _log = logging.getLogger(__name__)
26
+
27
+
28
+ class EasyOcrModel(BaseOcrModel):
29
+ _model_repo_folder = "EasyOcr"
30
+
31
+ def __init__(
32
+ self,
33
+ enabled: bool,
34
+ artifacts_path: Optional[Path],
35
+ options: EasyOcrOptions,
36
+ accelerator_options: AcceleratorOptions,
37
+ ):
38
+ super().__init__(
39
+ enabled=enabled,
40
+ artifacts_path=artifacts_path,
41
+ options=options,
42
+ accelerator_options=accelerator_options,
43
+ )
44
+ self.options: EasyOcrOptions
45
+
46
+ self.scale = 3 # multiplier for 72 dpi == 216 dpi.
47
+
48
+ if self.enabled:
49
+ try:
50
+ import easyocr
51
+ except ImportError:
52
+ raise ImportError(
53
+ "EasyOCR is not installed. Please install it via `pip install easyocr` to use this OCR engine. "
54
+ "Alternatively, Docling has support for other OCR engines. See the documentation."
55
+ )
56
+
57
+ if self.options.use_gpu is None:
58
+ device = decide_device(accelerator_options.device)
59
+ # Enable easyocr GPU if running on CUDA, MPS
60
+ use_gpu = any(
61
+ device.startswith(x)
62
+ for x in [
63
+ AcceleratorDevice.CUDA.value,
64
+ AcceleratorDevice.MPS.value,
65
+ ]
66
+ )
67
+ else:
68
+ warnings.warn(
69
+ "Deprecated field. Better to set the `accelerator_options.device` in `pipeline_options`. "
70
+ "When `use_gpu and accelerator_options.device == AcceleratorDevice.CUDA` the GPU is used "
71
+ "to run EasyOCR. Otherwise, EasyOCR runs in CPU."
72
+ )
73
+ use_gpu = self.options.use_gpu
74
+
75
+ download_enabled = self.options.download_enabled
76
+ model_storage_directory = self.options.model_storage_directory
77
+ if artifacts_path is not None and model_storage_directory is None:
78
+ download_enabled = False
79
+ model_storage_directory = str(artifacts_path / self._model_repo_folder)
80
+
81
+ with warnings.catch_warnings():
82
+ if self.options.suppress_mps_warnings:
83
+ warnings.filterwarnings("ignore", message=".*pin_memory.*MPS.*")
84
+ self.reader = easyocr.Reader(
85
+ lang_list=self.options.lang,
86
+ gpu=use_gpu,
87
+ model_storage_directory=model_storage_directory,
88
+ recog_network=self.options.recog_network,
89
+ download_enabled=download_enabled,
90
+ verbose=False,
91
+ )
92
+
93
+ @staticmethod
94
+ def download_models(
95
+ detection_models: List[str] = ["craft"],
96
+ recognition_models: List[str] = ["english_g2", "latin_g2"],
97
+ local_dir: Optional[Path] = None,
98
+ force: bool = False,
99
+ progress: bool = False,
100
+ ) -> Path:
101
+ # Models are located in https://github.com/JaidedAI/EasyOCR/blob/master/easyocr/config.py
102
+ from easyocr.config import (
103
+ detection_models as det_models_dict,
104
+ recognition_models as rec_models_dict,
105
+ )
106
+
107
+ if local_dir is None:
108
+ local_dir = settings.cache_dir / "models" / EasyOcrModel._model_repo_folder
109
+
110
+ local_dir.mkdir(parents=True, exist_ok=True)
111
+
112
+ # Collect models to download
113
+ download_list = []
114
+ for model_name in detection_models:
115
+ if model_name in det_models_dict:
116
+ download_list.append(det_models_dict[model_name])
117
+ for model_name in recognition_models:
118
+ if model_name in rec_models_dict["gen2"]:
119
+ download_list.append(rec_models_dict["gen2"][model_name])
120
+
121
+ # Download models
122
+ for model_details in download_list:
123
+ buf = download_url_with_progress(model_details["url"], progress=progress)
124
+ with zipfile.ZipFile(buf, "r") as zip_ref:
125
+ zip_ref.extractall(local_dir)
126
+
127
+ return local_dir
128
+
129
+ def __call__(
130
+ self, conv_res: ConversionResult, page_batch: Iterable[Page]
131
+ ) -> Iterable[Page]:
132
+ if not self.enabled:
133
+ yield from page_batch
134
+ return
135
+
136
+ for page in page_batch:
137
+ assert page._backend is not None
138
+ if not page._backend.is_valid():
139
+ yield page
140
+ else:
141
+ with TimeRecorder(conv_res, "ocr"):
142
+ ocr_rects = self.get_ocr_rects(page)
143
+
144
+ all_ocr_cells = []
145
+ for ocr_rect in ocr_rects:
146
+ # Skip zero area boxes
147
+ if ocr_rect.area() == 0:
148
+ continue
149
+ high_res_image = page._backend.get_page_image(
150
+ scale=self.scale, cropbox=ocr_rect
151
+ )
152
+ im = numpy.array(high_res_image)
153
+
154
+ with warnings.catch_warnings():
155
+ if self.options.suppress_mps_warnings:
156
+ warnings.filterwarnings(
157
+ "ignore", message=".*pin_memory.*MPS.*"
158
+ )
159
+
160
+ result = self.reader.readtext(im)
161
+
162
+ del high_res_image
163
+ del im
164
+
165
+ cells = [
166
+ TextCell(
167
+ index=ix,
168
+ text=line[1],
169
+ orig=line[1],
170
+ from_ocr=True,
171
+ confidence=line[2],
172
+ rect=BoundingRectangle.from_bounding_box(
173
+ BoundingBox.from_tuple(
174
+ coord=(
175
+ (line[0][0][0] / self.scale) + ocr_rect.l,
176
+ (line[0][0][1] / self.scale) + ocr_rect.t,
177
+ (line[0][2][0] / self.scale) + ocr_rect.l,
178
+ (line[0][2][1] / self.scale) + ocr_rect.t,
179
+ ),
180
+ origin=CoordOrigin.TOPLEFT,
181
+ )
182
+ ),
183
+ )
184
+ for ix, line in enumerate(result)
185
+ if line[2] >= self.options.confidence_threshold
186
+ ]
187
+ all_ocr_cells.extend(cells)
188
+
189
+ # Post-process the cells
190
+ self.post_process_cells(all_ocr_cells, page)
191
+
192
+ # DEBUG code:
193
+ if settings.debug.visualize_ocr:
194
+ self.draw_ocr_rects_and_cells(conv_res, page, ocr_rects)
195
+
196
+ yield page
197
+
198
+ @classmethod
199
+ def get_options_type(cls) -> Type[OcrOptions]:
200
+ return EasyOcrOptions
@@ -0,0 +1,145 @@
1
+ import logging
2
+ import sys
3
+ import tempfile
4
+ from collections.abc import Iterable
5
+ from pathlib import Path
6
+ from typing import Optional, Type
7
+
8
+ from docling_core.types.doc import BoundingBox, CoordOrigin
9
+ from docling_core.types.doc.page import BoundingRectangle, TextCell
10
+
11
+ from docling.datamodel.accelerator_options import AcceleratorOptions
12
+ from docling.datamodel.base_models import Page
13
+ from docling.datamodel.document import ConversionResult
14
+ from docling.datamodel.pipeline_options import (
15
+ OcrMacOptions,
16
+ OcrOptions,
17
+ )
18
+ from docling.datamodel.settings import settings
19
+ from docling.models.base_ocr_model import BaseOcrModel
20
+ from docling.utils.profiling import TimeRecorder
21
+
22
+ _log = logging.getLogger(__name__)
23
+
24
+
25
+ class OcrMacModel(BaseOcrModel):
26
+ def __init__(
27
+ self,
28
+ enabled: bool,
29
+ artifacts_path: Optional[Path],
30
+ options: OcrMacOptions,
31
+ accelerator_options: AcceleratorOptions,
32
+ ):
33
+ super().__init__(
34
+ enabled=enabled,
35
+ artifacts_path=artifacts_path,
36
+ options=options,
37
+ accelerator_options=accelerator_options,
38
+ )
39
+ self.options: OcrMacOptions
40
+
41
+ self.scale = 3 # multiplier for 72 dpi == 216 dpi.
42
+
43
+ if self.enabled:
44
+ if "darwin" != sys.platform:
45
+ raise RuntimeError("OcrMac is only supported on Mac.")
46
+ install_errmsg = (
47
+ "ocrmac is not correctly installed. "
48
+ "Please install it via `pip install ocrmac` to use this OCR engine. "
49
+ "Alternatively, Docling has support for other OCR engines. See the documentation: "
50
+ "https://docling-project.github.io/docling/installation/"
51
+ )
52
+ try:
53
+ from ocrmac import ocrmac
54
+ except ImportError:
55
+ raise ImportError(install_errmsg)
56
+
57
+ self.reader_RIL = ocrmac.OCR
58
+
59
+ def __call__(
60
+ self, conv_res: ConversionResult, page_batch: Iterable[Page]
61
+ ) -> Iterable[Page]:
62
+ if not self.enabled:
63
+ yield from page_batch
64
+ return
65
+
66
+ for page in page_batch:
67
+ assert page._backend is not None
68
+ if not page._backend.is_valid():
69
+ yield page
70
+ else:
71
+ with TimeRecorder(conv_res, "ocr"):
72
+ ocr_rects = self.get_ocr_rects(page)
73
+
74
+ all_ocr_cells = []
75
+ for ocr_rect in ocr_rects:
76
+ # Skip zero area boxes
77
+ if ocr_rect.area() == 0:
78
+ continue
79
+ high_res_image = page._backend.get_page_image(
80
+ scale=self.scale, cropbox=ocr_rect
81
+ )
82
+
83
+ with tempfile.NamedTemporaryFile(
84
+ suffix=".png", mode="w"
85
+ ) as image_file:
86
+ fname = image_file.name
87
+ high_res_image.save(fname)
88
+
89
+ boxes = self.reader_RIL(
90
+ fname,
91
+ recognition_level=self.options.recognition,
92
+ framework=self.options.framework,
93
+ language_preference=self.options.lang,
94
+ ).recognize()
95
+
96
+ im_width, im_height = high_res_image.size
97
+ cells = []
98
+ for ix, (text, confidence, box) in enumerate(boxes):
99
+ x = float(box[0])
100
+ y = float(box[1])
101
+ w = float(box[2])
102
+ h = float(box[3])
103
+
104
+ x1 = x * im_width
105
+ y2 = (1 - y) * im_height
106
+
107
+ x2 = x1 + w * im_width
108
+ y1 = y2 - h * im_height
109
+
110
+ left = x1 / self.scale
111
+ top = y1 / self.scale
112
+ right = x2 / self.scale
113
+ bottom = y2 / self.scale
114
+
115
+ cells.append(
116
+ TextCell(
117
+ index=ix,
118
+ text=text,
119
+ orig=text,
120
+ from_ocr=True,
121
+ confidence=confidence,
122
+ rect=BoundingRectangle.from_bounding_box(
123
+ BoundingBox.from_tuple(
124
+ coord=(left, top, right, bottom),
125
+ origin=CoordOrigin.TOPLEFT,
126
+ )
127
+ ),
128
+ )
129
+ )
130
+
131
+ # del high_res_image
132
+ all_ocr_cells.extend(cells)
133
+
134
+ # Post-process the cells
135
+ self.post_process_cells(all_ocr_cells, page)
136
+
137
+ # DEBUG code:
138
+ if settings.debug.visualize_ocr:
139
+ self.draw_ocr_rects_and_cells(conv_res, page, ocr_rects)
140
+
141
+ yield page
142
+
143
+ @classmethod
144
+ def get_options_type(cls) -> Type[OcrOptions]:
145
+ return OcrMacOptions