如何训练专属的OCR文字识别模型

news2024/10/6 10:25:54

1. 背景

在10月24日程序员节,公司决定向每位技术人员发放购物实体卡以示庆祝。然而,手动输入实体卡上的一大串卡密可能是一项繁琐且不那么智能的任务;同时,线上用户在绑定购物卡的时候,同样也是需要手动输入。

基于以上背景,我们决定开发一套能够自动识别卡密的OCR文字识别模型:简单地将卡密放在相机前,便可以无需费心记忆和手动输入卡密,快速完成兑换过程,减少了可能存在的人为错误,以带来更便捷的用户体验

2. 基于通用模型的识别

2.1 OCR框架选型

随着文档数字化的发展,光学字符识别 (OCR) 变得越来越流行。OCR 在处理基于图像的文档中发挥着至关重要的作用。在文字识别方面,主要有两款主流的开源框架Tesseract和EasyOCR。

根据参考文献[1]中进行的一项实验,Tesseract 在字母识别方面做得更好,而 EasyOCR 在数字识别方面做得更好。在我们的实际使用场景下,字母的使用频率要远高于字母,因此我们选择使用Tesseract,它是一款目前由 Google 维护的开源 OCR引擎。

2.2 OCR框架安装&使用

如果你使用的是Mac系统,可以直接使用Homebrew进行安装:

brew install tesseract

框架自带的少量通用模型存储在/usr/local/share/tessdata目录下,后缀名为.traineddata,如果需要更多类型的通用模型,可以从github中下载并导入该目录下。GitHub - tesseract-ocr/tessdata_best: Best (most accurate) trained LSTM models.
模型使用可以直接在命令行中输入:

tesseract <input-pic-path> <output-path> -l <model-name> --psm 7

2.3 通用模型的识别效果

我们使用最通用的英文数字模型eng.traineddata,对一张实体卡的卡密进行识别,效果如下,可以看到,识别效果很一般,错误率较高,不仅把特殊字体的0识别成了B,还可能会把B识别成E。原因就是我们的卡密字体并不是一种常规字体,会造成通用模型的识别困难。
初步识别效果

2.4 交互层面弥补错误识别

针对通用模型识别错误率高的问题,首先想到的是交互方面的优化
将容易识别错的相似元素进行分组,譬如0、8、B、E为一组,R、A为一组等等。当识别到存在组内元素的时候,为用户提供一个用于交互的UI滚轮组件,使用户能够手动修正为组内的其他相似元素。
思考再三,还是觉得这样的解决方案太粗暴了,用户可能会疑惑为什么OCR每次都需要手动修正,这么明显的数字0为什么识别不出来?最终还是放弃了从交互层面来弥补错误的思路。

3. 训练专属的OCR模型

Tesseract除了可以使用官方提供的语言包(traineddata文件),还可以自己训练模型,特别适用于某些官方语言包识别效果不佳的场景下。本章将基于Tesseract-OCR5.0来训练自己的模型、以及如何提高准确率。
由于购物卡的卡密字体在生产过程中是不会改变的,因此我们可以根据它的字体样本,来训练一套专属的OCR模型,来改善通用模型在识别过程中的一些错误,提高OCR的准确率。

3.1 模型训练 - 样本采集准备

训练的前置准备工作就是样本采集,字体的数量千千万,我们无法通过肉眼识别实体卡的卡密到底用了哪种字体。首先我们尝试使用字体识别工具,发现最相似的字体匹配程度也只在70%左右,由于样本本身并不是百分百的匹配,经过后续的训练测试验证,识别效果也确实不理想。
字体寻找
解铃还须系铃人,只能想方设法找购物卡的制造商来解决了。经过沟通,然而制造商回应:
样本寻找
因此我们并不能拿到卡密字体的电子样本,为了不让这次沟通无功而返,我打算让制造商将0~9、A~Z打印出来并拍照。于是便有了下面这张照片,也是仅有的可用于训练的样本。
样本寻找

3.2 模型训练 - 生成用于训练的tif和box文件

首先生成训练用的tif文件,需要将多个训练图片合成到一个tif文件里。tif文件格式是一种用于存储图像数据的文件格式,具有无损压缩、支持多页等特性。我们可以直接使用jTessBoxEditor工具来完成,工具下载地址VietOCR - Browse /jTessBoxEditor at SourceForge.net。
打开jTessBoxEditor,选择Tools -> Merge TIFF,进入训练样本所在文件夹,选中要参与训练的样本图片,并将tif文件命名为"eng.myfont.exp0.tif"。

tif文件命名格式 [lang].[fontname].exp[num].tif
lang是语言名,fontname是字体名称,num为自定义版本号

tif
接着,在训练目录下打开cmd,输入下面命令,用现有的eng模型初步识别.tif文件并生成对应的.box文件,执行后在当前路径下生成 “eng.myfont.exp0.box” 文件。

tesseract eng.myfont.exp0.tif eng.myfont.exp0 -l eng --psm 7 batch.nochop makebox

box文件中将记录每个字符在图片上的位置以及识别出的内容。其中,psm参数用于设置识别模式,7代表将图像视为单个文本行,我们的场景使用的是单行统一文本,因此采用参数7。其他psm常用参数所代表的识别模式汇总如下:

0    Orientation and script detection (OSD) only.
1    Automatic page segmentation with OSD.
2    Automatic page segmentation, but no OSD, or OCR.
3    Fully automatic page segmentation, but no OSD. (Default)
4    Assume a single column of text of variable sizes.
5    Assume a single uniform block of vertically aligned text.
6    Assume a single uniform block of text.
7    Treat the image as a single text line.
8    Treat the image as a single word.
9    Treat the image as a single word in a circle.
10    Treat the image as a single character.
11    Sparse text. Find as much text as possible in no particular order.
12    Sparse text with OSD.
13    Raw line. Treat the image as a single text line, bypassing hacks that are Tesseract-specific.

3.3 模型训练 - 矫正box文件错误

由于我们使用的是通用模型对tif进行的初步识别,因此box文件中字符的内容和位置大概率是会出错的,且需要来手动调整的。依然使用jTessBoxEditor工具,点击Box Editor -> Open,打开步骤2中生成的“zwp.test.exp0.tif”,会自动关联到“zwp.test.exp0.box”文件,这两文件要求在同一目录下。
下图是对box文件中字符内容和位置的错误纠正示例:
纠错1
纠错2
调整完样本中的错误之后,点击"save"保存修改。box文件中的字符信息也会相应地进行更改,只是jTessBoxEditor工具帮助我们可视化地完成了这件事。

3.4 模型训练 - 生成基于通用模型的lstm文件

从0到1开始训练一个新模型需要海量的样本和超强的算力,如果样本不足容易过拟合,不适合我们快速出结果,因此我们的模型将基于已有通用模型进行微调训练
从步骤2.2中的tessdata_best代码库里,下载所需语言的通用模型.traineddata文件,在本案例中选择下载eng.traineddata文件,并将该文件保存到当前工作目录下。并使用combine_tessdata命令,用当前目录下的eng.traineddata文件生成eng.lstm文件:

combine_tessdata -e eng.traineddata eng.lstm

打印输出:

Extracting tessdata components from eng.traineddata
Wrote eng.lstm
Version:4.00.00alpha:eng:synth20170629:[1,36,0,1Ct3,3,16Mp3,3Lfys64Lfx96Lrx96Lfx512O1c1]
17:lstm:size=11689099, offset=192
18:lstm-punc-dawg:size=4322, offset=11689291
19:lstm-word-dawg:size=3694794, offset=11693613
20:lstm-number-dawg:size=4738, offset=15388407
21:lstm-unicharset:size=6360, offset=15393145
22:lstm-recoder:size=1012, offset=15399505
23:version:size=80, offset=15400517

Tesseract从版本4.0开始,训练方法使用的是基于LSTM的深度学习网络,lstm文件的命名也由此而来,为模型训练的中间产物。

3.5 模型训练 - 基于样本生成lstmf文件

这一步利用tif图片文件生成lstmf文件,如下命令会生成eng.myfont.exp0.lstmf文件,这个是典型tesseract命令:

tesseract eng.myfont.exp0.tif eng.myfont.exp0 -l eng --psm 7 lstm.train

--参数介绍--
0  eng.myfont.exp0.tif   输入图像
1  eng.myfont.exp0       输出的lstmf文件名称
2  -l eng                使用的基础模型名称
3  --psm 7               分割模式,上文已介绍
4  lstm.train            指明进行lstm训练

生成lstmf之后,在同层级目录下新建一个eng.training_files.txt文本文件,将lstmf的绝对路径写入文件,在我本地电脑中的文本文件如下所示:

/Users/calvin/tesseract/training/eng.myfont.exp0.lstmf

3.6 模型训练 - 开始训练

使用lstmtraining命令开始训练,这一步将生成训练中间文件_checkpoint:

lstmtraining 
--model_output="/Users/calvin/tesseract/training/" 
--continue_from="/Users/calvin/tesseract/training/eng.lstm" 
--train_listfile="/Users/calvin/tesseract/training/eng.training_files.txt"
--traineddata="/Users/calvin/tesseract/training/eng.traineddata" 
--debug_interval -1 
--max_iterations 2000 
--target_error_rate 0.01
  • –debug_interval -1 调试打印等级
  • –max_iterations 2000 最大迭代次数
  • –target_error_rate 0.01 期望错误率
  • –continue_from 基于eng字体的lstm文件
  • –model_output 输出checkpoint文件的名称
  • –train_listfile 训练清单文件名称
  • –traineddata 训练使用的字体

输出打印:

Loaded file /Users/calvin/tesseract/training/eng.lstm, unpacking...
Continuing from /Users/calvin/tesseract/training/eng.lstm
Loaded 5/5 lines (1-5) of document /Users/calvin/tesseract/training/eng.myfont.exp0.lstmf
Iteration 0: GROUND  TRUTH : 0124567890
Iteration 0: BEST OCR TEXT : 8124567898
File eng.myfont.exp0.lstmf line 0 :
Mean rms=2.635%, delta=7.463%, train=40%(100%), skip ratio=0%
Iteration 1: GROUND  TRUTH : RSTUVWXYZ
Iteration 1: BEST OCR TEXT : RSTUUWSEYZ
File eng.myfont.exp0.lstmf line 1 :
Mean rms=2.764%, delta=8.649%, train=47.778%(100%), skip ratio=0%
..........
..........
At iteration 15/1100/1100, mean rms=0.033%, delta=0.000%, BCER train=0.000%, BWER train=0.000%, 
skip ratio=0.000%, New best BCER = 0.000 wrote best model:/Users/calvin/tesseract/training/_0.000_15_1100.checkpoint wrote checkpoint.
Finished! Selected model with minimal training error rate (BCER) = 0

3.7 模型训练 - 基于训练结果生成模型文件

使用lstmtraining命令结束训练,这一步将生成traineddata模型文件:

lstmtraining --stop_training 
--traineddata="/Users/calvin/tesseract/training/eng.traineddata" 
--continue_from="/Users/calvin/tesseract/training/_checkpoint" 
--model_output="/Users/calvin/tesseract/training/yx.traineddata"
  • –stop_training 停止训练
  • –traineddata 训练使用的字体
  • –continue_from 训练中间文件名称
  • –model_output 生成模型文件的名称

输出日志:

Loaded file /Users/calvin/tesseract/training/_checkpoint, unpacking...

3.8 模型测试

最后将生成的yx.traineddata文件拷贝到tesseract安装目录的tessdata路径下,即完成字体的安装。再次使用2.2中提及的命令,对我们的模型进行测试:

tesseract <input-pic-path> <output-path> -l yx --psm 7

result
可以看到,在我们的新模型下,图片的OCR识别效果得到了很大的改善,错误率明显降低

4. 模型准确率优化

从前面的训练步骤可以看到,开始训练时需要用到一个已存在的模型eng.traineddata,比如第3.4步抽取它的lstm文件、第3.6步的训练等。既然这个原始字体训练出来的新字体识别的准确率不高,那我们是不是可以用训练好的新字体替代eng.traineddata再训练一次呢,这样产生的第2代的新字体会不会有更好地表现?
基于参考文献[4]中的测试结果,在大量测试数据下,第二次迭代后的识别准确率是要明显高于第一次的,且不受psm识别模式的影响,同时在后续第三次、第四次、第五次迭代后准确率则提升不明显
retrain
因此,在兼顾效率和准确率的前提下,我们选择可以对模型进行二次迭代优化,回到步骤3.4步~步骤3.7,将eng.traineddata相关的内容替换为yx.traineddata,新生成的第2代模型取名为yx2.traineddata,得到更高精度的字体识别模型。

5. 模型在移动端上的落地应用

all
模型在移动端上的落地应用需要分三层工作来完成:

  • 模型的训练放到本地进行,经过反复测试、优化,将训练好的文件模型上传到服务器。
  • 服务器负责为移动端提供接口,提供简单的版本管理和资源下发。
  • 应用端基于Tesseract SDK提供模型解析环境,并将模型应用于具体的OCR场景中。

6. 总结与后续工作

基于上文的训练过程,我们完成了针对特定字体的OCR模型识别训练,和通用模型相比,我们在特定字体场景下具有更高程度的OCR识别准确度。后续的工作主要从以下两方面进行:

  • 大量测试与纠错优化
    使用更多的购物卡对模型进行测试,若出现识别错误,则基于出错样本对已有模型继续进行训练优化。
  • 移动端上的资源下载/管理的能力建设
    生成的模型的大小约15MB左右,说大不大,说小也不小。可以肯定的是,无论如何都不可能把模型内置于移动端的安装包中,原则上是按需下发加载,因此需要移动端上具有资源下载的基础能力,需要考虑资源下载失败、版本更新、完整性校验等工作。最后,模型的下发与否需要遵从用户的意愿,因此在业务层面,需要保留OCR和手动输入两种入口。

7. 参考文献

  1. OCR Engine Comparison — Tesseract vs. EasyOCR

  2. Tesseract OCR in Python with Pytesseract andOpenCV

  3. Tesseract-OCR页面分割模式 (PSM) 使用详解

  4. Tesseract-OCR5.0字体训练以及提高准确率、提升训练效率的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1247472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql基础操作(命令行)

文章目录 Mysql基础操作&#xff08;命令行&#xff09;背景创建数据库选择数据库查看所有表查看表结构向表插入数据插入第一条插入第二条插入第三条 查询表数据修改表数据删除表数据 Mysql基础操作&#xff08;命令行&#xff09; 背景 docker安装mysql8&#xff0c;映射本地…

额温枪方案,MS8551,MS8601;MS1112,MS1100

鉴于测温的传感器信号非常微弱&#xff0c;需要用高精度、低噪声的运算放大器和高精度、低功耗的ADC。 运算放大器可供选择&#xff1a;MS8551 or MS8601&#xff0c;具有低失调&#xff08;1uV&#xff09;、低噪&#xff08;22nV√Hz &#xff09;、封装小等优点&#xff0c…

34970A 数据采集 / 数据记录仪开关单元

34970A 数据采集 / 数据记录仪开关单元 产品综述&#xff1a; Keysight 34970A 数据采集/数据记录仪开关单元由一个 3 插槽主机和一个内置的 6 1/2 位数字万用表组成。每个通道可以单独配置&#xff0c;以测量 11 种不同功能之一&#xff0c;这样既不会增加成本&#xff0c;也…

喜讯!云起无垠成为国家信息安全漏洞库(CNNVD)技术支撑单位

近日&#xff0c;云起无垠凭借其在漏洞挖掘、漏洞检测以及漏洞修复等领域的卓越表现&#xff0c;荣获“国家信息安全漏洞库&#xff08;CNNVD&#xff09;技术支撑单位等级证书&#xff08;三级&#xff09;”&#xff0c;正式成为CNNVD技术支撑单位。 中国国家信息安全漏洞库&…

科普:多领域分布式协同仿真

分布式协同仿真是一种在分布式计算环境中进行协同工作的仿真方法。使用该方法进行协同仿真时&#xff0c;仿真任务将被分发到多个计算节点上&#xff0c;并且这些节点可以同时工作以模拟完整的系统行为。分布式协同仿真已被广泛应用于工程、科学和军事领域&#xff0c;以便更好…

Python开源项目之人工智能老照片修复算法学习

文章目录 前言项目环境搭建conda虚拟环境创建激活环境Pytorch安装Synchronized-BatchNorm-PyTorch repository安装Global目录Synchronized-BatchNorm-PyTorch项目部署检测预处理模型下载下载脸部增强模型文件下载依赖完整部署后项目结构 项目使用验证一下总结关于Python技术储备…

【matlab程序】南海土台风画法

【matlab程序】南海土台风画法 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深地图图像修饰 【Python海洋专…

应用场景丨社区燃气管网监测系统建设

燃气作为现代社会的重要能源&#xff0c;燃气被广泛应用于居民生活、工业生产、商业服务等领域。然而&#xff0c;燃气泄漏事故时有发生&#xff0c;不仅给人们的生命财产安全带来严重威胁&#xff0c;也给燃气行业的发展带来不良影响。因此&#xff0c;对于燃气管道的监测和管…

你再不学Git就来不及了!!!

其他系列文章导航 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 版本控制 什么是版本控制 为什么要版本控制 一、认识 Git 1.1Git 简史 1.2Git 与其他版本管理系统的主要区别 1.3Git 的三种状态 二、Git 使用快速入门 2.1获…

conan 入门(三十三):requirements()指定header的可见性(transitive_headers)

package_type 从conan 2.x开始conafile.py增加了一个字段package_type&#xff0c;用于定义当前package的类型&#xff0c; 参见 package-type 如果我们在写conanfile.py时不指定这个成员&#xff0c;则它默认为library Requirement traits 不同的包类型定义默认定义不同的…

手把手webpack搭建前端架子

这里以react为例> (一)初始化package.json package name: 你的项目名字叫啥 version: 版本号 description: 对项目的描述 entry point: 项目的入口文件&#xff08;一般你要用那…

web静态网页设计与制作-基于HTML+CSS+JS实现旅游摄影网站

web静态网页设计与制作&#xff0c;基于HTMLCSSJS实现精美的旅游摄影网站&#xff0c;拥有极简的设计风格&#xff0c;丰富的交互动效&#xff0c;让人眼前一亮&#xff0c;享受视觉上的体验。 我使用了基本的HTML结构来构建网页&#xff0c;并使用CSS样式进行美化设计&#xf…

在 Ubuntu 上安装最新版的 Calibre

目录 前言 方法1&#xff1a;从 Ubuntu 的仓库安装 Calibre 卸载 Calibre 方法2&#xff1a;获取最新版本的 Calibre 卸载 Calibre 结语 前言 Calibre 是一款自由开源的电子书软件。下面介绍如何在 Ubuntu Linux 上安装它。 作为电子书管理的瑞士军刀&#xff0c;Calibre …

软件开发的高效神器,程序员爱不释手

目录 一、低代码助力开发 二、低代码核心功能 1.业务建模&#xff1a; 2.表单建模&#xff1a; 3.页面建模&#xff1a; 4.流程建模&#xff1a; 5.报表建模&#xff1a; 6.门户建模&#xff1a; 7.大屏建模&#xff1a; 8.移动建模&#xff1a; 三、低代码解放程序员的双手 在…

POE交换机——电源解决方案-升压控制器\降压控制器\中高压降压转换器

PoE是一种有线以太网供电技术&#xff0c;使用于数据传输的网线同时具备直流供电的能力&#xff0c;PoE供电具有可靠、连接简捷、标准统一的优势。越来越多的工业物联网设备开始采用PoE供电&#xff0c; 如IP电话、网络视频监控以及无线以太网设备等。 PoE交换机是一种用于提供…

VMware Workstation 17 虚拟机自启动失效 解决脚本

VMware Workstation17新增加了虚拟机自启配置 但是很奇怪在我的一台计算机上能够自启&#xff0c;在另一台计算机上就失效 编写脚本 以命令方式完成虚拟机开机自启 #虚拟机自启.batif "%1""hide" goto CmdBegin start mshta vbscript:createobject("w…

安卓手机SD卡不小心删除了怎么办?几步轻松恢复数据!

随着科技的不断发展&#xff0c;安卓手机已经成为了我们生活中不可或缺的一部分。然而&#xff0c;在使用安卓手机的过程中&#xff0c;我们有时会不小心将重要的文件或者照片删除掉&#xff0c;这无疑会给我们的生活带来不便。那么&#xff0c;当安卓手机的SD卡不小心被删除了…

Ubuntu 22.04.3编译AOSP13刷机

文章目录 设备信息下载AOSP并切换分支获取设备驱动编译系统编译遇到的问题Cannot allocate memoryUbuntu设置USB调试刷机参考链接 设备信息 手机&#xff1a;Pixel 4XL 下载AOSP并切换分支 在清华大学开源软件镜像站下载初始化包aosp-latest.tar。 解压缩&#xff0c;切换到…

【GCC】1:chatgpt:NetworkControllerInterface、GoogCcNetworkController

代码基于 mediasoup-sfu-cpp 中的m77版本。使用chatgpt辅助学习。网络状态估计器:开发中 D:\XTRANS\soup\mediasoup-sfu-cpp\deps\libwebrtc\libwebrtc\api\transport\network_control.h NetworkControllerInterface 网络控制器 此类,使用 网络状态和 通信状态 以 估计网络参…

快看!!电子杂志这样制作!几分钟的事

今天手把手教你怎么轻松制作电子杂志&#xff0c;不费力又不耗时。还能让你的杂志跟专业设计师们排排的相提并论&#xff0c;一起来学习吧&#xff01; 首先&#xff0c;你需要准备一些图片、文字素材&#xff0c;以及一款适合你的电子杂志制作软件。目前市面上有很多电子杂志…