onnxtr 0.5.0__tar.gz → 0.5.1__tar.gz

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.
Files changed (83) hide show
  1. {onnxtr-0.5.0 → onnxtr-0.5.1}/PKG-INFO +2 -1
  2. {onnxtr-0.5.0 → onnxtr-0.5.1}/README.md +1 -0
  3. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/elements.py +11 -3
  4. onnxtr-0.5.1/onnxtr/utils/reconstitution.py +173 -0
  5. onnxtr-0.5.1/onnxtr/version.py +1 -0
  6. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/PKG-INFO +2 -1
  7. {onnxtr-0.5.0 → onnxtr-0.5.1}/pyproject.toml +2 -1
  8. {onnxtr-0.5.0 → onnxtr-0.5.1}/setup.py +1 -1
  9. onnxtr-0.5.0/onnxtr/utils/reconstitution.py +0 -70
  10. onnxtr-0.5.0/onnxtr/version.py +0 -1
  11. {onnxtr-0.5.0 → onnxtr-0.5.1}/LICENSE +0 -0
  12. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/__init__.py +0 -0
  13. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/contrib/__init__.py +0 -0
  14. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/contrib/artefacts.py +0 -0
  15. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/contrib/base.py +0 -0
  16. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/file_utils.py +0 -0
  17. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/__init__.py +0 -0
  18. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/html.py +0 -0
  19. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/image.py +0 -0
  20. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/pdf.py +0 -0
  21. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/io/reader.py +0 -0
  22. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/__init__.py +0 -0
  23. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/_utils.py +0 -0
  24. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/builder.py +0 -0
  25. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/__init__.py +0 -0
  26. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/models/__init__.py +0 -0
  27. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/models/mobilenet.py +0 -0
  28. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/predictor/__init__.py +0 -0
  29. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/predictor/base.py +0 -0
  30. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/classification/zoo.py +0 -0
  31. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/__init__.py +0 -0
  32. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/_utils/__init__.py +0 -0
  33. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/_utils/base.py +0 -0
  34. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/core.py +0 -0
  35. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/models/__init__.py +0 -0
  36. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/models/differentiable_binarization.py +0 -0
  37. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/models/fast.py +0 -0
  38. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/models/linknet.py +0 -0
  39. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/postprocessor/__init__.py +0 -0
  40. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/postprocessor/base.py +0 -0
  41. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/predictor/__init__.py +0 -0
  42. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/predictor/base.py +0 -0
  43. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/detection/zoo.py +0 -0
  44. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/engine.py +0 -0
  45. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/factory/__init__.py +0 -0
  46. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/factory/hub.py +0 -0
  47. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/predictor/__init__.py +0 -0
  48. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/predictor/base.py +0 -0
  49. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/predictor/predictor.py +0 -0
  50. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/preprocessor/__init__.py +0 -0
  51. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/preprocessor/base.py +0 -0
  52. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/__init__.py +0 -0
  53. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/core.py +0 -0
  54. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/__init__.py +0 -0
  55. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/crnn.py +0 -0
  56. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/master.py +0 -0
  57. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/parseq.py +0 -0
  58. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/sar.py +0 -0
  59. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/models/vitstr.py +0 -0
  60. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/predictor/__init__.py +0 -0
  61. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/predictor/_utils.py +0 -0
  62. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/predictor/base.py +0 -0
  63. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/utils.py +0 -0
  64. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/recognition/zoo.py +0 -0
  65. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/models/zoo.py +0 -0
  66. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/py.typed +0 -0
  67. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/transforms/__init__.py +0 -0
  68. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/transforms/base.py +0 -0
  69. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/__init__.py +0 -0
  70. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/common_types.py +0 -0
  71. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/data.py +0 -0
  72. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/fonts.py +0 -0
  73. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/geometry.py +0 -0
  74. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/multithreading.py +0 -0
  75. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/repr.py +0 -0
  76. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/visualization.py +0 -0
  77. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr/utils/vocabs.py +0 -0
  78. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/SOURCES.txt +0 -0
  79. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/dependency_links.txt +0 -0
  80. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/requires.txt +0 -0
  81. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/top_level.txt +0 -0
  82. {onnxtr-0.5.0 → onnxtr-0.5.1}/onnxtr.egg-info/zip-safe +0 -0
  83. {onnxtr-0.5.0 → onnxtr-0.5.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: onnxtr
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Onnx Text Recognition (OnnxTR): docTR Onnx-Wrapper for high-performance OCR on documents.
5
5
  Author-email: Felix Dittrich <felixdittrich92@gmail.com>
6
6
  Maintainer: Felix Dittrich
@@ -285,6 +285,7 @@ Requires-Dist: pre-commit>=2.17.0; extra == "dev"
285
285
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fff4d764bb14fb8b4f4afeb9587231b)](https://app.codacy.com/gh/felixdittrich92/OnnxTR/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
286
286
  [![CodeFactor](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr/badge)](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr)
287
287
  [![Pypi](https://img.shields.io/badge/pypi-v0.5.0-blue.svg)](https://pypi.org/project/OnnxTR/)
288
+ [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/Felix92/OnnxTR-OCR)
288
289
 
289
290
  > :warning: Please note that this is a wrapper around the [doctr](https://github.com/mindee/doctr) library to provide a Onnx pipeline for docTR. For feature requests, which are not directly related to the Onnx pipeline, please refer to the base project.
290
291
 
@@ -8,6 +8,7 @@
8
8
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fff4d764bb14fb8b4f4afeb9587231b)](https://app.codacy.com/gh/felixdittrich92/OnnxTR/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
9
9
  [![CodeFactor](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr/badge)](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr)
10
10
  [![Pypi](https://img.shields.io/badge/pypi-v0.5.0-blue.svg)](https://pypi.org/project/OnnxTR/)
11
+ [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/Felix92/OnnxTR-OCR)
11
12
 
12
13
  > :warning: Please note that this is a wrapper around the [doctr](https://github.com/mindee/doctr) library to provide a Onnx pipeline for docTR. For feature requests, which are not directly related to the Onnx pipeline, please refer to the base project.
13
14
 
@@ -163,7 +163,7 @@ class Line(Element):
163
163
  if geometry is None:
164
164
  # Check whether this is a rotated or straight box
165
165
  box_resolution_fn = resolve_enclosing_rbbox if len(words[0].geometry) == 4 else resolve_enclosing_bbox
166
- geometry = box_resolution_fn([w.geometry for w in words]) # type: ignore[operator]
166
+ geometry = box_resolution_fn([w.geometry for w in words]) # type: ignore[misc]
167
167
 
168
168
  super().__init__(words=words)
169
169
  self.geometry = geometry
@@ -216,7 +216,7 @@ class Block(Element):
216
216
  box_resolution_fn = (
217
217
  resolve_enclosing_rbbox if isinstance(lines[0].geometry, np.ndarray) else resolve_enclosing_bbox
218
218
  )
219
- geometry = box_resolution_fn(line_boxes + artefact_boxes) # type: ignore[operator]
219
+ geometry = box_resolution_fn(line_boxes + artefact_boxes) # type: ignore
220
220
 
221
221
  super().__init__(lines=lines, artefacts=artefacts)
222
222
  self.geometry = geometry
@@ -294,6 +294,10 @@ class Page(Element):
294
294
  def synthesize(self, **kwargs) -> np.ndarray:
295
295
  """Synthesize the page from the predictions
296
296
 
297
+ Args:
298
+ ----
299
+ **kwargs: keyword arguments passed to the `synthesize_page` method
300
+
297
301
  Returns
298
302
  -------
299
303
  synthesized page
@@ -442,11 +446,15 @@ class Document(Element):
442
446
  def synthesize(self, **kwargs) -> List[np.ndarray]:
443
447
  """Synthesize all pages from their predictions
444
448
 
449
+ Args:
450
+ ----
451
+ **kwargs: keyword arguments passed to the `Page.synthesize` method
452
+
445
453
  Returns
446
454
  -------
447
455
  list of synthesized pages
448
456
  """
449
- return [page.synthesize() for page in self.pages]
457
+ return [page.synthesize(**kwargs) for page in self.pages]
450
458
 
451
459
  def export_as_xml(self, **kwargs) -> List[Tuple[bytes, ET.ElementTree]]:
452
460
  """Export the document as XML (hOCR-format)
@@ -0,0 +1,173 @@
1
+ # Copyright (C) 2021-2024, Mindee | Felix Dittrich.
2
+
3
+ # This program is licensed under the Apache License 2.0.
4
+ # See LICENSE or go to <https://opensource.org/licenses/Apache-2.0> for full license details.
5
+ import logging
6
+ from typing import Any, Dict, Optional
7
+
8
+ import numpy as np
9
+ from anyascii import anyascii
10
+ from PIL import Image, ImageDraw
11
+
12
+ from .fonts import get_font
13
+
14
+ __all__ = ["synthesize_page"]
15
+
16
+
17
+ # Global variable to avoid multiple warnings
18
+ ROTATION_WARNING = False
19
+
20
+
21
+ def _warn_rotation(entry: Dict[str, Any]) -> None: # pragma: no cover
22
+ global ROTATION_WARNING
23
+ if not ROTATION_WARNING and len(entry["geometry"]) == 4:
24
+ logging.warning("Polygons with larger rotations will lead to inaccurate rendering")
25
+ ROTATION_WARNING = True
26
+
27
+
28
+ def _synthesize(
29
+ response: Image.Image,
30
+ entry: Dict[str, Any],
31
+ w: int,
32
+ h: int,
33
+ draw_proba: bool = False,
34
+ font_family: Optional[str] = None,
35
+ smoothing_factor: float = 0.75,
36
+ min_font_size: int = 6,
37
+ max_font_size: int = 50,
38
+ ) -> Image.Image:
39
+ if len(entry["geometry"]) == 2:
40
+ (xmin, ymin), (xmax, ymax) = entry["geometry"]
41
+ polygon = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]
42
+ else:
43
+ polygon = entry["geometry"]
44
+
45
+ # Calculate the bounding box of the word
46
+ x_coords, y_coords = zip(*polygon)
47
+ xmin, ymin, xmax, ymax = (
48
+ int(round(w * min(x_coords))),
49
+ int(round(h * min(y_coords))),
50
+ int(round(w * max(x_coords))),
51
+ int(round(h * max(y_coords))),
52
+ )
53
+ word_width = xmax - xmin
54
+ word_height = ymax - ymin
55
+
56
+ # If lines are provided instead of words, concatenate the word entries
57
+ if "words" in entry:
58
+ word_text = " ".join(word["value"] for word in entry["words"])
59
+ else:
60
+ word_text = entry["value"]
61
+ # Find the optimal font size
62
+ try:
63
+ font_size = min(word_height, max_font_size)
64
+ font = get_font(font_family, font_size)
65
+ text_width, text_height = font.getbbox(word_text)[2:4]
66
+
67
+ while (text_width > word_width or text_height > word_height) and font_size > min_font_size:
68
+ font_size = max(int(font_size * smoothing_factor), min_font_size)
69
+ font = get_font(font_family, font_size)
70
+ text_width, text_height = font.getbbox(word_text)[2:4]
71
+ except ValueError: # pragma: no cover
72
+ font = get_font(font_family, min_font_size)
73
+
74
+ # Create a mask for the word
75
+ mask = Image.new("L", (w, h), 0)
76
+ ImageDraw.Draw(mask).polygon([(int(round(w * x)), int(round(h * y))) for x, y in polygon], fill=255)
77
+
78
+ # Draw the word text
79
+ d = ImageDraw.Draw(response)
80
+ try:
81
+ try:
82
+ d.text((xmin, ymin), word_text, font=font, fill=(0, 0, 0), anchor="lt")
83
+ except UnicodeEncodeError: # pragma: no cover
84
+ d.text((xmin, ymin), anyascii(word_text), font=font, fill=(0, 0, 0), anchor="lt")
85
+ # Catch generic exceptions to avoid crashing the whole rendering
86
+ except Exception: # pragma: no cover
87
+ logging.warning(f"Could not render word: {word_text}")
88
+
89
+ if draw_proba:
90
+ confidence = (
91
+ entry["confidence"]
92
+ if "confidence" in entry
93
+ else sum(w["confidence"] for w in entry["words"]) / len(entry["words"])
94
+ )
95
+ p = int(255 * confidence)
96
+ color = (255 - p, 0, p) # Red to blue gradient based on probability
97
+ d.rectangle([(xmin, ymin), (xmax, ymax)], outline=color, width=2)
98
+
99
+ prob_font = get_font(font_family, 20)
100
+ prob_text = f"{confidence:.2f}"
101
+ prob_text_width, prob_text_height = prob_font.getbbox(prob_text)[2:4]
102
+
103
+ # Position the probability slightly above the bounding box
104
+ prob_x_offset = (word_width - prob_text_width) // 2
105
+ prob_y_offset = ymin - prob_text_height - 2
106
+ prob_y_offset = max(0, prob_y_offset)
107
+
108
+ d.text((xmin + prob_x_offset, prob_y_offset), prob_text, font=prob_font, fill=color, anchor="lt")
109
+
110
+ return response
111
+
112
+
113
+ def synthesize_page(
114
+ page: Dict[str, Any],
115
+ draw_proba: bool = False,
116
+ font_family: Optional[str] = None,
117
+ smoothing_factor: float = 0.95,
118
+ min_font_size: int = 8,
119
+ max_font_size: int = 50,
120
+ ) -> np.ndarray:
121
+ """Draw a the content of the element page (OCR response) on a blank page.
122
+
123
+ Args:
124
+ ----
125
+ page: exported Page object to represent
126
+ draw_proba: if True, draw words in colors to represent confidence. Blue: p=1, red: p=0
127
+ font_family: family of the font
128
+ smoothing_factor: factor to smooth the font size
129
+ min_font_size: minimum font size
130
+ max_font_size: maximum font size
131
+
132
+ Returns:
133
+ -------
134
+ the synthesized page
135
+ """
136
+ # Draw template
137
+ h, w = page["dimensions"]
138
+ response = Image.new("RGB", (w, h), color=(255, 255, 255))
139
+
140
+ for block in page["blocks"]:
141
+ # If lines are provided use these to get better rendering results
142
+ if len(block["lines"]) > 1:
143
+ for line in block["lines"]:
144
+ _warn_rotation(block) # pragma: no cover
145
+ response = _synthesize(
146
+ response=response,
147
+ entry=line,
148
+ w=w,
149
+ h=h,
150
+ draw_proba=draw_proba,
151
+ font_family=font_family,
152
+ smoothing_factor=smoothing_factor,
153
+ min_font_size=min_font_size,
154
+ max_font_size=max_font_size,
155
+ )
156
+ # Otherwise, draw each word
157
+ else:
158
+ for line in block["lines"]:
159
+ _warn_rotation(block) # pragma: no cover
160
+ for word in line["words"]:
161
+ response = _synthesize(
162
+ response=response,
163
+ entry=word,
164
+ w=w,
165
+ h=h,
166
+ draw_proba=draw_proba,
167
+ font_family=font_family,
168
+ smoothing_factor=smoothing_factor,
169
+ min_font_size=min_font_size,
170
+ max_font_size=max_font_size,
171
+ )
172
+
173
+ return np.array(response, dtype=np.uint8)
@@ -0,0 +1 @@
1
+ __version__ = 'v0.5.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: onnxtr
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Onnx Text Recognition (OnnxTR): docTR Onnx-Wrapper for high-performance OCR on documents.
5
5
  Author-email: Felix Dittrich <felixdittrich92@gmail.com>
6
6
  Maintainer: Felix Dittrich
@@ -285,6 +285,7 @@ Requires-Dist: pre-commit>=2.17.0; extra == "dev"
285
285
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fff4d764bb14fb8b4f4afeb9587231b)](https://app.codacy.com/gh/felixdittrich92/OnnxTR/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
286
286
  [![CodeFactor](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr/badge)](https://www.codefactor.io/repository/github/felixdittrich92/onnxtr)
287
287
  [![Pypi](https://img.shields.io/badge/pypi-v0.5.0-blue.svg)](https://pypi.org/project/OnnxTR/)
288
+ [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/Felix92/OnnxTR-OCR)
288
289
 
289
290
  > :warning: Please note that this is a wrapper around the [doctr](https://github.com/mindee/doctr) library to provide a Onnx pipeline for docTR. For feature requests, which are not directly related to the Onnx pipeline, please refer to the base project.
290
291
 
@@ -107,7 +107,7 @@ changelog = "https://github.com/felixdittrich92/OnnxTR/releases"
107
107
  zip-safe = true
108
108
 
109
109
  [tool.setuptools.packages.find]
110
- exclude = ["docs*", "tests*", "scripts*"]
110
+ exclude = ["docs*", "tests*", "scripts*", "demo*"]
111
111
 
112
112
  [tool.setuptools.package-data]
113
113
  onnxtr = ["py.typed"]
@@ -166,6 +166,7 @@ known-third-party = ["onnxruntime", "cv2"]
166
166
  "onnxtr/models/**.py" = ["N806", "F841"]
167
167
  "tests/**.py" = ["D"]
168
168
  "scripts/**.py" = ["D"]
169
+ "demo/**.py" = ["D"]
169
170
  ".github/**.py" = ["D"]
170
171
 
171
172
 
@@ -9,7 +9,7 @@ from pathlib import Path
9
9
  from setuptools import setup
10
10
 
11
11
  PKG_NAME = "onnxtr"
12
- VERSION = os.getenv("BUILD_VERSION", "0.5.0a0")
12
+ VERSION = os.getenv("BUILD_VERSION", "0.5.1a0")
13
13
 
14
14
 
15
15
  if __name__ == "__main__":
@@ -1,70 +0,0 @@
1
- # Copyright (C) 2021-2024, Mindee | Felix Dittrich.
2
-
3
- # This program is licensed under the Apache License 2.0.
4
- # See LICENSE or go to <https://opensource.org/licenses/Apache-2.0> for full license details.
5
- from typing import Any, Dict, Optional
6
-
7
- import numpy as np
8
- from anyascii import anyascii
9
- from PIL import Image, ImageDraw
10
-
11
- from .fonts import get_font
12
-
13
- __all__ = ["synthesize_page"]
14
-
15
-
16
- def synthesize_page(
17
- page: Dict[str, Any],
18
- draw_proba: bool = False,
19
- font_family: Optional[str] = None,
20
- ) -> np.ndarray:
21
- """Draw a the content of the element page (OCR response) on a blank page.
22
-
23
- Args:
24
- ----
25
- page: exported Page object to represent
26
- draw_proba: if True, draw words in colors to represent confidence. Blue: p=1, red: p=0
27
- font_size: size of the font, default font = 13
28
- font_family: family of the font
29
-
30
- Returns:
31
- -------
32
- the synthesized page
33
- """
34
- # Draw template
35
- h, w = page["dimensions"]
36
- response = 255 * np.ones((h, w, 3), dtype=np.int32)
37
-
38
- # Draw each word
39
- for block in page["blocks"]:
40
- for line in block["lines"]:
41
- for word in line["words"]:
42
- # Get absolute word geometry
43
- (xmin, ymin), (xmax, ymax) = word["geometry"]
44
- xmin, xmax = int(round(w * xmin)), int(round(w * xmax))
45
- ymin, ymax = int(round(h * ymin)), int(round(h * ymax))
46
-
47
- # White drawing context adapted to font size, 0.75 factor to convert pts --> pix
48
- font = get_font(font_family, int(0.75 * (ymax - ymin)))
49
- img = Image.new("RGB", (xmax - xmin, ymax - ymin), color=(255, 255, 255))
50
- d = ImageDraw.Draw(img)
51
- # Draw in black the value of the word
52
- try:
53
- d.text((0, 0), word["value"], font=font, fill=(0, 0, 0))
54
- except UnicodeEncodeError:
55
- # When character cannot be encoded, use its anyascii version
56
- d.text((0, 0), anyascii(word["value"]), font=font, fill=(0, 0, 0))
57
-
58
- # Colorize if draw_proba
59
- if draw_proba:
60
- p = int(255 * word["confidence"])
61
- mask = np.where(np.array(img) == 0, 1, 0)
62
- proba: np.ndarray = np.array([255 - p, 0, p])
63
- color = mask * proba[np.newaxis, np.newaxis, :]
64
- white_mask = 255 * (1 - mask)
65
- img = color + white_mask
66
-
67
- # Write to response page
68
- response[ymin:ymax, xmin:xmax, :] = np.array(img)
69
-
70
- return response
@@ -1 +0,0 @@
1
- __version__ = 'v0.5.0'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes