iOCR自定义模板文字识别

更新记录

时间 更新说明
2019.04.25 正式上线,新增开通付费功能
2019.02.27 新增模板矩形裁切、透视裁切功能,让模板更规范,后期识别率更高;新增支持模板替换功能;模板匹配算法优化,识别准确率提升;同时对产品易用性做了多项提升
2019.02.21 优化了浏览器兼容性,新增对Firefox、Safari、IE11浏览器的支持
2019.02.11 分类器中加入增值税发票、出租车票、火车票、定额发票、行程单、大陆护照、机动车销售发票、车辆合格证、户口本的预置分类,用户直接勾选后即可实现对应票据的自动分类并结构化
2019.01.25 模板列表增加模板图片缩略图,查找模板更方便直观
2018.12.27 在识别区字段类型中新增手写数字识别类型,针对手写数字识别率更高
2018.10.31 新增自定义字段类型功能,在“字段类型管理”中针对返回值是有限集合的字段,用户可以上传词典,对该字段输出值进行限定
2018.10.10 分类模型升级,百度自有测试集上,准确率由95%左右全部提升到100%(视具体情况准确率可能有所波动)
2018.08.30 检测模型升级,识别耗时降低20%
2018.08.16 识别模型升级,漏识别率降低15.15%,准确率提升46.68%
2018.07.19 1.新增识别区属性选择,能针对特定类型的识别区提高识别率; 2.新增返回字段置信度;3.表格识别区新增表格线判断功能,识别准确率提升;4.新增参照字段框选引导
2018.06.04 新增票据自动分类功能
2018.03.16 产品易用性提升,优化使用流程
2017.12.25 产品上线

注意!请拒绝使用任何第三方插件使用百度OCR服务

使用第三方非法插件会导致您的 AK / SK 泄露,导致别人可以盗用您的账户进行任意消费! 切勿使用任何第三方插件! 因此导致的账号泄露、恶意消费,请用户自行承担责任。如果您已经使用了相关的插件,建议您立即删除对应appid、更换账户密码、更新所有appid的token,或更换账号!

产品介绍

iOCR自定义模板文字识别是一款可以针对固定版面票据、卡证实现自动分类并实现字段名和字段值对应提取的OCR产品

名词解释

  • 【参照字段】:图片中位置和内容都固定不变的文字,后期上传的图片会以此为依据进行扭正,参照字段的选取会影响图片的识别率,建议选取8个以上且分散在图片四周的参照字段,单个参照字段内的文字不可以换行。
  • 【识别区】:需要识别的值可能出现的范围。
  • 【templateSign】:模板ID,用于指定后期上传的图片用哪个模板来进行识别。
  • 【classifierId】:分类器ID,用于指定使用具体某个分类器,传入本参数后不用再传templateSign参数。

模板制作步骤

总体步骤:

  1. 上传模板图片
  2. 框选参照字段
  3. 框选识别区
  4. 保存 & 试一试
  5. 发布模板

上传模板图片

点击进入产品页面: ai.baidu.com/iocr ,点击“创建模板”后上传一张清晰且摆放端正的模板图片,并对模板进行命名。

框选参照字段

填写完模板名称之后,点击「框选参照字段」标签,使用鼠标在模板图片中框选图片中内容和位置都固定不变的文字,如下图所示的橘色矩形框选区域。

建议:选取8个以上且分散在图片四周的固定文字作为参照字段。

Alt text

框选识别区

点击「框选识别区」标签后鼠标默认启用识别区框选工具。例如单据中常见的日期。此时需要您把日期值所在的区域使用识别区框选工具框选出来,然后在右侧填写这个字段对应的字段名。

如图:蓝色矩形框选的为固定识别区
Alt text

保存之后试一试

点击“保存”之后,选择试一试进行在线测试,如果对效果满意即可发布上线。如果发布之后对想回滚到之前的版本,可以在“修改历史”里选择对应版本进行回滚。
Alt text

发布模板

如果觉得识别效果已经符合要求,可以点击下方的发布按钮进行发布操作;如果觉得效果不好,可以继续编辑/调整模板,然后保存后再测试。注意:只有发布后的模板才能在线上进行接口调用和后期的分类操作。如果没有发布,那么仅仅是生成了一个新的版本,此时对模板的任何修改都不会影响线上调用。

Alt text

发布页面中提示的模板ID也可以在自定义模板管理页查询到,也就是管理页的templateSign
Alt text

线上接口会用到模板ID【templateSign】。接口文档参见此处,当然您可能还有很多其他疑问,建议您可以参考自定义模板文字识别Q&A,或者在论坛发布您的问题,甚至您可以直接加入我们QQ群(群号:570832882),直接找到我们的产品经理、研发同学和运营同学来咨询问题。

高级功能

“带表格区域”模板的制作

功能:对票据中的表格按行列返回每个单元格中的内容。
通过上面的阅读您已经可以制作相对简单的模板,接下来演示一个带有表格识别区的复杂模板:

表格识别区可以针对图像中的表格按行列返回单元格中的值。点击工具栏从左往右第二个小图标Alt text,弹出小框,输入表格的列数。例如本例中的表格共有三列,则输入3,点击插入
Alt text

将左上角蓝色的表格识别区拖到模板图片上表格区域,通过调整顶点、分割线的小白点对识别区进行调整,直至每一列识别区覆盖每一列数据。同时请注意表格识别区覆盖的是表格内容!「不包括表头」
Alt text

模板自动分类功能

功能:让系统匹配票据的模板,无需在调用前指定模板ID,替代人工对票据进行分类
很多客户使用自定义模板文字识别定制了大量模板,但是需要人工先对各类票据进行分类,再选择对应的模板进行结构化识别。为了节省用户票据分类的成本,我们加入了模板自动分类功能,客户在“分类器管理”标签中可以针对所有的自定义模板和百度平台已有的系统模板(如身份证、银行卡、驾驶证等)创建分类器,实现模板的自动分类。

创建分类器

点击“分类器管理”标签进入管理页面,点击“创建分类器”后输入分类器名称和该分类器的应用场景/功能描述后点击确定进入编辑页面。

Alt text

选择参与分类的模板

需要分类的模板分为“我的模板”和“系统模板”,我的模板指客户在自定义模板文字识别中创建的模板,系统模板指百度官网预置的模板(包含了:身份证正面、身份证反面、银行卡、驾驶证、行驶证、车牌、营业执照、护照、增值税发票)。客户可以根据业务需要添加模板参与分类。

Alt text

上传对应模板的训练集

参与分类的如果是百度预置的模板您无需上传训练集,如果参与分类的是您自己制作的模板则需要您准备30到100张同模板的票据打包成ZIP包以后点击“编辑训练集”上传该训练集。当所有的自定义模板都已经上传了符合要求(30到100张、同模板)的训练集后点击“开始训练”。您可以在分类器管理页面查看预计完成的时间并通过刷新查看当前状态。(上传的训练集不会影响模板识别的结果,但是会通过影响分类准确率影响最终的识别结果)
请保证后期分类的图片和训练集中的图片类型(都是扫描件/都是拍照件)、照片质量、拍摄情况尽可能一致,训练集图片越接近后期使用图片,分类效果越好!

Alt text

训练完成后进行效果测试

当您的分类器训练完成后您可以在分类器管理页面点击“测试”上传图片进行分类测试,如果测试结果没有问题点击“发布”即可通过API调用该接口,参数classifierId指定某个已发布的分类器,即可实现该分类器中任意模板的自动识别。如果对分类结果不满意,建议检查训练集数据中是否包含了较多噪声数据,或尝试增加训练集内的图片数量。

自定义字段类型

功能:针对某些字段的输出值是有限集合的情况,通过用户上传字段词典,让系统智能纠正匹配,提高准确率,如婚姻状况、全国省市、教育情况。

创建字段类型

在顶部【字段类型管理】中点击【创建字段类型】,输入名称后点击【上传词典】上传txt词典文档,词典中不同字段值各占一行。
Alt text
如果您的字段为:中国地市县名称、省份名称、中国民族,您可以点击【添加预置类型】,百度已经为您准备好对应的词典文件,直接点击添加后,即可在模板制作时选用。百度也将不断丰富预置词典类型,方便您使用。

制作模板时选用

在制作模板时,当您框选完识别区以后,可以在对应识别区的“字段类型”中找到“我的字段类型”并选择对应类型。这样在识别后我们会根据识别到的结果智能纠正为词典中最接近的词作为结果输出。
Alt text

请求说明

请求示例

HTTP 方法:POST

请求URL: https://aip.baidubce.com/rest/2.0/solution/v1/iocr/recognise

URL参数:

参数
access_token 通过API Key和Secret Key获取的access_token,参考“Access Token获取

Header如下:

参数
Content-Type application/x-www-form-urlencoded

Body中放置请求参数,参数详情如下:

请求参数

参数 是否必选 类型 可选值范围 说明
image true string - 图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式
templateSign false string - 您在自定义文字识别平台制作的模板的ID,举例:Nsdax2424asaAS791823112
classifierId false int - 分类器Id。这个参数和templateSign至少存在一个,优先使用templateSign。存在templateSign时,表示使用指定模板;如果没有templateSign而有classifierId,表示使用分类器去判断使用哪个模板

请求代码示例

请参考通用文字识别(含位置信息版)的代码内容,并更换请求地址。

返回说明

返回参数

字段 类型 说明
error_code int 0代表成功,如果有错误码返回可以参考下方错误码列表排查问题
error_msg string 如果error_code具体的失败信息,可以参考下方错误码列表排查问题
data jsonObject 识别返回的结果
data_isStructured string 表示是否结构化成功,true为成功,false为失败;成功时候,返回结构化的识别结果;失败时,如果能识别,按行返回识别结果,如果不能识别,返回空
data_logId string 调用的日志id
data_templateSign string 图片分类结果对应的模板id或指定使用的模版id
data_scores float 分类置信度,如果指定templateSign,则该值为1
data_ret jsonArray 识别出来的字段数组,每一个单元里包含以下几个元素
字段 类型 说明
word_name string isStructured 为 true 时存在,表示字段的名字;如果 isStructured 为 false 时,不存在
word string 识别的字符串或单字
location jsonObject 字段在原图上对应的矩形框
probability jsonObject 字段的置信度,包括最大,最小和方差

返回示例

{
    "data": {
        "ret": [
            {
                "probability": {
                    "average": 0.998482,
                    "min": 0.9957,
                    "variance": 0.000002
                },
                "location": {
                    "height": 88,
                    "left": 1202,
                    "top": 437,
                    "width": 267
                },
                "word_name": "终点站",
                "word": "天津"
            },
            {
                "probability": {
                    "average": 0.994316,
                    "min": 0.629856,
                    "variance": 0.000281
                },
                "location": {
                    "height": 82,
                    "left": 359,
                    "top": 593,
                    "width": 660
                },
                "word_name": "发车时间",
                "word": "201706092107"
            },
            {
                "probability": {
                    "average": 0.998482,
                    "min": 0.9957,
                    "variance": 0.000002
                },
                "location": {
                    "height": 90,
                    "left": 432,
                    "top": 432,
                    "width": 261
                },
                "word_name": "始发站",
                "word": "北京南"
            },
            {
                "probability": {
                    "average": 0.952242,
                    "min": 0.77037,
                    "variance": 0.008272
                },
                "location": {
                    "height": 79,
                    "left": 879,
                    "top": 464,
                    "width": 252
                },
                "word_name": "车次",
                "word": "C2097"
            },
            {
                "probability": {
                    "average": 0.980604,
                    "min": 0.932502,
                    "variance": 0.000352
                },
                "location": {
                    "height": 74,
                    "left": 982,
                    "top": 877,
                    "width": 206
                },
                "word_name": "乘车人",
                "word": "向宇波"
            },
            {
                "probability": {
                    "average": 0.994155,
                    "min": 0.903164,
                    "variance": 0.000396
                },
                "location": {
                    "height": 65,
                    "left": 1171,
                    "top": 593,
                    "width": 248
                },
                "word_name": "座位号",
                "word": "07车无座"
            },
            {
                "probability": {
                    "average": 0.993914,
                    "min": 1.2888,
                    "variance": 0.000009
                },
                "location": {
                    "height": 67,
                    "left": 429,
                    "top": 674,
                    "width": 193
                },
                "word_name": "价格",
                "word": "54.50"
            }
        ],
        "templateSign": "1c65a67f151df56ba4e29c4dddace5ee",
        "scores": 1,
        "isStructured": true,
        "logId": "153206517722624"
    },
    "error_code": 0,
    "error_msg": ""
}