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[]={"data", "w", "h", "channels", "step", 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();while(1) {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);delete []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模块。

from distutils.core import setup, Extensiontessenigma = 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 tesseximport 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中比较方便地识别图像中的文字以及位置,对基于图像识别的自动化测试是很有帮助的。

转载于:https://www.cnblogs.com/silmerusse/p/3196301.html

编写Tesseract的Python扩展相关推荐

  1. Python 扩展 Op

    Python 扩展 Op 注意 :本文涉及的 Python Kernel 仅在 gcc 4.8.5 编译环境下充分测试,进一步的完善计划见 Issue 3951. 背景介绍 OneFlow 将各种对于 ...

  2. 表示python代码块的是_编写高质量Python代码的59个有效方法,你用过几个

    欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练.PDF电子文档.面试集锦.学习资料等. 这个周末断断续续的阅读完了<Effectiv ...

  3. zlib 离线安装_黑板派Python扩展库安装与常见问题解决完整指南

    点击蓝字 ! 关注我们 "Python小屋"编程比赛正式开始 推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国, ...

  4. python3.7扩展库是什么_Python3.4以后的版本中,____________库用于安装管理Python扩展包,________________库用于发布Python包。_学小易找答案...

    [填空题]Python3.4以后的版本中,____________库用于安装管理Python扩展包,________________库用于发布Python包. [判断题]Directions: The ...

  5. python 自动化办公 uibot_使用 Python 扩展丰富 UiBot 的功能及在 UiBot 中引用 Python 模块...

    前言 UiBot除了自带的强大功能外,还允许有编程经验的RPA开发人员对功能进行自由扩展,目前UiBot支持以下四种扩展方式: Python插件.Lua插件.Lua Mod插件.COM插件(.Net也 ...

  6. python文件编译_将c程序编译为python扩展,生成.whl文件

    借鉴的文章会在文章末尾会逐一给出 1. 对c文件进行编译 先确保要实现的代码运行成功,然后将main()函数删除,例如test.c文件 void test_func(char *str){ FILE ...

  7. 安装python扩展库时只能使用pip_安装 Python 扩展库时只能使用 pip 工具在线安装,如果安装不成功就没有别的办法了。_学小易找答案...

    [单选题]关于Python中的复数,下列说法错误的是_________________. [填空题]在Python程序中,导入sys模块后,可以通过列表________________访问命令行参数. ...

  8. python 自动化办公 uibot_【插件开发】使用 Python 扩展 UiBot 的功能

    前言: UiBot 除了自带的强大功能外,还允许有编程经验的开发人员对功能进行自由扩展,目前 UiBot 支持以下四种扩展方式: Python 插件.Lua 插件.Lua Mod 插件.COM 插件( ...

  9. Visual Studio Code 10 月 Python 扩展更新

    微软发布了 10 月的 Visual Studio Code Python 扩展更新,该版本包括支持原生编辑 Juypter Notebook,添加在终端中运行 Python 文件的按钮,以及改进 P ...

最新文章

  1. 【怎样写代码】向现有类型“添加”方法 -- 扩展方法(四):在编译时绑定扩展方法的规则
  2. 【转载】zookeeper学习
  3. 谷歌tts android手机自带引擎,Android使用讯飞语记引擎实现中文TTS
  4. 微赞企动协会wac_xiehui3.0.9全开源版模块
  5. OpenCV--图像内轮阔填充
  6. CentOS 7 中英文桌面安装步骤详细图解
  7. VINS-Mono代码分析与总结(完整版)
  8. linux# 解读wmctrl一览输出的项目
  9. Java排序算法——猴子排序(Bogo Sort)
  10. 小米笔记本12.5java_小米12.5笔记本系统
  11. 欧姆龙nj与nx哪个高端_没想到还有比三菱更垃圾的PLC,欧姆龙隆重登场
  12. 推荐→可以做时间线图片的APP
  13. linux 消息队列大小设置,linux 消息队列 参数
  14. CSDN使用MD编辑器写博客如何让图片居中(调整图片位置大小)MD编辑器学习笔记
  15. 国内域名如何转入 GoDaddy,域名转入GoDaddy要注意?
  16. iOS APP之间到跳转,以及热门应用,手机自带到应用跳转
  17. python写excel宏_使用python执行excel的VBA(宏)
  18. Running pipenv gives TypeError: 'module' object is not callable
  19. 如何转换为YOLO txt格式
  20. MySQL从删库到跑路(9):group by——给漂亮小姐姐分个组

热门文章

  1. Android关于finish()与System.exit()都不能退出应用的原因
  2. 20岁以后的男人应该知道的一些事,看一看吧
  3. .NET开源社区存在的问题
  4. 图解SQL Join用法
  5. setjmp和longjmp
  6. nginx实现大小写字母转换(ngx_http_lower_upper_case模块)
  7. RobotFramework自动化框架—robot文件中调用自定义库
  8. python学习day06--01
  9. 应急模拟系统功能结构图
  10. 1041 考试座位号