ocr-stream 1.4__tar.gz → 2.2.6__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-1.4 → ocr_stream-2.2.6}/PKG-INFO +2 -16
- ocr_stream-2.2.6/ocr_stream/__init__.py +5 -0
- ocr_stream-2.2.6/ocr_stream/bin_tess/__init__.py +95 -0
- ocr_stream-2.2.6/ocr_stream/modules/__init__.py +43 -0
- ocr_stream-2.2.6/ocr_stream/ocr/__init__.py +218 -0
- ocr_stream-2.2.6/ocr_stream/recognize.py +109 -0
- {ocr_stream-1.4 → ocr_stream-2.2.6}/ocr_stream.egg-info/PKG-INFO +2 -16
- ocr_stream-2.2.6/ocr_stream.egg-info/SOURCES.txt +12 -0
- {ocr_stream-1.4 → ocr_stream-2.2.6}/ocr_stream.egg-info/requires.txt +1 -2
- {ocr_stream-1.4 → ocr_stream-2.2.6}/pyproject.toml +8 -4
- ocr_stream-1.4/ocr_stream/__init__.py +0 -8
- ocr_stream-1.4/ocr_stream/__main__.py +0 -46
- ocr_stream-1.4/ocr_stream/_version.py +0 -5
- ocr_stream-1.4/ocr_stream/extractors.py +0 -126
- ocr_stream-1.4/ocr_stream/models/__init__.py +0 -2
- ocr_stream-1.4/ocr_stream/models/m_extractors.py +0 -2
- ocr_stream-1.4/ocr_stream/models/m_modules_ocr.py +0 -68
- ocr_stream-1.4/ocr_stream/modules_ocr.py +0 -491
- ocr_stream-1.4/ocr_stream/utils/__init__.py +0 -16
- ocr_stream-1.4/ocr_stream.egg-info/SOURCES.txt +0 -18
- ocr_stream-1.4/ocr_stream.egg-info/not-zip-safe +0 -1
- ocr_stream-1.4/setup.py +0 -44
- {ocr_stream-1.4 → ocr_stream-2.2.6}/README.md +0 -0
- {ocr_stream-1.4 → ocr_stream-2.2.6}/ocr_stream.egg-info/dependency_links.txt +0 -0
- {ocr_stream-1.4 → ocr_stream-2.2.6}/ocr_stream.egg-info/top_level.txt +0 -0
- {ocr_stream-1.4 → ocr_stream-2.2.6}/setup.cfg +0 -0
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ocr_stream
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: Extrair textos de documentos digitalizados e imagens.
|
|
5
5
|
Author: Bruno Chaves
|
|
6
|
-
Requires: PyPDF2
|
|
7
|
-
Requires: PyMuPDF
|
|
8
|
-
Requires: reportlab
|
|
9
|
-
Requires: openpyxl
|
|
10
|
-
Requires: openpyxl
|
|
11
|
-
Requires: pandas
|
|
12
|
-
Requires: Pillow
|
|
13
|
-
Requires: opencv_python
|
|
14
|
-
Requires: requests
|
|
15
|
-
Requires: pytesseract
|
|
16
|
-
Requires: soup_files
|
|
17
|
-
Requires: convert_stream
|
|
18
6
|
Requires-Python: >=3.11
|
|
19
7
|
Description-Content-Type: text/markdown
|
|
20
8
|
Requires-Dist: PyMuPDF
|
|
21
9
|
Requires-Dist: reportlab
|
|
22
10
|
Requires-Dist: openpyxl
|
|
23
11
|
Requires-Dist: pandas
|
|
24
|
-
Requires-Dist: Pillow>=11.3.0
|
|
25
12
|
Requires-Dist: requests>=2.32.4
|
|
26
13
|
Requires-Dist: opencv-python
|
|
27
|
-
Requires-Dist: convert_stream>=
|
|
14
|
+
Requires-Dist: convert_stream>=2.2.4
|
|
28
15
|
Requires-Dist: soup_files
|
|
29
|
-
Dynamic: requires
|
|
30
16
|
|
|
31
17
|
# ocrlib
|
|
32
18
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import os
|
|
4
|
+
from shutil import which
|
|
5
|
+
from soup_files import File, Directory, KERNEL_TYPE
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def __get_path_tesseract_unix() -> File | None:
|
|
9
|
+
out = which('tesseract')
|
|
10
|
+
if out is None:
|
|
11
|
+
return None
|
|
12
|
+
return File(out)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def __get_path_tesseract_windows() -> File | None:
|
|
16
|
+
out = which('tesseract.exe')
|
|
17
|
+
if out is None:
|
|
18
|
+
return None
|
|
19
|
+
return File(out)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_path_tesseract_sys() -> File | None:
|
|
23
|
+
if KERNEL_TYPE == 'Windows':
|
|
24
|
+
return __get_path_tesseract_windows()
|
|
25
|
+
return __get_path_tesseract_unix()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BinTesseract(object):
|
|
29
|
+
"""
|
|
30
|
+
Fornece o caminho absoluto do tesseract instalado no sistema, se
|
|
31
|
+
disponível. Você pode usar um binário alternativo, basta informar
|
|
32
|
+
o caminho do binário desejado no construtor.
|
|
33
|
+
"""
|
|
34
|
+
_instance = None # Atributo de classe para armazenar a instância singleton
|
|
35
|
+
|
|
36
|
+
def __new__(cls, *args, **kwargs):
|
|
37
|
+
if cls._instance is None:
|
|
38
|
+
cls._instance = super(BinTesseract, cls).__new__(cls)
|
|
39
|
+
return cls._instance
|
|
40
|
+
|
|
41
|
+
def __init__(self, path: File = None):
|
|
42
|
+
# Garante que __init__ não será executado mais de uma vez
|
|
43
|
+
if hasattr(self, '_initialized') and self._initialized:
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
self._initialized = True
|
|
47
|
+
self.__tess_data_dir = None
|
|
48
|
+
self.__lang = None
|
|
49
|
+
if path is not None:
|
|
50
|
+
self.__path_tesseract: File = path
|
|
51
|
+
else:
|
|
52
|
+
self.__path_tesseract = get_path_tesseract_sys()
|
|
53
|
+
|
|
54
|
+
def set_tesseract(self, path: File):
|
|
55
|
+
if not isinstance(path, File):
|
|
56
|
+
return
|
|
57
|
+
self.__path_tesseract = path
|
|
58
|
+
|
|
59
|
+
def get_tesseract(self) -> File | None:
|
|
60
|
+
return self.__path_tesseract
|
|
61
|
+
|
|
62
|
+
def set_lang(self, lang: str):
|
|
63
|
+
if not isinstance(lang, str):
|
|
64
|
+
return
|
|
65
|
+
self.__lang = lang
|
|
66
|
+
|
|
67
|
+
def get_lang(self):
|
|
68
|
+
return self.__lang
|
|
69
|
+
|
|
70
|
+
def set_tessdata_dir(self, tessdata_dir: str):
|
|
71
|
+
if not isinstance(tessdata_dir, str):
|
|
72
|
+
return
|
|
73
|
+
self.__tess_data_dir = tessdata_dir
|
|
74
|
+
|
|
75
|
+
def get_tessdata_dir(self) -> str | None:
|
|
76
|
+
if self.__tess_data_dir is not None:
|
|
77
|
+
return self.__tess_data_dir
|
|
78
|
+
try:
|
|
79
|
+
if KERNEL_TYPE == 'Windows':
|
|
80
|
+
if os.path.exists("C:\\Program Files (x86)\\Tesseract-OCR\\tessdata"):
|
|
81
|
+
self.__tess_data_dir = "C:\\Program Files (x86)\\Tesseract-OCR\\tessdata"
|
|
82
|
+
elif KERNEL_TYPE == 'Linux':
|
|
83
|
+
if os.path.exists('/usr/share/tesseract-ocr/5/tessdata'):
|
|
84
|
+
self.__tess_data_dir = '/usr/share/tesseract-ocr/5/tessdata'
|
|
85
|
+
except Exception as err:
|
|
86
|
+
print(err)
|
|
87
|
+
return self.__tess_data_dir
|
|
88
|
+
|
|
89
|
+
def exists(self) -> bool:
|
|
90
|
+
"""Verifica se o binário tesseract existe"""
|
|
91
|
+
if self.__path_tesseract is None:
|
|
92
|
+
return False
|
|
93
|
+
return self.__path_tesseract.exists()
|
|
94
|
+
|
|
95
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Union, TypeAlias
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LibOcr(Enum):
|
|
8
|
+
|
|
9
|
+
PYTESSERACT = "pytesseract"
|
|
10
|
+
PYOCR = "pyocr"
|
|
11
|
+
NOT_IMPLEMENTED = "not_implemented"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
MOD_PYTESSERACT: bool = False
|
|
15
|
+
MOD_PYOCR: bool = False
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from pytesseract import pytesseract, Output
|
|
19
|
+
MOD_PYTESSERACT = True
|
|
20
|
+
except:
|
|
21
|
+
pytesseract = None
|
|
22
|
+
Output = None
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
import pyocr
|
|
26
|
+
import pyocr.tesseract
|
|
27
|
+
MOD_PYOCR = True
|
|
28
|
+
except:
|
|
29
|
+
pyocr = None
|
|
30
|
+
pyocr.tesseract = None
|
|
31
|
+
|
|
32
|
+
if MOD_PYTESSERACT and MOD_PYOCR:
|
|
33
|
+
ModuleOcr: TypeAlias = Union[pyocr, pytesseract]
|
|
34
|
+
DEFAULT_LIB_OCR = LibOcr.PYTESSERACT
|
|
35
|
+
elif MOD_PYTESSERACT:
|
|
36
|
+
ModuleOcr: TypeAlias = Union[pytesseract]
|
|
37
|
+
DEFAULT_LIB_OCR = LibOcr.PYTESSERACT
|
|
38
|
+
elif MOD_PYOCR:
|
|
39
|
+
ModuleOcr: TypeAlias = Union[pyocr]
|
|
40
|
+
DEFAULT_LIB_OCR = LibOcr.PYOCR
|
|
41
|
+
else:
|
|
42
|
+
ModuleOcr: TypeAlias = None
|
|
43
|
+
DEFAULT_LIB_OCR = LibOcr.NOT_IMPLEMENTED
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import os.path
|
|
5
|
+
from abc import abstractmethod, ABC
|
|
6
|
+
from typing import Union
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
from pandas import DataFrame
|
|
9
|
+
from soup_files import File, Directory
|
|
10
|
+
from convert_stream import (
|
|
11
|
+
ImageObject, DocumentPdf, PageDocumentPdf, MapText, ColumnsTable,
|
|
12
|
+
get_hash_from_bytes, DEFAULT_LIB_IMAGE, LibImage
|
|
13
|
+
)
|
|
14
|
+
from ocr_stream.modules import (
|
|
15
|
+
LibOcr, ModuleOcr, DEFAULT_LIB_OCR, MOD_PYOCR, MOD_PYTESSERACT,
|
|
16
|
+
pytesseract, Output, pyocr,
|
|
17
|
+
)
|
|
18
|
+
from ocr_stream.bin_tess import BinTesseract
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
import pyocr.tesseract
|
|
22
|
+
except:
|
|
23
|
+
pyocr.tesseract = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TextRecognized(object):
|
|
27
|
+
"""
|
|
28
|
+
Recebe os bytes de uma página PDF reconhecida de imagem
|
|
29
|
+
e exporta para vários tipos de dados.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, bytes_recognized: bytes):
|
|
33
|
+
self.bytes_recognized: bytes = bytes_recognized
|
|
34
|
+
self.list_bad_char: list[str] = [
|
|
35
|
+
':', ',', ';', '$', '=',
|
|
36
|
+
'!', '}', '{', '(', ')',
|
|
37
|
+
'|', '\\', '‘', '*'
|
|
38
|
+
'¢', '“', '\'', '¢', '"',
|
|
39
|
+
'#', '.', '<', '?', '>',
|
|
40
|
+
'»', '@', '+', '[', ']',
|
|
41
|
+
'%', '~', '¥', '♀',
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
def to_string(self) -> str | None:
|
|
45
|
+
return self.to_page_pdf().to_string()
|
|
46
|
+
|
|
47
|
+
def to_page_pdf(self) -> PageDocumentPdf:
|
|
48
|
+
doc = self.to_document()
|
|
49
|
+
return doc.to_pages()[0]
|
|
50
|
+
|
|
51
|
+
def to_document(self) -> DocumentPdf:
|
|
52
|
+
return DocumentPdf.create_from_bytes(BytesIO(self.bytes_recognized))
|
|
53
|
+
|
|
54
|
+
def to_map(self, separator: str = '\n') -> MapText:
|
|
55
|
+
text = self.to_string()
|
|
56
|
+
if (text is None) or (text == '') or (text == 'nas'):
|
|
57
|
+
return MapText([])
|
|
58
|
+
try:
|
|
59
|
+
return MapText(text.split(separator))
|
|
60
|
+
except Exception as err:
|
|
61
|
+
print(err)
|
|
62
|
+
return MapText([])
|
|
63
|
+
|
|
64
|
+
def to_dict(self, separator: str = '\n') -> dict[str, list[str]]:
|
|
65
|
+
return self.to_map(separator).map_elements
|
|
66
|
+
|
|
67
|
+
def to_dataframe(self, separator='\n') -> DataFrame:
|
|
68
|
+
return self.to_map(separator).to_data()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ABCOcrTesseract(ABC):
|
|
72
|
+
|
|
73
|
+
def __init__(self, bin_tess: BinTesseract, *, lang: str = None, tess_data_dir: str = None):
|
|
74
|
+
if not bin_tess.exists():
|
|
75
|
+
raise FileNotFoundError('tesseract binary not found')
|
|
76
|
+
self.bin_tess: BinTesseract = bin_tess
|
|
77
|
+
self.lang: str = lang
|
|
78
|
+
self.tess_data_dir: str = tess_data_dir
|
|
79
|
+
self.current_library: LibOcr = DEFAULT_LIB_OCR
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def to_string(self, img: Union[File, ImageObject]) -> str:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def to_reconize(self, img: Union[File, ImageObject]) -> TextRecognized:
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class IPytesseract(ABCOcrTesseract):
|
|
91
|
+
|
|
92
|
+
def __init__(self, bin_tess: BinTesseract, *, lang: str = None, tess_data_dir: str = None):
|
|
93
|
+
super().__init__(bin_tess, lang=lang, tess_data_dir=tess_data_dir)
|
|
94
|
+
self.current_library: LibOcr = LibOcr.PYTESSERACT
|
|
95
|
+
self._MOD_TESS: pytesseract = pytesseract
|
|
96
|
+
self._MOD_TESS.tesseract_cmd = self.bin_tess.get_tesseract().absolute()
|
|
97
|
+
|
|
98
|
+
def __get_tess_dir_config(self) -> str | None:
|
|
99
|
+
"""
|
|
100
|
+
https://github.com/h/pytesseract
|
|
101
|
+
|
|
102
|
+
Example config: r'--tessdata-dir "C:\Program Files (x86)\Tesseract-OCR\tessdata"'
|
|
103
|
+
tessdata_dir_config = r'--tessdata-dir <replace_with_your_tessdata_dir_path>'
|
|
104
|
+
It's important to add double quotes around the dir path.
|
|
105
|
+
"""
|
|
106
|
+
# Caminho para os dados de idioma, por, eng etc...
|
|
107
|
+
# os.environ["TESSDATA_PREFIX"] = self.tess_data_dir.absolute()
|
|
108
|
+
if self.tess_data_dir is None:
|
|
109
|
+
return ''
|
|
110
|
+
if not os.path.exists(self.tess_data_dir):
|
|
111
|
+
return ''
|
|
112
|
+
return r'--tessdata-dir "{}"'.format(self.tess_data_dir)
|
|
113
|
+
|
|
114
|
+
def to_string(self, img: Union[File, ImageObject]) -> str:
|
|
115
|
+
if isinstance(img, File):
|
|
116
|
+
img = ImageObject.create_from_file(img)
|
|
117
|
+
|
|
118
|
+
if DEFAULT_LIB_IMAGE == LibImage.OPENCV:
|
|
119
|
+
_im = img.to_opencv()
|
|
120
|
+
elif DEFAULT_LIB_IMAGE == LibImage.PIL:
|
|
121
|
+
_im = img.to_pil()
|
|
122
|
+
else:
|
|
123
|
+
raise NotImplementedError()
|
|
124
|
+
|
|
125
|
+
if self.lang is None:
|
|
126
|
+
return self._MOD_TESS.image_to_string(_im, config=self.__get_tess_dir_config())
|
|
127
|
+
else:
|
|
128
|
+
return self._MOD_TESS.image_to_string(_im, lang=self.lang, config=self.__get_tess_dir_config())
|
|
129
|
+
|
|
130
|
+
def to_reconize(self, img: Union[File, ImageObject]) -> TextRecognized:
|
|
131
|
+
|
|
132
|
+
if isinstance(img, File):
|
|
133
|
+
img = ImageObject.create_from_file(img)
|
|
134
|
+
|
|
135
|
+
if DEFAULT_LIB_IMAGE == LibImage.OPENCV:
|
|
136
|
+
_im = img.to_opencv()
|
|
137
|
+
elif DEFAULT_LIB_IMAGE == LibImage.PIL:
|
|
138
|
+
_im = img.to_pil()
|
|
139
|
+
else:
|
|
140
|
+
raise NotImplementedError()
|
|
141
|
+
bt = self._MOD_TESS.image_to_pdf_or_hocr(
|
|
142
|
+
_im,
|
|
143
|
+
lang=self.lang,
|
|
144
|
+
config=self.__get_tess_dir_config()
|
|
145
|
+
)
|
|
146
|
+
return TextRecognized(bt)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# ======================================================================#
|
|
150
|
+
# Modulo OCR pyocr
|
|
151
|
+
# ======================================================================#
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class IPyOcr(ABCOcrTesseract):
|
|
155
|
+
|
|
156
|
+
def __init__(self, bin_tess: BinTesseract, *, lang: str = None, tess_data_dir: str = None):
|
|
157
|
+
super().__init__(bin_tess, lang=lang, tess_data_dir=tess_data_dir)
|
|
158
|
+
|
|
159
|
+
self.current_library: LibOcr = LibOcr.PYOCR
|
|
160
|
+
pyocr_modules: list = pyocr.get_available_tools()
|
|
161
|
+
if len(pyocr_modules) == 0:
|
|
162
|
+
raise ValueError(f"{__class__.__name__} No OCR tool found")
|
|
163
|
+
# The tools are returned in the recommended order of usage
|
|
164
|
+
self._pyOcr = pyocr_modules[0]
|
|
165
|
+
langs: list[str] = self._pyOcr.get_available_languages()
|
|
166
|
+
if lang in lang:
|
|
167
|
+
self.lang = lang
|
|
168
|
+
else:
|
|
169
|
+
self.lang = langs[0]
|
|
170
|
+
|
|
171
|
+
# Ex: Will use tool 'libtesseract'
|
|
172
|
+
print(f"Will use tool {self._pyOcr.get_name()}")
|
|
173
|
+
|
|
174
|
+
def to_string(self, img: Union[File, ImageObject]) -> str:
|
|
175
|
+
if isinstance(img, File):
|
|
176
|
+
img = ImageObject.create_from_file(img)
|
|
177
|
+
|
|
178
|
+
if DEFAULT_LIB_IMAGE == LibImage.OPENCV:
|
|
179
|
+
_im = img.to_opencv()
|
|
180
|
+
elif DEFAULT_LIB_IMAGE == LibImage.PIL:
|
|
181
|
+
_im = img.to_pil()
|
|
182
|
+
|
|
183
|
+
return self._pyOcr.to_string(
|
|
184
|
+
_im,
|
|
185
|
+
lang=self.lang,
|
|
186
|
+
builder=pyocr.builders.TextBuilder()
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def to_reconize(self, img: Union[File, ImageObject]) -> TextRecognized:
|
|
190
|
+
raise NotImplementedError(f'{__class__.__name__} método não implementado')
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class TesseractOcr(object):
|
|
194
|
+
|
|
195
|
+
def __init__(self, mod_ocr: ABCOcrTesseract):
|
|
196
|
+
self.mod_ocr: ABCOcrTesseract = mod_ocr
|
|
197
|
+
|
|
198
|
+
def to_string(self, img: Union[File, ImageObject]) -> str:
|
|
199
|
+
return self.mod_ocr.to_string(img)
|
|
200
|
+
|
|
201
|
+
def to_reconize(self, img: Union[File, ImageObject]) -> TextRecognized:
|
|
202
|
+
return self.mod_ocr.to_reconize(img)
|
|
203
|
+
|
|
204
|
+
@classmethod
|
|
205
|
+
def create(
|
|
206
|
+
cls,
|
|
207
|
+
bin_tess: BinTesseract, *,
|
|
208
|
+
lang: str = None,
|
|
209
|
+
tess_data_dir: str = None,
|
|
210
|
+
lib_ocr: LibOcr = DEFAULT_LIB_OCR,
|
|
211
|
+
) -> TesseractOcr:
|
|
212
|
+
if lib_ocr == LibOcr.PYTESSERACT:
|
|
213
|
+
md = IPytesseract(bin_tess, lang=lang, tess_data_dir=tess_data_dir)
|
|
214
|
+
elif lib_ocr == LibOcr.PYOCR:
|
|
215
|
+
md = IPyOcr(bin_tess, lang=lang, tess_data_dir=tess_data_dir)
|
|
216
|
+
else:
|
|
217
|
+
raise ValueError(f'{lib_ocr} is not supported')
|
|
218
|
+
return cls(md)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from convert_stream import ImageObject, LibImage, DocumentPdf, PageDocumentPdf, ConvertPdfToImages, PdfStream
|
|
4
|
+
from ocr_stream.bin_tess import BinTesseract
|
|
5
|
+
from ocr_stream.modules import LibOcr, DEFAULT_LIB_OCR, ModuleOcr
|
|
6
|
+
from ocr_stream.ocr import TesseractOcr, TextRecognized
|
|
7
|
+
from pandas import DataFrame
|
|
8
|
+
from soup_files import File, ProgressBarAdapter, CreatePbar
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RecognizeImage(object):
|
|
12
|
+
"""
|
|
13
|
+
Reconhecer textos em imagens com pytesseract|pyocr usando o tesseract
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, bin_tess: BinTesseract, *, lib_ocr: LibOcr = DEFAULT_LIB_OCR):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.module_ocr: TesseractOcr = TesseractOcr.create(
|
|
19
|
+
bin_tess,
|
|
20
|
+
lib_ocr=lib_ocr,
|
|
21
|
+
lang=bin_tess.get_lang(),
|
|
22
|
+
tess_data_dir=bin_tess.get_tessdata_dir(),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def bin_tesseract(self) -> BinTesseract:
|
|
27
|
+
return self.module_ocr.mod_ocr.bin_tess
|
|
28
|
+
|
|
29
|
+
def image_content_data(self, img: ImageObject | File) -> DataFrame:
|
|
30
|
+
"""
|
|
31
|
+
Retorna uma tabela estruturada com os dados reconhecidos da imagem.
|
|
32
|
+
|
|
33
|
+
Este método extrai as informações contidas em uma imagem e as organiza em
|
|
34
|
+
um DataFrame com colunas como o texto detectado, coordenadas da caixa delimitadora,
|
|
35
|
+
nível do OCR e confiabilidade, entre outras.
|
|
36
|
+
|
|
37
|
+
Parâmetros:
|
|
38
|
+
img (ImageObject | File): A imagem a ser processada, podendo ser um objeto
|
|
39
|
+
`ImageObject` ou um arquivo `File`.
|
|
40
|
+
|
|
41
|
+
Retorna:
|
|
42
|
+
DataFrame: Uma tabela contendo os dados reconhecidos na imagem.
|
|
43
|
+
|
|
44
|
+
Lança:
|
|
45
|
+
ValueError: Se o tipo do parâmetro `img` não for `ImageObject` ou `File`.
|
|
46
|
+
|
|
47
|
+
@param img: Imagem a ser processada, podendo ser uma instância de `ImageObject`
|
|
48
|
+
ou um arquivo `File`.
|
|
49
|
+
@type img: ImageObject | File
|
|
50
|
+
|
|
51
|
+
@rtype: pandas.DataFrame
|
|
52
|
+
@return: Um DataFrame com os dados reconhecidos na imagem.
|
|
53
|
+
|
|
54
|
+
@raise ValueError: Caso o tipo de `img` não seja `ImageObject` nem `File`.
|
|
55
|
+
"""
|
|
56
|
+
return self.image_recognize(img).to_dataframe()
|
|
57
|
+
|
|
58
|
+
def image_recognize(self, img: ImageObject | File) -> TextRecognized:
|
|
59
|
+
rec: TextRecognized = self.module_ocr.to_reconize(img)
|
|
60
|
+
return rec
|
|
61
|
+
|
|
62
|
+
def image_to_string(self, img: ImageObject | File) -> str:
|
|
63
|
+
return self.module_ocr.to_string(img)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class RecognizePdf(object):
|
|
67
|
+
|
|
68
|
+
def __init__(self, bin_tess: BinTesseract, *, lib_ocr: LibOcr = DEFAULT_LIB_OCR):
|
|
69
|
+
self.recognize_image: RecognizeImage = RecognizeImage(bin_tess, lib_ocr=lib_ocr)
|
|
70
|
+
self.pbar: ProgressBarAdapter = CreatePbar().get()
|
|
71
|
+
|
|
72
|
+
def set_pbar(self, p: ProgressBarAdapter):
|
|
73
|
+
self.pbar = p
|
|
74
|
+
|
|
75
|
+
def recognize_page_pdf(self, page: PageDocumentPdf) -> DocumentPdf:
|
|
76
|
+
"""
|
|
77
|
+
Converte a página em Imagem, reconhece o texto com OCR e
|
|
78
|
+
retorna uma nova página com o texto reconhecido.
|
|
79
|
+
"""
|
|
80
|
+
_doc = DocumentPdf.create_from_pages([page])
|
|
81
|
+
_conv = ConvertPdfToImages.create(_doc)
|
|
82
|
+
img: ImageObject = _conv.to_images()[0]
|
|
83
|
+
text_recognized: TextRecognized = self.recognize_image.image_recognize(img)
|
|
84
|
+
return text_recognized.to_document()
|
|
85
|
+
|
|
86
|
+
def recognize_document(self, doc: DocumentPdf) -> DocumentPdf:
|
|
87
|
+
_pages: list[PageDocumentPdf] = []
|
|
88
|
+
_pages.clear()
|
|
89
|
+
_conv = ConvertPdfToImages.create(doc)
|
|
90
|
+
images: list[ImageObject] = _conv.to_images()
|
|
91
|
+
max_num: int = len(images)
|
|
92
|
+
for num, img in enumerate(images):
|
|
93
|
+
self.pbar.update(
|
|
94
|
+
((num + 1) / max_num) * 100,
|
|
95
|
+
f'Aplicando OCR [{num+1} de {max_num}]'
|
|
96
|
+
)
|
|
97
|
+
text_recognized = self.recognize_image.image_recognize(img)
|
|
98
|
+
_pages.append(text_recognized.to_page_pdf())
|
|
99
|
+
print()
|
|
100
|
+
self.pbar.stop()
|
|
101
|
+
new_doc = DocumentPdf.create_from_pages(_pages)
|
|
102
|
+
return new_doc
|
|
103
|
+
|
|
104
|
+
def recognize_file_pdf(self, file: File) -> DocumentPdf:
|
|
105
|
+
file_doc = DocumentPdf.create_from_file(file)
|
|
106
|
+
recognized_doc = self.recognize_document(file_doc)
|
|
107
|
+
del file_doc
|
|
108
|
+
return recognized_doc
|
|
109
|
+
|
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ocr_stream
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: Extrair textos de documentos digitalizados e imagens.
|
|
5
5
|
Author: Bruno Chaves
|
|
6
|
-
Requires: PyPDF2
|
|
7
|
-
Requires: PyMuPDF
|
|
8
|
-
Requires: reportlab
|
|
9
|
-
Requires: openpyxl
|
|
10
|
-
Requires: openpyxl
|
|
11
|
-
Requires: pandas
|
|
12
|
-
Requires: Pillow
|
|
13
|
-
Requires: opencv_python
|
|
14
|
-
Requires: requests
|
|
15
|
-
Requires: pytesseract
|
|
16
|
-
Requires: soup_files
|
|
17
|
-
Requires: convert_stream
|
|
18
6
|
Requires-Python: >=3.11
|
|
19
7
|
Description-Content-Type: text/markdown
|
|
20
8
|
Requires-Dist: PyMuPDF
|
|
21
9
|
Requires-Dist: reportlab
|
|
22
10
|
Requires-Dist: openpyxl
|
|
23
11
|
Requires-Dist: pandas
|
|
24
|
-
Requires-Dist: Pillow>=11.3.0
|
|
25
12
|
Requires-Dist: requests>=2.32.4
|
|
26
13
|
Requires-Dist: opencv-python
|
|
27
|
-
Requires-Dist: convert_stream>=
|
|
14
|
+
Requires-Dist: convert_stream>=2.2.4
|
|
28
15
|
Requires-Dist: soup_files
|
|
29
|
-
Dynamic: requires
|
|
30
16
|
|
|
31
17
|
# ocrlib
|
|
32
18
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
ocr_stream/__init__.py
|
|
4
|
+
ocr_stream/recognize.py
|
|
5
|
+
ocr_stream.egg-info/PKG-INFO
|
|
6
|
+
ocr_stream.egg-info/SOURCES.txt
|
|
7
|
+
ocr_stream.egg-info/dependency_links.txt
|
|
8
|
+
ocr_stream.egg-info/requires.txt
|
|
9
|
+
ocr_stream.egg-info/top_level.txt
|
|
10
|
+
ocr_stream/bin_tess/__init__.py
|
|
11
|
+
ocr_stream/modules/__init__.py
|
|
12
|
+
ocr_stream/ocr/__init__.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ocr_stream"
|
|
7
|
-
version = "
|
|
7
|
+
version = "2.2.6"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Bruno Chaves"},
|
|
10
10
|
]
|
|
@@ -18,12 +18,16 @@ dependencies = [
|
|
|
18
18
|
"reportlab",
|
|
19
19
|
"openpyxl",
|
|
20
20
|
"pandas",
|
|
21
|
-
"Pillow>=11.3.0",
|
|
22
21
|
"requests>=2.32.4",
|
|
23
22
|
"opencv-python",
|
|
24
|
-
"convert_stream>=
|
|
23
|
+
"convert_stream>=2.2.4",
|
|
25
24
|
"soup_files",
|
|
26
25
|
]
|
|
27
26
|
|
|
28
27
|
[tool.setuptools]
|
|
29
|
-
packages = [
|
|
28
|
+
packages = [
|
|
29
|
+
"ocr_stream",
|
|
30
|
+
"ocr_stream.bin_tess",
|
|
31
|
+
"ocr_stream.modules",
|
|
32
|
+
"ocr_stream.ocr",
|
|
33
|
+
]
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
from .models.m_modules_ocr import LibraryOCR
|
|
4
|
-
from .modules_ocr import TextRecognized, BinaryTesseract
|
|
5
|
-
from .utils import File, Directory, InputFiles, UserFileSystem
|
|
6
|
-
from .extractors import RecognizeImage, RecognizePdf
|
|
7
|
-
from ._version import __version__, __modify_data__
|
|
8
|
-
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
------------------------------------------------------------
|
|
5
|
-
Configuração instalação:
|
|
6
|
-
------------------------------------------------------------
|
|
7
|
-
$ pip3 install -r requirements.txt
|
|
8
|
-
|
|
9
|
-
------------------------------------------------------------
|
|
10
|
-
Referências:
|
|
11
|
-
------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
https://gist.github.com/endolith/334196bac1cac45a4893
|
|
14
|
-
|
|
15
|
-
Tesseract OCR
|
|
16
|
-
https://github.com/tesseract-ocr/tesseract
|
|
17
|
-
|
|
18
|
-
pytesseract
|
|
19
|
-
https://github.com/h/pytesseract
|
|
20
|
-
|
|
21
|
-
pyocr
|
|
22
|
-
https://gitlab.gnome.org/World/OpenPaperwork/pyocr
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
import sys, os
|
|
26
|
-
this_file = os.path.abspath(os.path.relpath(__file__))
|
|
27
|
-
dir_of_project = os.path.dirname(this_file)
|
|
28
|
-
sys.path.insert(0, dir_of_project)
|
|
29
|
-
|
|
30
|
-
from convert_stream import print_title
|
|
31
|
-
from ocr_stream import __version__, __modify_data__
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def test():
|
|
35
|
-
# /usr/bin/tesseract
|
|
36
|
-
# /usr/share/tesseract-ocr/5/tessdata
|
|
37
|
-
pass
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def main():
|
|
41
|
-
print_title(f' ocrlib Versão: {__version__} | Atualização: {__modify_data__} ')
|
|
42
|
-
test()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if __name__ == '__main__':
|
|
46
|
-
main()
|