作者parcequetoi (Sky)
看板DataScience
标题Re: [问题] OCR实务经验请益
时间Thu May 10 12:45:41 2018
不好意思,又就同一个主题来讨教。
前阵子我已经用规则和正规表达式完成一个版本,
不过过程中也发现一些问题,是在规则下无法一一解决的,
想和板众请教、盼能得到一点方向。
目前我大致的做法是:
1. 用每个Google Vision辨认出的文字框的x座标,
做k-means clustering辅以Silhouette analysis,
以决定这份拿到的成绩单有几个栏位(columns)。
2. 根据决定出的每个栏位的文字内容,
用正规表达式去做一个voting system,
去对每个栏位表决这应该是个:
a. 科目栏位
b. 成绩栏位
c. 分数单位栏位
d. 前标 - 後标参考范围栏位
四者之中的哪一种。
3. 最後,挑出科目及成绩栏位,
依y座标去让成绩栏位中的文字框向科目栏位中的文字框寻求对应。
但是以上的做法有几个瓶颈:
1. 在上述做法的第一步里面,最基本的假设是:
成绩单总是依直栏排列,不同项目是分布在不同直栏内。
但其实
这假设不为真。
2. 在第二步中,由於是用整个栏位的内容一起表决,
因此会包含许多不需要的文字框,例如我下面引文里面的第一个例子,
成绩栏位就会包含「姓名:王小明」、「考试日期:」、「分数」、「分数」等,
而且「分数」文字框还会对应到「科目」文字框,形成多余的无意义组合。
这不能用正规表达式挑数字来解决,
因为成绩栏位中不一定是数字,还可能是A+、优秀、有待加强、甲上...等文字,
不可能用正规表达式穷尽所有可能。
3.
同种科目可能在各校有不同名称,且Google Vision回传的文字不一定是对的。
这会让日後的资料变得杂乱而无意义。
我需要一个自动校正系统,尽可能基於人类对「成绩单」的认知去校正内容,
例如「国文」、「国语」、「中文」、「团文」、「国X」
(真的是英文字母X),
全部都应该要是「国文」。
而「90.l」、「90.I」应该是「90.1」,「3A.6」可能是「34.6」。
现在,我的问题可以限缩成几个也许和ML或DL有关的问题:
1.
中文的自动校正可以怎麽达成?
我有想过用jieba断词,去断已知、正确的科目名称,再尝试做模糊搜索,
(虽然实务上要怎麽做模糊搜索也还不清楚),
但是,例如「国文」再断也就是「国」「文」,
用「文」的话「英文」跟「团文」都变国文,「国语」校正不到;
用「国」的话「团文」就校正不到。
这还没解决成绩中也许「优秀」跟「忧秀」都是「优秀」。
感觉需要一个能自我学习的常用词系统,但不知道怎麽开始。
2.
要怎麽根据单一个文字框的内容,去判断它属於哪一类?
我稍微查过text classification,好像都是对一整篇文章做分类,
例如Stack Overflow的auto-tag,或是垃圾邮件的区辨。
但我今天需要的却是根据也许十个字元以下的内容,
判断它是上述步骤2中abcd,还有e(无意义文字框如「分数」)的哪一种。
我初步的想法是把每个文字框内容转成向量,再做KNN,
但我直觉认为很难分得出来,
尤其里面有好几个栏位都可能有文数字掺杂,又或者多个栏位都是数字。
例如:成绩中有「优」、「95」这两个文字框;
同时,前标 - 後标参考范围中也有「优」、「88-96」这两个文字框。
直觉上它们的向量都是相近的。
拜托各位高手不吝赐教,谢谢~
※ 引述《parcequetoi (Sky)》之铭言:
: 作业系统: Linux
: 问题类别: OCR
: 使用工具: Python 3, Google Vision API
: 问题内容:
: 最近正在玩Google Vision API,
: 目标是透过OCR辨认出一份报告/成绩单的内容(格式不限),
: 并转存成後续可再利用分析的档案(e.g. json, csv, txt... 这部分还没想好)。
: 想像有以下三种成绩单:
: --------
: XXX高中
: 姓名:王小明 性别:男
: 考试日期:2018/01/10
: 语文能力
: 科目 分数 班平均
: 国文 70 75
: 英文 86 87
: 自然科学
: 科目 分数 班平均
: 物理 40 30
: 化学 93 60
: --------
: 实事求是 精益求精
: 姓名:李大同 性别:男
: 考试日期:2018-01-09
: 科目 分数 班平均
: 国文
: CHINESE 90 80
: 数学
: MATHEMATICS 89 90
: --------
: 姓名:黄小美
: 性别:女
: 学号:970284
: 试验日期:2018-01-08
: 考试科目 全班平均 实得分数
: CHINESE 国文 60 84
: MATHEMATICS 数学 90 92
: --------
: 这三种照片如果整理成CSV,大概都会希望长得像:
: 科目,分数,班平均
: 国文,70,75
: 英文,86,87
: 物理,40,30
: 化学,93,60
: 即英文科目名称忽略不计,留下分数及班平均。
: 至於照片最上面的个人资料都忽略。(如果能留下考试日期当然也不错)
: 目前我已经做到透过Google Vision API的text detection读出照片上的文字资讯,
: (document text detection我也试过但效果不好)
: (https://cloud.google.com/vision/docs/ocr)
: 并且把每个文字框内容依像素座标由上到下、由左到右排列。
: 但紧接着碰到两个问题:
: 1. 成绩单上同列资料y座标轴可能不同
: 可能因为成绩单纸张不平整或照相时有歪斜,
: 所以由上到下、由左到右排列完後,
: 可能会有「75,国文,70」这样的顺序,而非期待的「国文,70,75」。
: 这部分我想到或许可手动用rule-based的方法,
: 如任两个文字框y座标不超过n单位就视为同一列之类的,
: 但也想请问有没有更好的做法?
: 2. 分辨各栏位内容
: 各家的个人资料排列方式与位置均不同(置中置左置右),
: 有些的科目名称只有中文,有些是中英文对照,
: 中英文对照的又可以有在同一行写或分两行写等变化,
: 有些把班平均摆前面栏位,有些摆後面......
: 我曾经想过初步的想法是把每个文字框的x座标做x-means clustering,
: 再从x座标小的群开始,把每个cluster的内容依y座标排列下来,
: 原本预期可以避开上述问题1,
: 但是这方法却不能排除无用的文字框
: (e.g. 「姓名」、「语文能力」、多余的英文科目列),
: 导致每个cluster的元素数量不会一样多,却又不是每个元素都需要;
: 另外也不能分辨每一个cluster内表示的究竟是班平均还是个人分数。
: 想请问板上高手,有没有人有相关的资源或实务经验可以分享?谢谢!
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 203.74.120.191
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/DataScience/M.1525927544.A.2ED.html
※ 编辑: parcequetoi (203.74.120.191), 05/10/2018 13:07:47