欢迎大家前往云加社区,获取更多腾讯海量技术实践干货哦~
译者:Mr.Geek
本文翻译自dzone 中Ivan Ozhiganov所发文章Deep Dive Into OCR for Receipt Recognition 文中版权、图像代码等数据均归作者所有。为了本土化,翻译内容略作修改。
光学字符识别技术(OCR)目前被广泛利用在手写识别、打印识别及文本图像识别等相关领域。小到文档识别、银行卡身份证识别,大到广告、海报。因为OCR技术的发明,极大简化了我们处理数据的方式。
同时,机器学习(ML)和卷积神经网络(CNN)的快速发展也让文本识别出现了巨大的飞跃!我们在本文的研究中也将使用卷积神经网络CNN技术来识别零售店的纸质票据。为了方便演示,我们本次将仅采用俄语版的票据进行测试。
我们的目标是项目开发一个客户端来识别来获取相关文档,在有服务器端去识别解析数据。准备好了吗?让我们一起去看看怎么做吧!
预处理
首先,我们需要接收图像相关数据,使其水平竖直方向垂直,接下来使用算法进行检测是否为票据,最终二值化方便识别。
旋转图像识别收据
我们有三种方案来识别票据,下文对这三种方案做了测试。
1. 高阈值的自适应二值化技术。 2. 卷积神经网络(CNN)。 3. Haar特征分类器。
自适应二值化技术
首先,我们看到,图中图像上包含了完整的数据,同时票据又与背景有些差距。为了能更好识别相关数据,我们需要将图片进行旋转。使其水平沿竖直方向对齐。
我们使用Opencv中的自适应阈值化函数adaptive_threshold和scikit-image框架来调整收据数据。利用这两项函数,我们可以在高梯度区域保留白色像素,低梯度区域保留黑色像素。这使得我们获得了一个高反差的样本图片。这样,通过裁剪,我们就能得到票据的相关信息了。
使用卷积神经网络(CNN)
起初我们决定使用CNN来做相关位置检测的接收点,就像我们之前做对象检测项目一样。我们使用判断角度来拾取相关关键点。这种方案虽然好用,但是和高阈值对比检测裁剪更差。
因为CNN只能找到文本的角度坐标,而文字的角度变化很大,这就意味着CNN模型不是很精准。详情请参考下面CNN测试的结果。
使用Haar特征分类器来识别收据
作为第三种选择,我们尝试使用Haar特征分类器来做分类筛选。然而经过一周的分类训练和改变相关参数,我们并没有得到什么比较积极的结果,甚至发现CNN都比Haar表现好得多。
二值化
最终我们使用opencv中的adaptive_threshold方法进行二值化,经过二值化处理,我们得到了一个不错的图片。
文本检测
接下来我们来介绍几个不同的文本检测组件。
通过链接组件检测文本
首先,我们使用Opencv中的find Contours函数找到链接的文本组。大多数链接的组件是字符,但是也有二值化留下来嘈杂的文本,这里我们通过设置阈值的大小来过滤相关文本。
然后,我们执行合成算法来合成字符,如: Й和=。通过搜索最临近的字符组合合成单词。这种算法需要你找到每个相关字字母最临近的字符,然后从若干字母中找到最佳选择展示。
接下来文字形成文字行。我们通过判断文字是否高度一致来判断文本是否属于同一行。
当然,这个方案的缺点是不能识别有噪声的文本。
使用网格对文本进行检测
我们发现几乎所有票据都是相同宽度的文本,所以我们设法在收据上画出一个网格,并利用网格分割每个字符:
网格一下子精简了票据识别的难度。神经网络可以精准识别每个网格内的字符。这样就解决了文本嘈杂的情况。最终可以精确统计文本数量。
我们使用了以下算法来识别网格。
首先,我在二值化镜像中使用这个连接组件算法。
然后我们发现图中左下角有些是真,所哟我们通过二维周期函数来调整网格识别。
修正网格失真背后主要的思想是利用图形峰值点找到非线性几何失真,换句话说,我们必须找到这个函数的最大值的和。另外,我们还需要一个最佳失真值才行。
我们使用ScipyPython模块中的RectBivariateSpline函数来参数化几何失真。并用Scipy函数进行优化。得到如下结果:
总而言之,这个方法缓慢且不稳定,所以坚决不打算使用这个方案。
光学字符识别
我们通过组连接识别发现文本,并识别完整的单词。
识别通过连接组发现的文本
对于文本识别,我们使用卷积神经网络(CNN)接收相关字体进行培训。输出部分,我们通过对比来提升概率。我们那个几个最初的几个选项多对比,发现有99%的准确识别率后。又通过对比字典来提高准确度,并消除相关类似的字符,如"З" 和 "Э"造成的错误。
然而,当涉及嘈杂的文本时,该方法性能却十分低下。
识别完整的单词
当文本太嘈杂的时候,需要找到完整的单词才能进行单个字母的识别。我们使用下面两个方法来解决这个问题:
- LSTM网络
- 图像非均匀分割技术
LSTM网络
您可以阅读这些文章,以更加深入了解使用卷积神经网络识别序列中的文本 ,或我们可以使用神经网络建立与语言无关的OCR吗? 为此,我们使用了OCRopus库来进行识别。
我们使用了等宽的字体来作为人工识别样本进行训练。
训练结束后,我们由利用其他数据来测试我们的神经网络,当然,测试结果非常积极。这是我们得到的数据:
训练好的神经网络在简单的例子上表现十分优秀。同样,我们也识别到了网格不适合的复杂情况。
我们抽取的相关的训练样本,并让他通过神经网络进行训练。
为了避免神经网络过度拟合,我们多次停止并修正训练结果,并不断加入新数据作为训练样本。最后我们得到以下结果:
新的网络擅长识别复杂的词汇,但是简单的文字识别却并不好。
我们觉得这个卷积神经网络可以细化识别单个字符来使文本识别更加优秀。
图像非均匀分割技术
因为收据字体是等宽的字体,所以我们决定按照字符分割字体。首先,我们需要知道每个字母的宽度。因此,字符的宽度尤为重要,我们需要估计每个字母的长度,利用函数,我们得到下图。选择多种模式来选取特定的字母宽度。
我们得到一个单词的近似宽度,通过除以字符中的字母数,给出一个近似分类:
区分最佳的是:
这种分割方案的准确度是非常高的:
当然,也有识别不太好的情况:
分割后我们在使用CNN做识别处理。
从收据中提取含义
我们使用正则表达式来查找收据中购买情况。所有收据都有一个共通点:购买价格以XX.XX格式来撰写。因此,可以通过提取购买的行来提取相关信息。个人纳税号码是十位数,也可以通过正则表达式轻松获取。同样,也可以通过正则表达式找到NAME / SURNAME等信息。
总结
- 不论你选择什么方法,LSTM或者其他更加复杂的方案,都没有错误,有些方法很难用,但是有些方法却很简单,因识别样本而异。
- 我们将继续优化这个项目。目前来看,在没有噪声的情况下,系统性能更加优秀。
原文链接:https://dzone.com/articles/using-ocr-for-receipt-recognition
原文作者:Ivan Ozhiganov
相关阅读
此文已由作者授权云加社区发布,转载请注明原文出处
深入浅出了解OCR识别票据原理的更多相关文章
-
深入浅出了解OCR识别票据原理(Applying OCR Technology for Receipt Recognition)
原文:Applying OCR Technology for Receipt Recognition 译文:深入浅出了解OCR识别票据原理 英文票据识别技术, 非中文票据识别技术, 中文情况的ocr更 ...
-
发票OCR识别/票据OCR自动识别
对于一些大的集团公司来说,分散式财务管理模式管理效率不高,管理成本相对较高,同时也制约了集团企业发展战略的实施,因而需要建设财务共享中心.一个企业想建造财务共享中心,面临的难题是大量的数据采集和信息处 ...
-
Atitit  ocr识别原理 与概论 attilax总结
Atitit ocr识别原理 与概论 attilax总结 1.1. Ocr的过程与流程1 1.2. OCR不同技术细分略有不同,但大概原理是一样的. 即主要技术过程是:二值化(又叫归一化)----- ...
-
AI时代的OCR识别技术浅析
人工智能这个词可谓是耳熟能详,近几年人工智能热潮再次席卷而来,引起轰动的要数google的AlphaGo,相继打败了围棋界的韩国选手李世石以及世界冠军柯洁,见证了人工智能发展的里程碑式的变革,人工智能 ...
-
例子:照片的OCR识别
来自ng的ml-003中 18_XVIII._Application_Example-_Photo_OCR 这是ng2013年在coursera上最后的一课了.这一系列的几个视频还是相比前面有些难懂, ...
-
使用Python基于VGG/CTPN/CRNN的自然场景文字方向检测/区域检测/不定长OCR识别
GitHub:https://github.com/pengcao/chinese_ocr https://github.com/xiaofengShi/CHINESE-OCR |-angle 基于V ...
-
基于Tesseract的OCR识别小程序
一.背景 先说下开发背景,今年有次搬家找房子(2020了应该叫去年了),发现每天都要对着各种租房广告打很多电话.(当然网上也找了实地也找),每次基本都是对着墙面看电话号码然后拨打,次数一多就感觉非常麻 ...
-
基于Python实现对PDF文件的OCR识别
http://www.jb51.net/article/89955.htm https://pythontips.com/2016/02/25/ocr-on-pdf-files-using-pytho ...
-
OCR识别-python版(一)
需求:识别图片中的文字信息环境:windows系统 开发语言:python 使用工具类:1.pyocr 2.PIL 3.tesseract-ocr 步骤: 1.pyocr 网络通直接使用命令:pip ...
随机推荐
-
WPF学习系列之六 (元素绑定)
元素绑定 简单地说,数据绑定是一种关系,该关系告诉WPF从一个源对象提取一些信息,并使用这些信息设置目标对象的属性.目标属性总是依赖属性,并且通常位于WPF元素中. 一.将元素绑定到一起 <Wi ...
-
Linux下查看文件和文件夹大小的df和du命令
转自:http://www.yayu.org/look.php?id=162 当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择. df可以查看一级文件夹大小.使用比 ...
-
POJ 3616 Milking Time 简单DP
题意:奶牛Bessie在0~N时间段产奶.农夫约翰有M个时间段可以挤奶,时间段f,t内Bessie能挤到的牛奶量e.奶牛产奶后需要休息R小时才能继续下一次产奶,求Bessie最大的挤奶量. 详见代码 ...
-
再造*之网易彩票-第一季(IOS 篇 by sixleaves)
前言 在网上看了别人做的模仿网易彩票的项目, 于是也跟着用自己的想法做了一篇.写这篇博客的目的, 在于UI综合的一次小练习, 同时总结和串联其各个控件之间的应用.封装思想等.考虑到有人上不了githu ...
-
关于C语言程序条件编译的简单使用方法
#include <stdio.h> #include <stdlib.h> #define Mode //如果定义了Mode,那么就执行这个函数 #ifdef Mode vo ...
-
ES ik分词器使用技巧
match查询会将查询词分词,然后对分词的结果进行term查询. 然后默认是将每个分词term查询之后的结果求交集,所以只要分词的结果能够命中,某条数据就可以被查询出来,而分词是在新建索引时指定的,只 ...
-
【CH5302】金字塔 区间DP
题目大意:给定一棵树,树上点有标记,给定一棵树的\(dfs\)序标记序列,求有多少种可能的子树形态.(子树之间有序) 这是一道区间计数类DP,涉及到树的\(dfs\)序. 这道题区间的划分点 \(k\ ...
-
Scala进阶之路-反射(reflect)技术详解
Scala进阶之路-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的反射技术和Java反射用法类似,我这里就不一一介绍反射是啥了,如果对 ...
-
SpringMVC点滴(1)
在使用springMVC很久,却一直没有总结其中的一些便捷配置和功能,恰好有空,加以总结 Servlet 3之后,在web.xml中加入async的支持,从而实现异步请求,需要在servlet和fil ...
-
Spring Data JPA 关系映射(一对一,一对多,多对多 )
CascadeType.REMOVE 级联删除操作,删除当前实体时,与它有映射关系的实体也会跟着被删除.CascadeType.MERGE 级联更新(合并)操作,当Student中的数据改变,会相应地 ...