Der Standardwert restype
ist c_int
, und die Standardargumentkonvertierung von einer ganzen Zahl ist ebenfalls c_int
. Im Web finden Sie Beispiele, die von einer 32-Bit-Plattform mit sizeof(int) == sizeof(void *)
ausgehen. Dies war nie eine gute Annahme zu machen. Um einen 64-Bit-Zeiger vor dem Trunkieren zu schützen, wenn er in und aus einer Python-Ganzzahl konvertiert wird, setzen Sie den Funktionszeiger auf argtypes
und restype
. Es ist eine gute Idee, dies trotzdem zu tun, da es ctypes erlaubt, einen ArgumentError
zu erzeugen, wenn die falschen Typen oder die Anzahl der Argumente verwendet werden.
Wenn Sie die Prototypen nicht für jede Funktion definieren möchten, setzen Sie mindestens TessBaseAPICreate.restype
auf einen undurchsichtigen Zeigertyp. Die folgenden Ctypes-Definitionen basieren auf der Kopfzeile api/capi.h. Aus praktischen Gründen habe ich die API in eine Klasse verpackt.
import sys
import cv2
import ctypes
import ctypes.util
if sys.platform == 'win32':
LIBNAME = 'libtesseract302'
else:
LIBNAME = 'tesseract'
class TesseractError(Exception):
pass
class Tesseract(object):
_lib = None
_api = None
class TessBaseAPI(ctypes._Pointer):
_type_ = type('_TessBaseAPI', (ctypes.Structure,), {})
@classmethod
def setup_lib(cls, lib_path=None):
if cls._lib is not None:
return
if lib_path is None:
lib_path = ctypes.util.find_library(LIBNAME)
if lib_path is None:
raise TesseractError('tesseract library not found')
cls._lib = lib = ctypes.CDLL(lib_path)
# source:
# https://github.com/tesseract-ocr/tesseract/
# blob/3.02.02/api/capi.h
lib.TessBaseAPICreate.restype = cls.TessBaseAPI
lib.TessBaseAPIDelete.restype = None # void
lib.TessBaseAPIDelete.argtypes = (
cls.TessBaseAPI,) # handle
lib.TessBaseAPIInit3.argtypes = (
cls.TessBaseAPI, # handle
ctypes.c_char_p, # datapath
ctypes.c_char_p) # language
lib.TessBaseAPISetImage.restype = None
lib.TessBaseAPISetImage.argtypes = (
cls.TessBaseAPI, # handle
ctypes.c_void_p, # imagedata
ctypes.c_int, # width
ctypes.c_int, # height
ctypes.c_int, # bytes_per_pixel
ctypes.c_int) # bytes_per_line
lib.TessBaseAPIGetUTF8Text.restype = ctypes.c_char_p
lib.TessBaseAPIGetUTF8Text.argtypes = (
cls.TessBaseAPI,) # handle
def __init__(self, language='eng', datapath=None, lib_path=None):
if self._lib is None:
self.setup_lib(lib_path)
self._api = self._lib.TessBaseAPICreate()
if self._lib.TessBaseAPIInit3(self._api, datapath, language):
raise TesseractError('initialization failed')
def __del__(self):
if not self._lib or not self._api:
return
if not getattr(self, 'closed', False):
self._lib.TessBaseAPIDelete(self._api)
self.closed = True
def _check_setup(self):
if not self._lib:
raise TesseractError('lib not configured')
if not self._api:
raise TesseractError('api not created')
def set_image(self, imagedata, width, height,
bytes_per_pixel, bytes_per_line=None):
self._check_setup()
if bytes_per_line is None:
bytes_per_line = width * bytes_per_pixel
self._lib.TessBaseAPISetImage(self._api,
imagedata, width, height,
bytes_per_pixel, bytes_per_line)
def get_utf8_text(self):
self._check_setup()
return self._lib.TessBaseAPIGetUTF8Text(self._api)
def get_text(self):
self._check_setup()
result = self._lib.TessBaseAPIGetUTF8Text(self._api)
if result:
return result.decode('utf-8')
Beispiel Nutzung:
if __name__ == '__main__':
imcv = cv2.imread('ocrtest.png')
height, width, depth = imcv.shape
tess = Tesseract()
tess.set_image(imcv.ctypes, width, height, depth)
text = tess.get_text()
print text.strip()
ich dies mit libtesseract.so.3 auf Linux getestet. Beachten Sie, dass cv2.imread
ein NumPy-Array zurückgibt. Dies hat ein ctypes
Attribut, das den _as_parameter_
Hook enthält, als c_void_p
Zeiger auf das Array festgelegt. Beachten Sie auch, dass der Code in der Frage die Breite und Höhe transponiert hat. Es sollte h, w, d = imcv.shape
sein.
ocrtest.png:

Ausgang:
I am trying to use Tesseract 3.02 with ctypes and cv2 in python. Tesseract
provides a DLL exposed set of C style APIs, one of them is as following:
Ich kann nicht Sie mit dem C-Api helfen, aber wenn niemand antwortet: Verwenden Sie die [ausführbare Dateien zu erhalten aus dem Text] (https://github.com/niccokunzmann/mousemove/blob/master/mousemove/auslesen.py#L32). Es ist weit weg von optimal. – User
'TessBaseAPISetImage' gibt keinen Wert zurück. Der Standard-'restype' ist' c_int', also wird 44 nur in eine ganze Zahl umgewandelt. – eryksun