默認restype
是c_int
,並且整數的默認參數轉換也是c_int
。您將在網絡上找到假設具有sizeof(int) == sizeof(void *)
的32位平臺的示例。這從來都不是一個好的假設。爲了保護64位指針在與Python整數轉換時截斷,設置函數指針的argtypes
和restype
。無論如何,這是一個好主意,因爲它允許ctypes在使用錯誤類型或數量的參數時引發ArgumentError
。
如果您不想爲每個函數定義原型,那麼至少應將TessBaseAPICreate.restype
設置爲不透明指針類型。
以下ctypes定義基於標頭api/capi.h。爲了方便起見,我將API打包爲Tesseract
類。
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')
實例:
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()
我libtesseract.so.3測試這在Linux。請注意0返回一個NumPy數組。這有一個屬性,其中包括_as_parameter_
鉤子,設置爲指向該陣列的c_void_p
指針。還要注意,問題中顯示的代碼具有寬度和高度轉置。它應該是h, w, d = imcv.shape
。
ocrtest.png:
輸出:
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:
我不能幫你用C-API,但如果沒有人回答:使用[可執行程序獲得出文本](https://github.com/niccokunzmann/mousemove/blob/master/mousemove/auslesen.py#L32)。它遠離最佳狀態。 – User
'TessBaseAPISetImage'不返回值。默認的'restype'是'c_int',所以44只是垃圾轉換爲整數。 – eryksun