前语

Vision 是 Apple 在 WWDC2017 推出的一个视觉处理结构,它能够进行人脸检测、文本辨认、条形码检测、图画匹配和一般特征跟踪。它也支持运用自定义 Core ML 模型来完结分类或目标检测等使命。

在这篇文章里,我将运用 Vision 的文本辨认功用来进行身份证信息的提取。废话不多说,让咱们开端吧!

示例代码

import Vision
fun recognizeTextRequest {
    // 初始化 VNImageRequestHandler
    let image = UIImage(named: "xxx")
    var cgOrientation = CGImagePropertyOrientation.right
    guard let image = image else { return }
    switch image.imageOrientation {
        case .up: cgOrientation = .up
        case .upMirrored: cgOrientation = .upMirrored
        case .down: cgOrientation = .down
        case .downMirrored: cgOrientation = .downMirrored
        case .left: cgOrientation = .left
        case .leftMirrored: cgOrientation = .leftMirrored
        case .right: cgOrientation = .right
        case .rightMirrored: cgOrientation = .rightMirrored
    @unknown default:
        fatalError()
    }
    guard let cgImage = image.cgImage else { return }
    let requestHandler = VNImageRequestHandler(cgImage: cgImage, orientation: cgOrientation)
    // 初始化 VNRecognizeTextRequest
    let request = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
    // 默认情况下不会辨认中文,需求手动指定 recognitionLanguages
    request.recognitionLanguages = ["zh-Hans", "zh-Hant"]
    request.usesLanguageCorrection = true
    // 执行 request
    DispatchQueue.global(qos: .userInitiated).async {
        do {
            try requestHandler.perform([request])
        } catch {
            print("Unable to perform the requests: (error).")
        }
    }
}
func recognizeTextHandler(request: VNRequest, error: Error?) {
        guard let observations = request.results as? [VNRecognizedTextObservation] else {
            return
        }
        DispatchQueue.main.async {
            let recognizedStrings = observations.compactMap { observation in
                return observation.topCandidates(1).first?.string
            }
            print(recognizedStrings)
        }
}

完整版代码如上,下面咱们来进行代码阐明。

代码解释

要想运用 Vision 结构,首先要做的第一步肯定是导入该结构。

接着,咱们需求初始化 VNImageRequestHandler 来进行相片的文字提取。VNImageRequestHandler 共支持五种初始化方法,在本篇的示例代码中,咱们运用了 CGImage 来进行初始化。

请注意:由于 CGImageCIImageCVPixelBuffer 的示例目标没有资源的方向信息,所以运用这三种类型初始化时,需求把资源的方向信息也带进去。以下是其他四种初始化方法:

  • CIImageL:能够经过 UIImageciImage 特点取得,需求经过枚举 CGImagePropertyOrientation 来指定,调用 init(ciImage:orientation:options:) 来初始化。
  • CVPixelBuffer:它是 Core Video 的图画资源格式,首要用于实时画面或者电影。 经过 init(cvPixelBuffer:orientation:options:) 进行初始化。
  • NSData:图画数据可能会被紧缩或保存在内存中,也可能在服务器获取。假如在服务器获取资源,请检查从网络下载的图画是否有垂直方向;假如没有,需求调用 init(data:orientation:options:) 将资源的方向信息传递进去。
  • NSURL:图片在磁盘的路径。

为什么 Vision 必需求取得图片的方向呢?由于假如 Vision 假设了错误的方向,它可能无法正确地检测到侧面或上下颠倒的特征。假如是相册中挑选的相片包括方向信息。咱们能够经过 UIImageimageOrientation 特点来取得这些数据。假如你是经过其他方法获取相片,比如从网络或其他应用程序获取相片,假如这些图片没有包括方向信息,则你需求就独自提供。

在 Vision 中,每项功用都是一个 request,不同项的功用运用不同的 request。这儿咱们用到的是文字辨认,所以接下来咱们就需求初始化 VNRecognizeTextRequest 了。

VNRecognizeTextRequest 的初始化参数需求咱们传递一个 completionHandler 来执行辨认完结之后的逻辑。在 completionHandler 里咱们只是简单的打印了一下辨认结果。

然后便是设置一下 recognitionLanguagesusesLanguageCorrection 两个特点的值,由于 Vision 默认情况下不会辨认中文,所以咱们需求给 recognitionLanguages 赋值让 Vision 能够辨认中文。

usesLanguageCorrection 则能够进步文字辨认的准确率,但会多耗费性能。

最终一步便是调用 perform 执行 request 了。由于 Vision 的操作都是比较耗费性能的,所以最好将其放在后台行列里执行,以免堵塞主行列。

Tips:尽管 recognizeTextHandler 的打印代码不回到主行列也没问题,但为了表明假如进行 UI 操作是需求回到主行列的,所以我还是写了 DispatchQueue.main.async

总结

运用 Vision 进行文字辨认需求以下几个过程:

  • 导入 Vision 结构
  • 声明 completionHandler 处理辨认后的逻辑
  • 初始化 VNImageRequestHandler
  • 初始化 VNRecognizeTextRequest
  • handle 执行 request 即可