基于Tesseract-OCR和WPF UI Automation进行信息自动化收集

有一个小工具荒废已久,最近又有需求提出来,希望能恢复下这个工具。但以前有些代码改动没有保存到svn上,同时也没有相关的说明文档,于是只能从头梳理一遍,顺便写下此文,作为一个交接他人的文档。

这个工具的作用是:自动收集某个第三方应用程序的的数据,然后将这些数据保存起来进行二次分析,最终通过页面的方式展示分析结果和一些历史趋势。

这个第三方应用最重要的内容如下图所示:

 我们的目的是获取每一行每一列的数据,这里通过UI Automation实现这个目标,其中最核心的代码如下:

利用上面的接口,我们就可以获取当前应用界面布局中的各种单元节点。这里有一个非常有用的工具推荐给大家:UISpy.exe,它可以帮助我们可视化的去定位界面中各个节点,并获取这个节点的详细信息。具体的用法网上有很多教程,这里就不展开说明了。

利用上述方法,我们现在已经可以定位到每个单元格,并获取单元格内的信息了。例如我们获取到了下面的单元格:

如果这个单元格的内容是一个字符串,那么我们的任务基本就完成了,只要通过UI Automation的接口直接读取到这个单元格的内容就可以了。但是,非常不幸运,我们希望获取的这个内容,并没有存储在这个单元格的信息之中。那么怎么办呢?于是就想到了,截取这个单元格作为一张图片,然后再利用图像识别技术。

因为通过UI Automation能够获取这个单元格的尺寸信息,所以截图不存在问题,剩下的就是图像识别了。我们这里采取的是Tesseract-OCR的开源识别技术,网上也有很多相关的教程,这里也不具体展开了。这里说下遇到的2个问题。

第一个问题是不能识别。当我们截图如下所示:

通过Tesseract识别后,都是一串莫名其妙的英文,尝试换了一些其他字库去识别,依旧不能准确识别。后来才知道,原来以前同事针对这个需求,专门做过对应的字库训练,可惜,这个专门训练的字库也在岁月的流逝中无情的丢失了。只能再次祭出google大法,最后发现有人说,有可能是图片的尺寸较小,造成了Tesseract识别不了。于是通过下面的代码对原始图像进行了放大:

这里,我放大了2倍:

然后可喜的发现,大部分都是准确的识别出来了。

第二个问题是识别不准确。有时候会发现数字被错误的识别成英文字母,查了下一些网上的建议,大部分是对图像做一个预处理,比如二值化等,来增加识别的准确性。这里我并没有采取这些方法,而是简单的用了字符替换,当发现有数字被误识别为字母的时候,利用下面的替换表进行简单替换:

{'O': '0', 'A' : '8','I': '1', 'L': '1','Z': '2', 'S': '8''E': '6', ‘G’: ’9’, 'B': ’6’}

结果表明,这样简单的处理后,基本能满足这个工具的需求了。

现在我们已经完成了目标,获取到了应用程序中每行的详细信息:idnamarank。只要每天定时运行这个工具,将获取到的这些信息上传到服务器,并通过页面展示出来就可以了。

到最后了,其实也不妨说下前面我为什么采取将图片放大来提高识别率的方法。因为按照Tesseract的文档,我对样本进行了字库训练后,可耻的发现失败了,也没继续深究下去,因为毕竟只是个小工具,能实现目的就好。

本文来自网易实践者社区,经作者朱洁授权发布。