当前位置:网站首页>用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。
边栏推荐
- 经验分享|盘点企业进行知识管理时的困惑类型
- dotnet 启动 JIT 多核心编译提升启动性能
- 知识分享|如何设计有效的帮助中心,不妨来看看以下几点
- 拼多多开放平台订单信息查询接口【pdd.order.basic.list.get订单基础信息列表查询接口(根据成交时间)】代码对接教程
- [Teach you to use the serial port idle interrupt of the STM32HAL library]
- Cryptography Series: PEM and PKCS7, PKCS8, PKCS12
- proe和creo的区别有哪些
- 数据仓库(1)什么是数据仓库,数仓有什么特点
- [21 days learning challenge - kernel notes] (2), based in the device tree
- Data warehouse (1) What is data warehouse and what are the characteristics of data warehouse
猜你喜欢
AXI interface application of Zynq Fpga image processing - the use of axi_lite interface
Win11如何开启Telnet客户端?
PowerCLi 导入License到vCenter 7
PowerCLi import license to vCenter 7
SPSS-System Clustering Software Practice
立方度量(Cubic Metric)
unity2D横版游戏教程9-对话框dialog
proe和creo的区别有哪些
[2022 Hangzhou Electric Power Multi-School 5 1012 Questions Buy Figurines] Application of STL
1319_STM32F103串口BootLoader移植
随机推荐
三种方式设置特定设备UWP XAML view
路由中的meta、params传参的一些问题(可传不可传,为空,搭配,点击传递多次参数报错)
Android 面试——如何写一个又好又快的日志库?
C#之app.config、exe.config和vshost.exe.config作用区别
LayaBox---TypeScript---举例
js的new Function()常用方法
Arduino 电机测速
括号匹配
大势所趋之下的nft拍卖,未来艺术品的新赋能
Red team kill-free development practice of simulated confrontation
3. Byte stream and character stream of IO stream
OD-Model [6]: YOLOv2
二叉搜索树解决硬木问题
PowerCLi 导入License到vCenter 7
AXI interface application of Zynq Fpga image processing - the use of axi_lite interface
OD-Model【6】:YOLOv2
LayaBox---知识点
【PCBA方案设计】握力计方案
Altium Designer 19.1.18 - 画多边形铜皮挖空时,针对光标胡乱捕获的解决方法
【2022杭电多校5 1003 Slipper】多个超级源点+最短路