用Tesseract开发一个你自己的文字识别应用

前言

这次和⼤家聊聊⽂字识别相关的话题。⼤家在平时肯定对各种扫描类的 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有三种可以选择的模式, tesseractOnlytesseractCubeCombinedcubeOnly。我们使⽤第⼀种模式,采⽤训练数据的⽅式。 cubeOnly 的意识就是使⽤更精准的 cube ⽅式, tesseractCubeCombined 就是两种模式的结合使⽤。

cube 模式需要额外的模型数据,⼤致样例是这样:

上图是英⽂的 cube 识别模型。简体中⽂的模型我暂时没有找到,所以我们这个实例中只是⽤到了 tesseractOnly 模式。并且在没有 cube 模型数据的情况下,我们是不⽤使⽤ tesseractCubeCombinedcubeOnly 的,否则会因为模型数据不存在⽽报错。⼤家如果能够找到中⽂的 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

猜你喜欢

转载自blog.csdn.net/zhanglei5415/article/details/126049883