} } }

    编写Tesseract的Python扩大

    添加时间:2013-7-18 点击量:

    Tesseract是一个开源的OCR(光学字符辨认)引擎,用于辨认并输出中的文字。固然和贸易软件比起来辨认精度不算很高,然则若是你要寻找免费开源的OCR引擎,可能Tesseract就是独一的选择了。Tesseract用起来还算是斗劲便利。它供给了一个简单的号令行对象,没有很多选项,输入输出就是文字。因为是开源的,你也可以直接编译应用它基于C++的库。


    比来一段时候我对Python产生了很大的爱好。它是如此的简洁高效,只要可以用Python完成的工作就懒得应用其他编程说话。所以到了应用Tesseract的时辰我起首想到了去Google一下有没有Python binding。确切有人应用swig做了个tesseract的封装,不过不幸的是实际应用存在不少题目。起首是安装不便,尤其在mac上的安装令人溃散。即使完成安装,不知为何又segment fault。其次,很多办法只做了简单的封装,又缺乏文档,想做深切一点的应用例如输出文字在图中的地位,感触感染无从着手。不如从Tesseract的源代码入手,本身编写python的扩大,对tesseract的某些感爱好的办法做个封装,也趁便熟悉下Python和C/C++集成的办法。可以在扩大里随心所欲,真是令人表情兴奋。


    起首,新建一个cpp源文件,然后为这个新模块想个名字,比如 tessex。然后,须要定义这个新模块,以及模块里须要露出出来的办法。如许在Python里就可以用import tessex来载入模块。



    static PyMethodDef tessexMethods[] = {
    
    {
    recognize, (PyCFunction)tessex_recognize,
    METH_VARARGS
    |METH_KEYWORDS,
    recognize text in an image.},
    {NULL, NULL,
    0, NULL}
    };

    PyMODINIT_FUNC inittessex(
    void) {
    void) Py_InitModule(tessex, tessexMethods);
    }


    这里,我们露出一个办法recognize,用来扫描给定然后返回识此外文字以及地位。大师知道Python办法可以传两种参数,一种是无名的,一种是有名的,分别对应METH_VARARGS以及METH_KEYWORDS。作为一个有点完美主义偏向的人,我把两个选项都勾上了。然后我们看下recognize办法的定义。正如之前讲的,须要声明参数args以及kw。



    static PyObject tessex_recognize(PyObject self, PyObject args, PyObject kw){


    接下来是展开从Python调用传进来的参数。要应用有名参数,须要把所有参数名都先列出来。



      static const char kwlist[]={datawhchannelsstep, NULL};


    然后调用PyArg_ParseTupleAndKeywords展开有名参数。一个格局字符串用于声明参数的类型。data是图像的像素buffer,实用S类型。w、h、channels、step分别是图像的宽度、高度、信道数、步长,都是整型变量,实用i类型。



        PyStringObject data;
    
    int w=0;
    int h=0;
    int channels=0;
    int step=0;

    if (!PyArg_ParseTupleAndKeywords(args, kw, Siiii, (char)(kwlist),
    &data, &w, &h, &channels, &step)) {
    PyErr_SetString(PyExc_Exception,
    Tessex: Failed to parse arguments.);
    return NULL;
    }


    
    

    我们要开端应用Tesseract的API了。Tesseract支撑多种说话,不过说话包要分别安装。这里我们应用英语。 



        tesseract::TessBaseAPI api = new tesseract::TessBaseAPI();
    
    if (api->Init(NULL, eng)) {
    PyErr_SetString(PyExc_Exception,
    Tessex: Failed to initialize tesseract API.);
    return NULL;
    }


     把传入的图像数据传递给Tesseract,然掉队行辨认。



        api->SetImage((const unsigned char)PyString_AS_STRING(data),
    
    w, h, channels, step);

    api
    ->Recognize(0);


    辨认成果的处理惩罚稍微错杂点。一般的应用若是只想获得所有文字,只要调用GetUTF8Text()就完了。然则我想知道每一行的文字,它们的具体地位以及可托度,就须要对辨认成果进行具体的解析。荣幸的是Tesseract供给了iterator接口,可以返回不合粒度的数据。这里我选择了按行输出,即RIL_TEXTLINE。 



        PyObject l = PyList_New(0);
    
    tesseract::ResultIterator
    it = api->GetIterator();
    it
    ->Begin();
    while1) {
    char utf8_text;
    int left, top, right, bottom;
    int confidence = 0;

    utf8_text
    = it->GetUTF8Text(tesseract::RIL_TEXTLINE);
    if (utf8_text == NULL)
    break;

    confidence
    = it->Confidence(tesseract::RIL_TEXTLINE);
    it
    ->BoundingBox(tesseract::RIL_TEXTLINE, &left, &top, &right, &bottom);

    PyObject
    t = Py_BuildValue((siiiii), utf8_text,
    left, top, right, bottom, confidence);
    PyList_Append(l, t);

    []utf8_text;

    it
    ->Next(tesseract::RIL_TEXTLINE);
    }
    api
    ->End();

    PyObject
    o = Py_BuildValue(O, l);

    return o;


    返回的是一个list,其每个元素都是一个tuple,代表辨认出来的文字行,包含文字、地位和可托度。


    最后不要忘了include须要的头文件,并在链接选项里参加须要的库。



    #include Python.h
    
    #include
    <tesseract/baseapi.h>
    #include
    <tesseract/resultiterator.h>


    具体如何编译tesseract可以参考https://code.google.com/p/tesseract-ocr/wiki/Compiling/ 


    在示例代码里我们并没有效到任何图形库。然则因为要应用Tesseract就必须链接leptonica库,所以须要参加链接选项-llept。


    若是你想在扩大里应用leptonica的功能可以include <leptonica/allheaders.h>。或者你想应用openCV,可以include <opencv2/opencv.hpp>并链接-lopencv_XXXXX。



    如许代码项目组算是完成了。不过接下来还有一步,我们须要打包完成一个Python扩大使之轻易编译和安装。可以应用distutils模块。



     distutils.core import setup, Extension
    

    tessenigma
    = Extension (
    tessex
    sources
    =[tessex.cpp],
    include_dirs
    = [/usr/local/include],
    libraries
    =[ tesseract],
    library_dirs
    =[/usr/local/lib]


    setup (name
    =tessex
    version
    =1.0
    description
    =This is a tesseract extensiion.
    ext_modules
    = [tessex])


    把这些定义写入一个setup.py文件里。如许我们就可以用凡是的体式格式编译和安装模块了。编译用setup.py build。一个动态链接库会生成。例如在Linux下面就是tessex.so。安装模块应用setup.py install。前面生成的库文件会被复制到Python的site-packages下面。当然你也可以手动复制到¥PYTHONPATH路径下面,一样能被Python找到。



    安装好扩大后,在Python里是如许调用的,假定我们应用一个openCV图像:



    import tessex
    import cv

    cv_img = cv.LoadImage(path, cv.CV_LOAD_IMAGE_COLOR)

    lines = tessex.recognize(
    data
    =cv_img.tostring(),
    w
    =cv_img.width,
    h
    =cv_img.height,
    channels
    =cv_img.nChannels,
    step
    =cv_img.width cv_img.nChannels cv_img.depth / 8

    for line in lines:
      line_text, left, top, right, bottom, confidence
    = line


    经由过程Tesseract扩大,可以在Python中斗劲便利地辨认图像中的文字以及地位,对基于图像识此外主动化测试是很有帮助的。


    彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
    分享到: