ocr-stream 2.3.8__tar.gz → 2.4.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.
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/PKG-INFO +2 -2
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream/__init__.py +72 -106
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream/recognize.py +47 -15
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream.egg-info/PKG-INFO +2 -2
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream.egg-info/requires.txt +1 -1
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/pyproject.toml +2 -2
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/README.md +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream/bin_tess/__init__.py +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream/modules/__init__.py +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream/ocr/__init__.py +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream.egg-info/SOURCES.txt +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream.egg-info/dependency_links.txt +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/ocr_stream.egg-info/top_level.txt +0 -0
- {ocr_stream-2.3.8 → ocr_stream-2.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ocr_stream
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Extrair textos de documentos digitalizados e imagens.
|
|
5
5
|
Author: Bruno Chaves
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pandas
|
|
|
12
12
|
Requires-Dist: requests>=2.32.4
|
|
13
13
|
Requires-Dist: opencv-python
|
|
14
14
|
Requires-Dist: pytesseract
|
|
15
|
-
Requires-Dist: convert_stream>=2.
|
|
15
|
+
Requires-Dist: convert_stream>=2.4.1
|
|
16
16
|
Requires-Dist: soup_files>=1.4
|
|
17
17
|
|
|
18
18
|
# ocrlib
|
|
@@ -1,64 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from io import BytesIO
|
|
4
|
-
import threading
|
|
5
4
|
from ocr_stream.modules import *
|
|
6
5
|
from ocr_stream.bin_tess import BinTesseract, get_path_tesseract_sys
|
|
7
6
|
from ocr_stream.ocr import TesseractOcr, TextRecognized
|
|
8
|
-
from ocr_stream.recognize import
|
|
9
|
-
|
|
10
|
-
from convert_stream.image import ImageObject, CollectionImages
|
|
11
|
-
from convert_stream.mod_types import (
|
|
12
|
-
ColumnsTable, ColumnBody, HeadCell, HeadValues, create_void_dict_map
|
|
7
|
+
from ocr_stream.recognize import (
|
|
8
|
+
RecognizeImage, RecognizePdf, VoidPbar, ProgressVoid
|
|
13
9
|
)
|
|
14
|
-
|
|
15
|
-
from convert_stream.text import FindText
|
|
16
|
-
from convert_stream.pdf import ConvertPdfToImages, CollectionPagePdf
|
|
10
|
+
import convert_stream as cs
|
|
17
11
|
import pandas as pd
|
|
18
|
-
|
|
19
|
-
JsonConvert, ProgressBarAdapter, ABCProgressBar, CreatePbar, Directory, File, InputFiles, LibraryDocs,
|
|
20
|
-
ProgressBarSimple
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class VoidPbar(ABCProgressBar):
|
|
25
|
-
|
|
26
|
-
def __init__(self):
|
|
27
|
-
super().__init__()
|
|
28
|
-
|
|
29
|
-
def set_percent(self, percent: float):
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
def set_text(self, text: str):
|
|
33
|
-
pass
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class ProgressVoid(ProgressBarAdapter):
|
|
37
|
-
|
|
38
|
-
def __init__(self, progress_bar: ABCProgressBar = VoidPbar()):
|
|
39
|
-
super().__init__(progress_bar)
|
|
40
|
-
|
|
41
|
-
def update(self, percent: float, status: str = "-"):
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
def update_percent(self, percent: float = 0):
|
|
45
|
-
pass
|
|
12
|
+
import soup_files as sp
|
|
46
13
|
|
|
47
|
-
|
|
48
|
-
pass
|
|
14
|
+
__version__ = '2.4'
|
|
49
15
|
|
|
50
16
|
|
|
51
|
-
def read_image(img: ImageObject, rec: RecognizeImage = RecognizeImage()) -> TextRecognized:
|
|
17
|
+
def read_image(img: cs.ImageObject, rec: RecognizeImage = RecognizeImage()) -> TextRecognized:
|
|
52
18
|
_txt = rec.image_recognize(img)
|
|
53
19
|
_txt.metadata = img.metadata
|
|
54
20
|
return _txt
|
|
55
21
|
|
|
56
22
|
|
|
57
23
|
def read_images(
|
|
58
|
-
images: list[ImageObject], *,
|
|
24
|
+
images: list[cs.ImageObject], *,
|
|
59
25
|
rec: RecognizeImage = RecognizeImage(),
|
|
60
|
-
pbar: ProgressBarAdapter = CreatePbar().get()
|
|
61
|
-
) -> DocumentPdf:
|
|
26
|
+
pbar: sp.ProgressBarAdapter = sp.CreatePbar().get()
|
|
27
|
+
) -> cs.DocumentPdf:
|
|
62
28
|
pbar.start()
|
|
63
29
|
print()
|
|
64
30
|
max_num = len(images)
|
|
@@ -67,26 +33,26 @@ def read_images(
|
|
|
67
33
|
for idx, image in enumerate(images):
|
|
68
34
|
pbar.update(
|
|
69
35
|
((idx + 1) / max_num) * 100,
|
|
70
|
-
f'[OCR] {idx + 1} / {max_num}',
|
|
36
|
+
f'[OCR IMAGENS] {idx + 1} / {max_num}',
|
|
71
37
|
)
|
|
72
38
|
out = read_image(image, rec=rec).to_page_pdf()
|
|
73
39
|
pages.append(out)
|
|
74
|
-
tmp_doc = DocumentPdf.create_from_pages(pages)
|
|
40
|
+
tmp_doc = cs.DocumentPdf.create_from_pages(pages)
|
|
75
41
|
print()
|
|
76
42
|
pbar.stop()
|
|
77
43
|
return tmp_doc
|
|
78
44
|
|
|
79
45
|
|
|
80
46
|
def read_document(
|
|
81
|
-
document: DocumentPdf, *,
|
|
47
|
+
document: cs.DocumentPdf, *,
|
|
82
48
|
dpi: int = 300,
|
|
83
|
-
pbar: ProgressBarAdapter = CreatePbar().get()
|
|
84
|
-
) -> DocumentPdf:
|
|
49
|
+
pbar: sp.ProgressBarAdapter = sp.CreatePbar().get()
|
|
50
|
+
) -> cs.DocumentPdf:
|
|
85
51
|
pbar.start()
|
|
86
52
|
print()
|
|
87
|
-
_metadata = document.metadata
|
|
53
|
+
_metadata: cs.MetaDataFile = document.metadata
|
|
88
54
|
recognized_items: list[TextRecognized] = []
|
|
89
|
-
pages_pdf: list[PageDocumentPdf] = document.to_pages()
|
|
55
|
+
pages_pdf: list[cs.PageDocumentPdf] = document.to_pages()
|
|
90
56
|
total = len(pages_pdf)
|
|
91
57
|
void_pbar = ProgressVoid()
|
|
92
58
|
for num, page in enumerate(pages_pdf):
|
|
@@ -94,14 +60,14 @@ def read_document(
|
|
|
94
60
|
((num + 1) / total) * 100,
|
|
95
61
|
f'[OCR PDF] {num + 1}/{total} {page.metadata.name}',
|
|
96
62
|
)
|
|
97
|
-
convert: ConvertPdfToImages = ConvertPdfToImages(DocumentPdf.create_from_pages([page]))
|
|
63
|
+
convert: cs.ConvertPdfToImages = cs.ConvertPdfToImages(cs.DocumentPdf.create_from_pages([page]))
|
|
98
64
|
convert.set_pbar(void_pbar)
|
|
99
|
-
images: list[ImageObject] = convert.to_images(dpi=dpi)
|
|
65
|
+
images: list[cs.ImageObject] = convert.to_images(dpi=dpi)
|
|
100
66
|
for im in images:
|
|
101
67
|
recognized_items.append(read_image(im))
|
|
102
68
|
print()
|
|
103
|
-
final_pages: list[PageDocumentPdf] = [x.to_page_pdf() for x in recognized_items]
|
|
104
|
-
final_doc: DocumentPdf = DocumentPdf.create_from_pages(final_pages)
|
|
69
|
+
final_pages: list[cs.PageDocumentPdf] = [x.to_page_pdf() for x in recognized_items]
|
|
70
|
+
final_doc: cs.DocumentPdf = cs.DocumentPdf.create_from_pages(final_pages)
|
|
105
71
|
final_doc.metadata = _metadata
|
|
106
72
|
return final_doc
|
|
107
73
|
|
|
@@ -110,33 +76,33 @@ class SearchableTextImage(object):
|
|
|
110
76
|
"""
|
|
111
77
|
|
|
112
78
|
return {
|
|
113
|
-
ColumnsTable.KEY.value: ColumnBody(ColumnsTable.KEY.value, ListString([])),
|
|
114
|
-
ColumnsTable.NUM_PAGE.value: ColumnBody(ColumnsTable.NUM_PAGE.value, ListString([])),
|
|
115
|
-
ColumnsTable.NUM_LINE.value: ColumnBody(ColumnsTable.NUM_LINE.value, ListString([])),
|
|
116
|
-
ColumnsTable.TEXT.value: ColumnBody(ColumnsTable.TEXT.value, ListString([])),
|
|
117
|
-
ColumnsTable.FILE_NAME.value: ColumnBody(ColumnsTable.FILE_NAME.value, ListString([])),
|
|
118
|
-
ColumnsTable.FILETYPE.value: ColumnBody(ColumnsTable.FILETYPE.value, ListString([])),
|
|
119
|
-
ColumnsTable.FILE_PATH.value: ColumnBody(ColumnsTable.FILE_PATH.value, ListString([])),
|
|
120
|
-
ColumnsTable.DIR.value: ColumnBody(ColumnsTable.DIR.value, ListString([])),
|
|
79
|
+
cs.ColumnsTable.KEY.value: cs.ColumnBody(cs.ColumnsTable.KEY.value, ListString([])),
|
|
80
|
+
cs.ColumnsTable.NUM_PAGE.value: cs.ColumnBody(cs.ColumnsTable.NUM_PAGE.value, ListString([])),
|
|
81
|
+
cs.ColumnsTable.NUM_LINE.value: cs.ColumnBody(cs.ColumnsTable.NUM_LINE.value, ListString([])),
|
|
82
|
+
cs.ColumnsTable.TEXT.value: cs.ColumnBody(cs.ColumnsTable.TEXT.value, ListString([])),
|
|
83
|
+
cs.ColumnsTable.FILE_NAME.value: cs.ColumnBody(cs.ColumnsTable.FILE_NAME.value, ListString([])),
|
|
84
|
+
cs.ColumnsTable.FILETYPE.value: cs.ColumnBody(cs.ColumnsTable.FILETYPE.value, ListString([])),
|
|
85
|
+
cs.ColumnsTable.FILE_PATH.value: cs.ColumnBody(cs.ColumnsTable.FILE_PATH.value, ListString([])),
|
|
86
|
+
cs.ColumnsTable.DIR.value: cs.ColumnBody(cs.ColumnsTable.DIR.value, ListString([])),
|
|
121
87
|
}
|
|
122
88
|
"""
|
|
123
89
|
def __init__(self, silent: bool = False):
|
|
124
90
|
self.silent = silent
|
|
125
|
-
self.elements:
|
|
91
|
+
self.elements: cs.DictTextTable = cs.DictTextTable.create_void_dict()
|
|
126
92
|
|
|
127
93
|
def __repr__(self):
|
|
128
94
|
return f'SearchableTextPdf: {self.elements}'
|
|
129
95
|
|
|
130
96
|
@property
|
|
131
97
|
def length(self) -> int:
|
|
132
|
-
return len(self.elements[ColumnsTable.TEXT.value])
|
|
98
|
+
return len(self.elements[cs.ColumnsTable.TEXT.value])
|
|
133
99
|
|
|
134
100
|
def is_empty(self) -> bool:
|
|
135
|
-
return len(self.elements[ColumnsTable.TEXT.value]) == 0
|
|
101
|
+
return len(self.elements[cs.ColumnsTable.TEXT.value]) == 0
|
|
136
102
|
|
|
137
103
|
@property
|
|
138
|
-
def columns(self) -> HeadValues:
|
|
139
|
-
return HeadValues([HeadCell(x) for x in list(self.elements.keys())])
|
|
104
|
+
def columns(self) -> cs.HeadValues:
|
|
105
|
+
return cs.HeadValues([cs.HeadCell(x) for x in list(self.elements.keys())])
|
|
140
106
|
|
|
141
107
|
@property
|
|
142
108
|
def first(self) -> dict[str, str]:
|
|
@@ -174,8 +140,8 @@ class SearchableTextImage(object):
|
|
|
174
140
|
return _current_item
|
|
175
141
|
|
|
176
142
|
def add_line(self, line: dict[str, str]) -> None:
|
|
177
|
-
cols: HeadValues = self.columns
|
|
178
|
-
cols_line: HeadValues = HeadValues([HeadCell(y) for y in list(line.keys())])
|
|
143
|
+
cols: cs.HeadValues = self.columns
|
|
144
|
+
cols_line: cs.HeadValues = cs.HeadValues([cs.HeadCell(y) for y in list(line.keys())])
|
|
179
145
|
for col in cols:
|
|
180
146
|
if cols_line.contains(col, case=True, iqual=True):
|
|
181
147
|
self.elements[col].append(line[col])
|
|
@@ -190,7 +156,7 @@ class SearchableTextImage(object):
|
|
|
190
156
|
ou 'nas' em caso de erro nas = Not a String
|
|
191
157
|
"""
|
|
192
158
|
try:
|
|
193
|
-
return ' '.join(self.elements[ColumnsTable.TEXT.value])
|
|
159
|
+
return ' '.join(self.elements[cs.ColumnsTable.TEXT.value])
|
|
194
160
|
except Exception as e:
|
|
195
161
|
print(e)
|
|
196
162
|
return 'nas'
|
|
@@ -198,12 +164,12 @@ class SearchableTextImage(object):
|
|
|
198
164
|
def to_data_frame(self) -> pd.DataFrame:
|
|
199
165
|
return pd.DataFrame.from_dict(self.elements)
|
|
200
166
|
|
|
201
|
-
def to_file_json(self, file: File):
|
|
167
|
+
def to_file_json(self, file: sp.File):
|
|
202
168
|
"""Exporta os dados da busca para um arquivo JSON"""
|
|
203
|
-
dt = JsonConvert.from_dict(self.elements).to_json_data()
|
|
169
|
+
dt = sp.JsonConvert.from_dict(self.elements).to_json_data()
|
|
204
170
|
dt.to_file(file)
|
|
205
171
|
|
|
206
|
-
def to_file_excel(self, file: File):
|
|
172
|
+
def to_file_excel(self, file: sp.File):
|
|
207
173
|
"""Exporta os dados da busca para um arquivo .XLSX"""
|
|
208
174
|
self.to_data_frame().to_excel(file.absolute(), index=False)
|
|
209
175
|
|
|
@@ -214,9 +180,9 @@ class ImageFinder(object):
|
|
|
214
180
|
"""
|
|
215
181
|
|
|
216
182
|
def __init__(self):
|
|
217
|
-
self.docs_collection: dict[str, ImageObject] = {}
|
|
183
|
+
self.docs_collection: dict[str, cs.ImageObject] = {}
|
|
218
184
|
self.recognize: RecognizeImage = RecognizeImage()
|
|
219
|
-
self.pbar: ProgressBarAdapter = ProgressBarAdapter()
|
|
185
|
+
self.pbar: sp.ProgressBarAdapter = sp.ProgressBarAdapter()
|
|
220
186
|
|
|
221
187
|
def is_empty(self) -> bool:
|
|
222
188
|
return len(self.docs_collection) == 0
|
|
@@ -224,29 +190,29 @@ class ImageFinder(object):
|
|
|
224
190
|
def clear(self) -> None:
|
|
225
191
|
self.docs_collection.clear()
|
|
226
192
|
|
|
227
|
-
def add_image(self, img: File | bytes | BytesIO | str | ImageObject) -> None:
|
|
228
|
-
if isinstance(img, File):
|
|
229
|
-
img = ImageObject(img)
|
|
230
|
-
elif isinstance(img, ImageObject):
|
|
193
|
+
def add_image(self, img: sp.File | bytes | BytesIO | str | cs.ImageObject) -> None:
|
|
194
|
+
if isinstance(img, sp.File):
|
|
195
|
+
img = cs.ImageObject(img)
|
|
196
|
+
elif isinstance(img, cs.ImageObject):
|
|
231
197
|
pass
|
|
232
198
|
elif isinstance(img, bytes):
|
|
233
|
-
img = ImageObject(img)
|
|
199
|
+
img = cs.ImageObject(img)
|
|
234
200
|
elif isinstance(img, str):
|
|
235
|
-
img = ImageObject(img)
|
|
201
|
+
img = cs.ImageObject(img)
|
|
236
202
|
elif isinstance(img, BytesIO):
|
|
237
|
-
img = ImageObject(img)
|
|
203
|
+
img = cs.ImageObject(img)
|
|
238
204
|
|
|
239
205
|
if not img.metadata.file_path.is_empty:
|
|
240
206
|
self.docs_collection[img.metadata.file_path] = img
|
|
241
207
|
else:
|
|
242
208
|
self.docs_collection[img.metadata.name] = img
|
|
243
209
|
|
|
244
|
-
def add_images(self, images: list[File] | list[ImageObject] | list[bytes] | list[BytesIO]) -> None:
|
|
210
|
+
def add_images(self, images: list[sp.File] | list[cs.ImageObject] | list[bytes] | list[BytesIO]) -> None:
|
|
245
211
|
for f in images:
|
|
246
212
|
self.add_image(f)
|
|
247
213
|
|
|
248
|
-
def add_directory_images(self, dir_pdf: Directory) -> None:
|
|
249
|
-
files = InputFiles(dir_pdf).get_files(file_type=LibraryDocs.IMAGE)
|
|
214
|
+
def add_directory_images(self, dir_pdf: sp.Directory) -> None:
|
|
215
|
+
files = sp.InputFiles(dir_pdf).get_files(file_type=sp.LibraryDocs.IMAGE)
|
|
250
216
|
if len(files) > 0:
|
|
251
217
|
self.add_images(files)
|
|
252
218
|
|
|
@@ -271,13 +237,13 @@ class ImageFinder(object):
|
|
|
271
237
|
f'[PESQUISANDO]: {n+1}/{total_num}',
|
|
272
238
|
)
|
|
273
239
|
|
|
274
|
-
current_img: ImageObject = self.docs_collection[file_key]
|
|
240
|
+
current_img: cs.ImageObject = self.docs_collection[file_key]
|
|
275
241
|
txt_in_img = self.recognize.image_to_string(current_img)
|
|
276
242
|
if (txt_in_img == '') or (txt_in_img is None):
|
|
277
243
|
self.pbar.update_text(f'ERRO: {n+1} {current_img.metadata.name}')
|
|
278
244
|
continue
|
|
279
245
|
try:
|
|
280
|
-
fd = FindText(txt_in_img, separator=separator)
|
|
246
|
+
fd = cs.text.FindText(txt_in_img, separator=separator)
|
|
281
247
|
idx = fd.find_index(text, iqual=iqual, case=case)
|
|
282
248
|
if idx is None:
|
|
283
249
|
continue
|
|
@@ -286,14 +252,14 @@ class ImageFinder(object):
|
|
|
286
252
|
print(f'{__class__.__name__} {err}')
|
|
287
253
|
else:
|
|
288
254
|
new_line: dict[str, str] = {
|
|
289
|
-
ColumnsTable.KEY.value: f'{idx}',
|
|
290
|
-
ColumnsTable.NUM_PAGE.value: 'nan',
|
|
291
|
-
ColumnsTable.NUM_LINE.value: f'{idx + 1}',
|
|
292
|
-
ColumnsTable.TEXT.value: math_text,
|
|
293
|
-
ColumnsTable.FILE_NAME.value: current_img.metadata.file_path,
|
|
294
|
-
ColumnsTable.FILETYPE.value: current_img.metadata.extension,
|
|
295
|
-
ColumnsTable.FILE_PATH.value: current_img.metadata.dir_path,
|
|
296
|
-
ColumnsTable.DIR.value: current_img.metadata.dir_path,
|
|
255
|
+
cs.ColumnsTable.KEY.value: f'{idx}',
|
|
256
|
+
cs.ColumnsTable.NUM_PAGE.value: 'nan',
|
|
257
|
+
cs.ColumnsTable.NUM_LINE.value: f'{idx + 1}',
|
|
258
|
+
cs.ColumnsTable.TEXT.value: math_text,
|
|
259
|
+
cs.ColumnsTable.FILE_NAME.value: current_img.metadata.file_path,
|
|
260
|
+
cs.ColumnsTable.FILETYPE.value: current_img.metadata.extension,
|
|
261
|
+
cs.ColumnsTable.FILE_PATH.value: current_img.metadata.dir_path,
|
|
262
|
+
cs.ColumnsTable.DIR.value: current_img.metadata.dir_path,
|
|
297
263
|
}
|
|
298
264
|
_searchable.add_line(new_line)
|
|
299
265
|
return _searchable
|
|
@@ -322,13 +288,13 @@ class ImageFinder(object):
|
|
|
322
288
|
f'[PESQUISANDO]: {n + 1}/{total_num}',
|
|
323
289
|
)
|
|
324
290
|
|
|
325
|
-
current_img: ImageObject = self.docs_collection[file_key]
|
|
291
|
+
current_img: cs.ImageObject = self.docs_collection[file_key]
|
|
326
292
|
txt_in_img = self.recognize.image_to_string(current_img)
|
|
327
293
|
if (txt_in_img == '') or (txt_in_img is None):
|
|
328
294
|
self.pbar.update_text(f'ERRO: {n + 1} {current_img.metadata.name}')
|
|
329
295
|
continue
|
|
330
296
|
try:
|
|
331
|
-
fd = FindText(txt_in_img, separator=separator)
|
|
297
|
+
fd = cs.text.FindText(txt_in_img, separator=separator)
|
|
332
298
|
idx = fd.find_index(text, iqual=iqual, case=case)
|
|
333
299
|
if idx is None:
|
|
334
300
|
continue
|
|
@@ -337,14 +303,14 @@ class ImageFinder(object):
|
|
|
337
303
|
print(f'{__class__.__name__} {err}')
|
|
338
304
|
else:
|
|
339
305
|
new_line: dict[str, str] = {
|
|
340
|
-
ColumnsTable.KEY.value: f'{idx}',
|
|
341
|
-
ColumnsTable.NUM_PAGE.value: 'nan',
|
|
342
|
-
ColumnsTable.NUM_LINE.value: f'{idx + 1}',
|
|
343
|
-
ColumnsTable.TEXT.value: math_text,
|
|
344
|
-
ColumnsTable.FILE_NAME.value: current_img.metadata.file_path,
|
|
345
|
-
ColumnsTable.FILETYPE.value: current_img.metadata.extension,
|
|
346
|
-
ColumnsTable.FILE_PATH.value: current_img.metadata.dir_path,
|
|
347
|
-
ColumnsTable.DIR.value: current_img.metadata.dir_path,
|
|
306
|
+
cs.ColumnsTable.KEY.value: f'{idx}',
|
|
307
|
+
cs.ColumnsTable.NUM_PAGE.value: 'nan',
|
|
308
|
+
cs.ColumnsTable.NUM_LINE.value: f'{idx + 1}',
|
|
309
|
+
cs.ColumnsTable.TEXT.value: math_text,
|
|
310
|
+
cs.ColumnsTable.FILE_NAME.value: current_img.metadata.file_path,
|
|
311
|
+
cs.ColumnsTable.FILETYPE.value: current_img.metadata.extension,
|
|
312
|
+
cs.ColumnsTable.FILE_PATH.value: current_img.metadata.dir_path,
|
|
313
|
+
cs.ColumnsTable.DIR.value: current_img.metadata.dir_path,
|
|
348
314
|
}
|
|
349
315
|
_searchable.add_line(new_line)
|
|
350
316
|
return _searchable
|
|
@@ -352,5 +318,5 @@ class ImageFinder(object):
|
|
|
352
318
|
|
|
353
319
|
__all__ = [
|
|
354
320
|
'ImageFinder', 'SearchableTextImage', 'read_images',
|
|
355
|
-
'read_document', 'RecognizeImage', 'RecognizePdf'
|
|
321
|
+
'read_document', 'RecognizeImage', 'RecognizePdf', 'VoidPbar', 'ProgressVoid'
|
|
356
322
|
]
|
|
@@ -7,7 +7,34 @@ from ocr_stream.bin_tess import BinTesseract
|
|
|
7
7
|
from ocr_stream.modules import LibOcr, DEFAULT_LIB_OCR
|
|
8
8
|
from ocr_stream.ocr import TesseractOcr, TextRecognized
|
|
9
9
|
from pandas import DataFrame
|
|
10
|
-
|
|
10
|
+
import soup_files as sp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class VoidPbar(sp.ABCProgressBar):
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
super().__init__()
|
|
17
|
+
|
|
18
|
+
def set_percent(self, percent: float):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def set_text(self, text: str):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ProgressVoid(sp.ProgressBarAdapter):
|
|
26
|
+
|
|
27
|
+
def __init__(self, progress_bar: sp.ABCProgressBar = VoidPbar()):
|
|
28
|
+
super().__init__(progress_bar)
|
|
29
|
+
|
|
30
|
+
def update(self, percent: float, status: str = "-"):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
def update_percent(self, percent: float = 0):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
def update_text(self, text: str = "-"):
|
|
37
|
+
pass
|
|
11
38
|
|
|
12
39
|
|
|
13
40
|
class RecognizeImage(object):
|
|
@@ -32,7 +59,7 @@ class RecognizeImage(object):
|
|
|
32
59
|
def bin_tesseract(self) -> BinTesseract:
|
|
33
60
|
return self.module_ocr.mod_ocr.bin_tess
|
|
34
61
|
|
|
35
|
-
def image_content_data(self, img: ImageObject | File) -> DataFrame:
|
|
62
|
+
def image_content_data(self, img: ImageObject | sp.File) -> DataFrame:
|
|
36
63
|
"""
|
|
37
64
|
Retorna uma tabela estruturada com os dados reconhecidos da imagem.
|
|
38
65
|
|
|
@@ -41,35 +68,35 @@ class RecognizeImage(object):
|
|
|
41
68
|
nível do OCR e confiabilidade, entre outras.
|
|
42
69
|
|
|
43
70
|
Parâmetros:
|
|
44
|
-
img (ImageObject | File): A imagem a ser processada, podendo ser um objeto
|
|
45
|
-
`ImageObject` ou um arquivo `File`.
|
|
71
|
+
img (ImageObject | sp.File): A imagem a ser processada, podendo ser um objeto
|
|
72
|
+
`ImageObject` ou um arquivo `sp.File`.
|
|
46
73
|
|
|
47
74
|
Retorna:
|
|
48
75
|
DataFrame: Uma tabela contendo os dados reconhecidos na imagem.
|
|
49
76
|
|
|
50
77
|
Lança:
|
|
51
|
-
ValueError: Se o tipo do parâmetro `img` não for `ImageObject` ou `File`.
|
|
78
|
+
ValueError: Se o tipo do parâmetro `img` não for `ImageObject` ou `sp.File`.
|
|
52
79
|
|
|
53
80
|
@param img: Imagem a ser processada, podendo ser uma instância de `ImageObject`
|
|
54
|
-
ou um arquivo `File`.
|
|
55
|
-
@type img: ImageObject | File
|
|
81
|
+
ou um arquivo `sp.File`.
|
|
82
|
+
@type img: ImageObject | sp.File
|
|
56
83
|
|
|
57
84
|
@rtype: pandas.DataFrame
|
|
58
85
|
@return: Um DataFrame com os dados reconhecidos na imagem.
|
|
59
86
|
|
|
60
|
-
@raise ValueError: Caso o tipo de `img` não seja `ImageObject` nem `File`.
|
|
87
|
+
@raise ValueError: Caso o tipo de `img` não seja `ImageObject` nem `sp.File`.
|
|
61
88
|
"""
|
|
62
89
|
return self.image_recognize(img).to_dataframe()
|
|
63
90
|
|
|
64
|
-
def image_recognize(self, img: ImageObject | File, *, land_scape: bool = False) -> TextRecognized:
|
|
65
|
-
if isinstance(img, File):
|
|
91
|
+
def image_recognize(self, img: ImageObject | sp.File, *, land_scape: bool = False) -> TextRecognized:
|
|
92
|
+
if isinstance(img, sp.File):
|
|
66
93
|
img = ImageObject(img)
|
|
67
94
|
if land_scape:
|
|
68
95
|
img.set_landscape()
|
|
69
96
|
rec: TextRecognized = self.module_ocr.to_reconize(img)
|
|
70
97
|
return rec
|
|
71
98
|
|
|
72
|
-
def image_to_string(self, img: ImageObject | File) -> str:
|
|
99
|
+
def image_to_string(self, img: ImageObject | sp.File) -> str:
|
|
73
100
|
return self.module_ocr.to_string(img)
|
|
74
101
|
|
|
75
102
|
|
|
@@ -81,9 +108,9 @@ class RecognizePdf(object):
|
|
|
81
108
|
lib_ocr: LibOcr = DEFAULT_LIB_OCR,
|
|
82
109
|
):
|
|
83
110
|
self.recognize_image: RecognizeImage = RecognizeImage(bin_tess, lib_ocr=lib_ocr)
|
|
84
|
-
self.pbar: ProgressBarAdapter = CreatePbar().get()
|
|
111
|
+
self.pbar: sp.ProgressBarAdapter = sp.CreatePbar().get()
|
|
85
112
|
|
|
86
|
-
def set_pbar(self, p: ProgressBarAdapter):
|
|
113
|
+
def set_pbar(self, p: sp.ProgressBarAdapter):
|
|
87
114
|
self.pbar = p
|
|
88
115
|
|
|
89
116
|
def recognize_page_pdf(self, page: PageDocumentPdf, *, dpi: int = 300) -> DocumentPdf:
|
|
@@ -93,32 +120,37 @@ class RecognizePdf(object):
|
|
|
93
120
|
"""
|
|
94
121
|
_doc = DocumentPdf.create_from_pages([page])
|
|
95
122
|
_conv = ConvertPdfToImages.create(_doc)
|
|
123
|
+
_conv.set_pbar(self.pbar)
|
|
96
124
|
img: ImageObject = _conv.to_images(dpi=dpi)[0]
|
|
97
125
|
text_recognized: TextRecognized = self.recognize_image.image_recognize(img)
|
|
98
126
|
del _doc
|
|
99
127
|
del _conv
|
|
100
128
|
del img
|
|
129
|
+
text_recognized.metadata.file_path = page.metadata.file_path
|
|
130
|
+
text_recognized.metadata.dir_path = page.metadata.dir_path
|
|
101
131
|
return text_recognized.to_document()
|
|
102
132
|
|
|
103
133
|
def recognize_document(self, doc: DocumentPdf, *, dpi: int = 300) -> DocumentPdf:
|
|
104
134
|
_pages: list[PageDocumentPdf] = []
|
|
105
135
|
_pages.clear()
|
|
106
136
|
_conv = ConvertPdfToImages.create(doc)
|
|
137
|
+
_conv.set_pbar(self.pbar)
|
|
107
138
|
images: list[ImageObject] = _conv.to_images(dpi=dpi)
|
|
108
139
|
max_num: int = len(images)
|
|
109
140
|
for num, img in enumerate(images):
|
|
110
141
|
self.pbar.update(
|
|
111
142
|
((num + 1) / max_num) * 100,
|
|
112
|
-
f'
|
|
143
|
+
f'OCR Documento [{num+1} de {max_num}]'
|
|
113
144
|
)
|
|
114
145
|
text_recognized = self.recognize_image.image_recognize(img)
|
|
115
146
|
_pages.append(text_recognized.to_page_pdf())
|
|
116
147
|
print()
|
|
117
148
|
self.pbar.stop()
|
|
118
149
|
new_doc = DocumentPdf.create_from_pages(_pages)
|
|
150
|
+
new_doc.metadata = doc.metadata
|
|
119
151
|
return new_doc
|
|
120
152
|
|
|
121
|
-
def recognize_file_pdf(self, file: File, *, dpi: int = 300) -> DocumentPdf:
|
|
153
|
+
def recognize_file_pdf(self, file: sp.File, *, dpi: int = 300) -> DocumentPdf:
|
|
122
154
|
file_doc = DocumentPdf.create_from_file(file)
|
|
123
155
|
recognized_doc = self.recognize_document(file_doc, dpi=dpi)
|
|
124
156
|
del file_doc
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ocr_stream
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Extrair textos de documentos digitalizados e imagens.
|
|
5
5
|
Author: Bruno Chaves
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pandas
|
|
|
12
12
|
Requires-Dist: requests>=2.32.4
|
|
13
13
|
Requires-Dist: opencv-python
|
|
14
14
|
Requires-Dist: pytesseract
|
|
15
|
-
Requires-Dist: convert_stream>=2.
|
|
15
|
+
Requires-Dist: convert_stream>=2.4.1
|
|
16
16
|
Requires-Dist: soup_files>=1.4
|
|
17
17
|
|
|
18
18
|
# ocrlib
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ocr_stream"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4.1"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Bruno Chaves"},
|
|
10
10
|
]
|
|
@@ -21,7 +21,7 @@ dependencies = [
|
|
|
21
21
|
"requests>=2.32.4",
|
|
22
22
|
"opencv-python",
|
|
23
23
|
"pytesseract",
|
|
24
|
-
"convert_stream>=2.
|
|
24
|
+
"convert_stream>=2.4.1",
|
|
25
25
|
"soup_files>=1.4",
|
|
26
26
|
]
|
|
27
27
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|