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:
TESS_API void TESS_CALL TessBaseAPISetImage(TessBaseAPI* handle, const unsigned char* imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line);
So far, my code is as follows:
tesseract = ctypes.cdll.LoadLibrary('libtesseract302.dll')
api = tesseract.TessBaseAPICreate()
tesseract.TessBaseAPIInit3(api, '', 'eng')
imcv = cv2.imread('test.bmp')
w, h, d = imcv.shape
ret = tesseract.TessBaseAPISetImage(api, ctypes.c_char_p(str(imcv.data)), w, h, d, w * d)
#ret = 44 here
The last line return an error code 44, which I can't find anywhere in errcode.h provided by Tesseract. I am not sure what I am doing wrong here.
I have found similar question How to recognize data not filename using ctypes and tesseract 3.0.2?, however the question is not resolved. I am also aware of https://code.google.com/p/python-tesseract/, I dig into source code of this project but didn't be able to find the information I need.
I can confirm the image in test.bmp is legit and readable by calling cv2.imshow
.
also the same image can be OCR by Tesseract on command line.
The default
restype
isc_int
, and the default argument conversion from an integer is alsoc_int
. You'll find examples on the web that assume a 32-bit platform that hassizeof(int) == sizeof(void *)
. This was never a good assumption to make. To protect a 64-bit pointer from truncation when converted to and from a Python integer, set the function pointer'sargtypes
andrestype
. It's a good idea to do this anyway, since it allows ctypes to raise anArgumentError
when the the wrong types or number of arguments are used.If you'd rather not define the prototypes for every function, then at least set
TessBaseAPICreate.restype
to an opaque pointer type.The following ctypes definitions are based on the header api/capi.h. For convenience I've packaged the API into a
Tesseract
class.Example usage:
I tested this on Linux with libtesseract.so.3. Note that
cv2.imread
returns a NumPy array. This has actypes
attribute that includes the_as_parameter_
hook, set as ac_void_p
pointer to the the array. Note also that the code shown in the question has the width and height transposed. It should have beenh, w, d = imcv.shape
.ocrtest.png:
Output: