当前位置:网站首页>用Tesseract开发一个你自己的文字识别应用
用Tesseract开发一个你自己的文字识别应用
2022-08-04 21:26:00 【ReyZhang】
前言
这次和⼤家聊聊⽂字识别相关的话题。⼤家在平时肯定对各种扫描类的 APP 不陌⽣。拿着⼿机摄像头对着任何⽂字,直接将摄像头中的⽂字内容转换成⼿机上可编辑的字符串。
完整的 OCR 算法,并不简单。涉及到图像识别算法,以及将从图⽚中识别出来的⽂字转换成我们程序中可以使⽤的⼆进制形式。这其中还包括不同语⾔的字符如何识别,怎样更精准的识别等等。
设想⼀下,如果作为开发者,让你⾃⼰从头开发这样⼀套算法,恐怕要花掉很⼤⼒⽓。不过好消息是,我们⽣活在这个开源时代,早已经有很多前辈们为我们趟好了道路。这也是我们今天要聊的主题, Tesseract就是这样⼀个开源库,给定任意⼀张图⽚,它可以识别出⾥⾯所有的⽂字内容,并且 API 接⼝使⽤⾮常简单。
Tesseract
Tesseract 是 Google 发布的⼀款 OCR 开源库,它⽀持多个变成语⾔环境,以及运⾏环境,其中包括我们这⾥将要介绍的 iOS 环境。今天就⽤它带领⼤家开发⼀个属于你⾃⼰的 OCR 应⽤。
1.安装 Tesseract
最简单的⽅式是⽤过 Cocoapods,进⼊你的项⽬根⽬录,输⼊:
pod init
然后,编辑⽣成的 Podfile 配置⽂件:
target 'ocrSamples' do
use_frameworks!
pod 'TesseractOCRiOS'
end
将TesseractOCRiOS加⼊配置列表中,最后输⼊:
pod install
2,.配置⼯作
安装完成后,我们还需要进⾏⼀下简单的配置,⾸先要在 Build Phases -> Link Binary With Libraries 中配置,项⽬需要的依赖库, CoreImage, libstdc++, 以及 TesseractOCRiOS ⾃⾝:
配置好依赖库之后,我们还需要将⽂字识别训练数据添加进来,训练数据是什么呢,TesseractOCRiOS识别图⽚的时候,会依照这个训练数据的规则来识别⽂字。⽐如中⽂,英⽂等,都有对应的训练数据,这可以理解为深度学习预先为我们训练好的模型。⽤它来进⾏核⼼的识别算法。
训练数据是需要按照不同语言来区分的,Tesseract 有专门的页面列出了所有可用的训练数据:https://github.com/tesseract-ocr/tessdata/tree/3.04.00
比如我们这里需要识别简体中文,就可以下载 chi-sim 这个训练数据:

然后将训练数据拖放到⼯程中:
上图中的 chi_sim.traineddata 是我们下载的训练数据,这⾥⾯有⼀点要注意的是,这个⽂件必须要在 testdata 这个⽂件夹中。并且这个⽂件夹要以 "Create Folder Reference" 的⽅式拖放进来:
这种引⽤⽅式和另外⼀种 "Create Groups" 的⽅式有什么区别呢?
主要区别在于:
- 使⽤
引⽤⽅式拖放进来的⽬录,在最后⽣成 APP 包的时候,Main Bunlde中是以testdata/chi_sim.traineddata这样的路径形式保存我们训练数据资源的 - 使⽤
"Create Groups"⽅式,最终存储的时候是会忽略⽂件夹名的,最后存储在Main Bundle中的⽂件是以/chi_sim.traineddata这个路径存放的。
注意: ⽽ TesseractOCRiOS,默认情况下是会在 testdata/chi_sim.traineddata 这个路径查找训练数据的,所以如果使⽤"Create Groups" ⽅式拖⼊,会造成运⾏时找不到训练数据,⽽报错。这点细节需要格外注意。
最后, 为了让 TesseractOCRiOS 能够正确运⾏,我们还需要关掉 BitCode,否则会报编译错误,我们需要在两处都要关掉它,⼀个是⾄⼯程,另外⼀个是 Pods 模块,如下图:
3. 开始编码
做完上述的准备⼯作后,我们就可以开始编码了,这⾥只给⼤家展⽰最精简的代码。⾸先我们需要在主界⾯上显⽰两个控件,⼀个是我们预先存储好的带有⽂字的照⽚,另外⼀个是⽤于展⽰识别结果的⽂本框:
override func viewDidLoad() {
super.viewDidLoad()
self.imageView = UIImageView(frame: CGRect(x: 0, y: 80, width: self.view.frame.size.width, height:
self.view.frame.size.width * 0.7))
self.imageView?.image = UIImage(named: "textimg")
self.view.addSubview( self.imageView!)
self.textView = UITextView(frame: CGRect(x: 0, y: labelResult.frame.origin.y + labelResult.frame.size.height + 20, width: self.view.frame.size.width, height: 200))
self.view.addSubview( self.textView!)
}
这⾥⾯我们只将两个控件的初始化关键代码写出来,其他不重要的代码都略去。然后就可以调⽤ TesseractOCRiOS 来进⾏⽂字识别了:
func recognizeText(image: UIImage) {
if let tesseract= G8Tesseract(language: "chi_sim") {
tesseract. engineMode= .tesseractOnly
tesseract. pageSegmentationMode= .auto
tesseract. image= image
tesseract.recognize()
self.textView?. text= tesseract.recognizedText
}
}
所有识别相关的代码就都在这⾥了。⾸先调⽤ G8Tesseract 进⾏初始化,我们传⼊训练数据的名称,这⾥是 "chi_sim"代表简体中⽂。
engineMode有三种可以选择的模式, tesseractOnly,tesseractCubeCombined 和 cubeOnly。我们使⽤第⼀种模式,采⽤训练数据的⽅式。 cubeOnly 的意识就是使⽤更精准的 cube ⽅式, tesseractCubeCombined 就是两种模式的结合使⽤。
cube 模式需要额外的模型数据,⼤致样例是这样:
上图是英⽂的 cube 识别模型。简体中⽂的模型我暂时没有找到,所以我们这个实例中只是⽤到了 tesseractOnly 模式。并且在没有 cube 模型数据的情况下,我们是不⽤使⽤ tesseractCubeCombined 和 cubeOnly 的,否则会因为模型数据不存在⽽报错。⼤家如果能够找到中⽂的 cube 模型,也欢迎在留⾔中反馈,这样会让这个⽂字识别更加精准。
其他的调⽤就不需要多讲了,将要识别的 image 对象设置给 Tesseract。然后调⽤它的 recognize ⽅法进⾏识别,最后将识别结果 tesseract.recognizedText 设置给 TextView。
最终的运⾏效果如下:
上⾯的图⽚是我拍的 SwiftCafe ⽹站上⼀篇⽂章的照⽚,从识别结果上看,还算⽐较准确。
总结
⼤家从上⾯的代码中应该也感受到了, Tesseract 虽然提供了本质上算是⽐较复杂的⽂字识别算法,但它提供给开发者的接⼝可以说得上是⾮常简单。 OCR ⽂字识别从整体上来说,也可以算得上是 AI 的⼀个应⽤分⽀,在这个 AI ⼤⾏其道的时代,即便掌握⼀些应⽤技术,对我们开发者来说也可以很⼤的拓宽我们的视野。发挥你的创意,也许类似Tesseract 这些组件能够帮助你创造 AI 时代的新锐应⽤。
Tesseract 这些组件能够帮助你创造 AI 时代的新锐应⽤。
当然, Tesseract ⽬前⾃⾝还有⼀些缺陷,⽐如它只能识别印刷字体,⽽不能精准的识别⼿写字体。不过那⼜怎么样呢,本来相当复杂的 OCR 算法,可以让我们⽤⾮常少的代价应⽤起来,还是⼀件对开发者⾮常幸福的事情。
照例,本文中的示例工程代码已经放到 Github 中,大家有需要可以直接下载:https://github.com/swiftcafex/Samples/tree/master/ocrSamples。
边栏推荐
猜你喜欢

DGL安装教程

stm32mp157系统移植 | 移植ST官方5.10内核到小熊派开发板

【2022杭电多校5 1012题 Buy Figurines】STL的运用

laravel whereDoesntHave

Yolov7:Trainable bag-of-freebies sets new state-of-the-art for real-time objectdetectors

js数据类型、节流/防抖、点击事件委派优化、过渡动画

PRIMAL: Pathfinding via Reinforcement and Imitation Multi-Agent Learning 代码解析

JWT actively checks whether the Token has expired
![[Teach you to use the serial port idle interrupt of the STM32HAL library]](/img/9e/88a11727e1452315edc2c8ac74690e.png)
[Teach you to use the serial port idle interrupt of the STM32HAL library]

PowerCLi batch configuration of NTP
随机推荐
立即升级!WPS Office 出现 0day 高危安全漏洞:可完全接管系统,官方推出紧急更新
【2022杭电多校5 1003 Slipper】多个超级源点+最短路
零基础都能拿捏的七夕浪漫代码,快去表白或去制造惊喜吧
LayaBox---TypeScript---首次接触遇到的问题
AtCoder Beginner Contest 262 D - I Hate Non-integer Number
NFT宝典:你需要知道NFT的术语和定义
C语言知识大全(一)——C语言概述,数据类型
【SQL之降龙十八掌】01——亢龙有悔:入门10题
dotnet 通过 WMI 获取系统安装软件
硬件开发定制全流程解析
[21天学习挑战赛——内核笔记](二)——设备树基础
88. (the home of cesium) cesium polymerization figure
顺序队列
数电快速入门(五)(编码器的介绍以及通用编码器74LS148和74LS147的介绍)
3、IO流之字节流和字符流
dotnet 使用 lz4net 压缩 Stream 或文件
AXI interface application of Zynq Fpga image processing - the use of axi_lite interface
PRIMAL: Pathfinding via Reinforcement and Imitation Multi-Agent Learning 代码解析
Common methods of js's new Function()
PowerCLi import license to vCenter 7