ML收藏swiftiOS经验总结

Tesseract OCR框架(二) —— 基于Tesserac

2019-05-26  本文已影响216人  刀客传奇

版本记录

版本号 时间
V1.0 2019.05.26 星期日

前言

Tesseract OCR是谷歌Google维护的一个框架,用于从图片中提取文字,有iOSC++多种版本,在很多领域都有广泛的应用。接下来我们就一起走进这个框架(iOS部分)。感兴趣的可以看下面几篇.
1. Tesseract OCR框架(一) —— 基本概览(一)

开始

在本教程中,您将学习如何使用Tesseract使用OCR读取和处理从图像中提取的文本。

OCR是从图像中电子提取文本的过程。 您以前无疑已经看过它 - 它被广泛用于处理从扫描文档到平板电脑上的手写涂鸦,再到 Word Lens technology in the GoogleTranslate app

在本教程中,您将学习如何使用由Google维护的开源OCR引擎Tesseract从爱情诗中获取文本并使其成为您自己的文本。 准备好留下深刻印象!

在本教程中,您将学习如何使用由Google维护的开源OCR引擎Tesseract从爱情诗中获取文本并使其成为您自己的文本。 准备好留下深刻印象!

打开本教程的材料,然后将文件夹解压缩到方便的位置。

Love In a Snap目录包含另外三个:

在打开Xcode中的Love In A Snap Starter/Love In A Snap.xcodeproj中,然后构建并运行入门应用程序。 点击一下即可了解用户界面。

回到Xcode,看一下ViewController.swift。 它已经包含一些@IBOutlets和空的@IBAction方法,它们将视图控制器链接到其预制的Main.storyboard接口。 它还包含performImageRecognition(_ :),在这里Tesseract最终将完成其工作。

向下滚动页面,你会看到:

// 1
// MARK: - UINavigationControllerDelegate
extension ViewController: UINavigationControllerDelegate {
}
// 2
// MARK: - UIImagePickerControllerDelegate
extension ViewController: UIImagePickerControllerDelegate {
  // 3
  func imagePickerController(_ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    // TODO: Add more code here...
  }
}

现在,轮到你接管并将这个应用程序变为现实!


Tesseract’s Limitations

Tesseract OCR非常强大,但确实有以下限制:

哦哦! 你打算如何在iOS中使用它? Nexor TechnologyTesseract OCR创建了兼容的Swift包装器。


Adding the Tesseract Framework

首先,您必须通过CocoaPods安装Tesseract OCR iOS,这是一个广泛使用的iOS项目依赖管理器。

如果您尚未在计算机上安装CocoaPods,请打开终端,然后执行以下命令:

sudo gem install cocoapods

在请求完成CocoaPods安装时输入您的计算机密码。

接下来,cdLove In A Snap入门项目文件夹。 例如,如果您已将Love In A Snap添加到桌面,则可以输入:

cd ~/Desktop/"Love In A Snap/Love In A Snap Starter"

接着,输入:

pod init

这将为您的项目创建一个Podfile

用以下内容替换Podfile的内容:

platform :ios, '12.1'

target 'Love In A Snap' do
  use_frameworks!

  pod 'TesseractOCRiOS'

end

这告诉CocoaPods您希望将TesseractOCRiOS包含为项目的依赖项。

回到终端,输入:

pod install

pod安装到你的项目

当终端输出指示时,“Please close any current Xcode sessions and use Love In A Snap.xcworkspace for this project from now on.”,在Xcode中打开Love In A Snap.xcworkspace


How Tesseract OCR Works

一般来说,OCR使用人工智能来查找和识别图像中的文本。

一些OCR引擎依赖于一种称为机器学习(machine learning)的人工智能。机器学习允许系统通过识别和预测模式来学习和适应数据。

Tesseract OCR iOS引擎使用称为神经网络(neural network)的特定类型的机器学习模型。

神经网络在人脑中的模型之后被松散地建模。我们的大脑包含大约860亿个连接的神经元,这些神经元被分组成各种网络,能够通过重复学习特定的功能。类似地,在更简单的尺度上,人工神经网络接收多种样本输入,并通过随时间的成功和失败来学习,从而产生越来越准确的输出。这些样本输入称为“训练数据”。

在教育系统时,这个培训数据:

然后将该输出与期望的输出进行比较,并相应地调整边缘权重,使得传递到神经网络的后续训练数据返回越来越准确的结果。

Tesseract寻找像素,字母,单词和句子的图案。 Tesseract使用称为自适应识别(adaptive recognition)的双通道方法。 对数据进行一次传递以识别字符,然后第二次传递以填写任何不太可能符合给定单词或句子上下文的字母的字母。


Adding Trained Data

为了在给定语言的范围内更好地磨练其预测,Tesseract需要特定于语言的训练数据来执行其OCR

导航到Finder中的Love In A Snap/Resourcestessdata文件夹包含一堆英语和法语培训文件。 你将在本教程中处理的爱情诗主要是英文,但也包含一些法语。 Très浪漫主义!

Your poem vil impress vith French! Ze language ov love! *Haugh* *Haugh* *Haugh*

现在,您将tessdata添加到您的项目中。 Tesseract OCR iOS要求您添加tessdata作为引用文件夹。

Add tessdata as a referenced folder

您现在应该在导航器中看到一个蓝色的tessdata文件夹。 蓝色表示引用了文件夹而不是Xcode组。

现在您已经添加了Tesseract框架和语言数据,现在是时候开始使用有趣的编码了!


Loading the Image

首先,您将创建一种从设备的相机或照片库访问图像的方法。

打开ViewController.swift并将以下内容插入takePhoto(_ :)

// 1
let imagePickerActionSheet =
  UIAlertController(title: "Snap/Upload Image",
                    message: nil,
                    preferredStyle: .actionSheet)

// 2
if UIImagePickerController.isSourceTypeAvailable(.camera) {
  let cameraButton = UIAlertAction(
    title: "Take Photo",
    style: .default) { (alert) -> Void in
      // TODO: Add more code here...
  }
  imagePickerActionSheet.addAction(cameraButton)
}

// 3
let libraryButton = UIAlertAction(
  title: "Choose Existing",
  style: .default) { (alert) -> Void in
    // TODO: Add more code here...
}
imagePickerActionSheet.addAction(libraryButton)

// 4
let cancelButton = UIAlertAction(title: "Cancel", style: .cancel)
imagePickerActionSheet.addAction(cancelButton)

// 5
present(imagePickerActionSheet, animated: true)

在这里,您:

import UIKit之后立即添加:

import MobileCoreServices

这使ViewController可以访问kUTTypeImage抽象图像标识符,您将使用它来限制图像选择器的媒体类型。

现在在cameraButton UIAlertAction的闭包中,用以下代码替换// TODO注释:

// 1
self.activityIndicator.startAnimating()
// 2
let imagePicker = UIImagePickerController()
// 3
imagePicker.delegate = self
// 4
imagePicker.sourceType = .camera
// 5
imagePicker.mediaTypes = [kUTTypeImage as String]
// 6
self.present(imagePicker, animated: true, completion: {
  // 7
  self.activityIndicator.stopAnimating()
})

所以当用户点击cameraButton时,这段代码:

同样,在libraryButton的闭包中,添加:

self.activityIndicator.startAnimating()
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
self.present(imagePicker, animated: true, completion: {
  self.activityIndicator.stopAnimating()
})

这与您刚刚添加到cameraButton的闭包中的代码相同,除了imagePicker.sourceType = .photoLibrary。 在这里,您将图像选择器设置为显示设备的照片库而不是相机。

接下来,要处理捕获或选定的图像,请将以下内容插入imagePickerController(_:didFinishPickingMediaWithInfo :)

// 1
guard let selectedPhoto =
  info[.originalImage] as? UIImage else {
    dismiss(animated: true)
    return
}
// 2
activityIndicator.startAnimating()
// 3
dismiss(animated: true) {
  self.performImageRecognition(selectedPhoto)
}

在这里,您:

您将在本教程的下一部分中编写performImageRecognition代码,但是,现在,只需打开Info.plist。 将光标悬停在顶部单元格信息属性列表上,然后在出现时单击+按钮两次。

在这两个新条目的密钥字段中,将Privacy – Camera Usage Description添加到另一个和Privacy – Photo Library Usage Description到另一个。 为每个选择String类型。 然后在Value列中,分别在请求访问其相机和照片库的权限时,输入要向用户显示的任何文本。

构建并运行您的项目。 点击Snap / Upload Image按钮,您将看到刚刚创建的UIAlertController

测试出操作表选项,并在出现提示时授予应用程序访问相机和/或库的权限。 按预期确认照片库和相机显示。

注意:如果您在模拟器上运行,则没有可用的物理相机,因此您将看不到Take Photo选项。

都好? 如果是这样,那么终于可以使用Tesseract了!


Implementing Tesseract OCR

首先,添加import MobileCoreServices以下,使ViewController可以使用Tesseract框架:

import TesseractOCR

现在,在performImageRecognition(_ :)中,用以下内容替换// TODO注释:

// 1
if let tesseract = G8Tesseract(language: "eng+fra") {
  // 2
  tesseract.engineMode = .tesseractCubeCombined
  // 3
  tesseract.pageSegmentationMode = .auto
  // 4
  tesseract.image = image
  // 5
  tesseract.recognize()
  // 6
  textView.text = tesseract.recognizedText
}
// 7
activityIndicator.stopAnimating()

由于这是本教程的内容,这里有一个详细的细分,一行一行:

现在,是时候测试第一批新代码了!


Processing Your First Image

Finder中,导航到Love In A Snap / Resources / Lenore.png以查找示例图像。

Lenore.png是一首写给“Lenore”的爱情诗的形象,但通过一些编辑,你可以把它变成一首肯定会引起你所渴望的人的注意的诗!

虽然您可以打印图像的副本,然后使用应用程序拍摄照片以执行OCR,您可以轻松自己并将图像直接添加到设备的相机胶卷。 这消除了人为错误,进一步照明不一致,文本偏斜和打印有缺陷的可能性。 毕竟,图像已经是黑暗和模糊的。

注意:如果您使用的是模拟器,只需将图像文件拖放到模拟器上即可将其添加到其照片库中。

构建并运行您的应用程序。 点击Snap / Upload Image,点击Choose Existing,然后从照片库中选择样本图像以通过OCR运行它。

注意:您可以放心地忽略TesseractOCR库生成的数百个编译警告。

哦哦! 什么都没出现! 这是因为当前的图像尺寸太大,以至于Tesseract无法处理。 是时候改变了!


Scaling Images While Preserving Aspect Ratio

图像的纵横比aspect ratio是其宽度和高度之间的比例关系。 从数学上讲,要在不影响纵横比的情况下缩小原始图像的大小,必须保持宽高比不变。

当您知道原始图像的高度和宽度,并且您知道最终图像的所需高度或宽度时,您可以重新排列宽高比等式,如下所示:

这导致两个公式。

公式1:当图像的宽度大于其高度时。

Height1/Width1 * width2 = height2

公式2:当图像的高度大于其宽度时。

Width1/Height1 * height2 = width2

现在,将以下扩展和方法添加到ViewController.swift的底部:

// MARK: - UIImage extension

//1
extension UIImage {
  // 2
  func scaledImage(_ maxDimension: CGFloat) -> UIImage? {
    // 3
    var scaledSize = CGSize(width: maxDimension, height: maxDimension)
    // 4
    if size.width > size.height {
      scaledSize.height = size.height / size.width * scaledSize.width
    } else {
      scaledSize.width = size.width / size.height * scaledSize.height
    }
    // 5
    UIGraphicsBeginImageContext(scaledSize)
    draw(in: CGRect(origin: .zero, size: scaledSize))
    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    // 6
    return scaledImage
  }
}

此代码执行以下操作:

现在,在performImageRecognition(_ :)的顶部,包括:

let scaledImage = image.scaledImage(1000) ?? image

这将尝试缩放图像,使其不超过1,000点宽或长。 如果scaledImage()无法返回缩放图像,则常量将默认为原始图像。

然后,将tesseract.image = image替换为:

tesseract.image = scaledImage

这会将缩放后的图像指定给Tesseract对象。

从照片库中再次构建,运行和选择诗歌。

但很可能你的结果并不完美。 还有改进的余地......


Improving OCR Accuracy

“Garbage In,Garbage Out.”提高输出质量的最简单方法是提高输入质量。 正如谷歌在其Tesseract OCR网站上列出的那样As Google lists on their Tesseract OCR site,黑暗或不均匀的照明,图像噪声,倾斜的文本方向和厚厚的暗图像边界都会导致不太完美的结果。

Examples of potentially problematic image inputs that can be corrected for improved results. Source: Google’s Tesseract OCR site.

接下来,您将提高图像的质量。


Improving Image Quality

Tesseract iOS框架曾经有内置的方法来提高图像质量,但是这些方法已被弃用,框架的文档现在建议使用Brad LarsonGPUImage framework框架。

GPUImage可以通过CocoaPods获得,因此在Podfile中的pod'TesseractOCRiOS'下面,添加:

pod 'GPUImage'

然后,在终端中,重新运行:

pod install

现在应该可以在项目中使用GPUImage

注意:它还会添加数百个编译警告。 您也可以放心地忽略它们。

回到ViewController.swift,添加以下import TesseractOCR以使类中的GPUImage可用:

import GPUImage

直接在scaledImage(_ :)下面,也在UIImage扩展名中,添加:

func preprocessedImage() -> UIImage? {
  // 1
  let stillImageFilter = GPUImageAdaptiveThresholdFilter()
  // 2
  stillImageFilter.blurRadiusInPixels = 15.0
  // 3
  let filteredImage = stillImageFilter.image(byFilteringImage: self)
  // 4
  return filteredImage
}

在这里,您:

回到performImageRecognition(_ :),紧接在scaledImage常量实例化下面,添加:

let preprocessedImage = scaledImage.preprocessedImage() ?? scaledImage

此代码尝试通过GPUImage过滤器运行scaledImage,但如果preprocessedImage()的过滤器失败,则默认使用未过滤的scaledImage

然后,将tesseract.image = scaledImage替换为:

tesseract.image = preprocessedImage

这要求Tesseract处理缩放和过滤的图像。

现在您已经完成所有这些工作,再次构建,运行并选择图像。

瞧! 希望您的结果现在比以前更完美或更接近完美。

但如果你眼中的苹果没有被命名为“Lenore”,那么他或她可能不会欣赏这首来自你的诗......他们可能想知道这个“Lenore”角色是谁!

“Lenore”替换为您心爱的人的姓名... presto chango! 你已经为你的爱人和你的爱人创作了一首爱情诗。

而已! 你的Love In A Snap应用程序是完整的 - 肯定会赢得你崇拜的人的心脏。

尝试使用其他文本的应用程序,以查看OCR结果如何在源之间变化,并根据需要下载更多语言数据download more language data

您还可以训练Tesseract以进一步提高其输出。 毕竟,如果你能够用眼睛或耳朵甚至指尖解读字符,你就已经成为字符识别方面的可认证专家,并且完全有能力教你的电脑,而不是已经知道的。

后记

本篇主要讲述了基于Tesseract OCR iOS框架的图片中的文字识别简单示例的基本情况,感兴趣的给个赞或者关注~~~

上一篇下一篇

猜你喜欢

热点阅读