如何使用 iOS Vision 框架识别身份证信息

前言

Vision 是 Apple 在 WWDC2017 推出的一个视觉处理框架,它可以进行人脸检测、文本识别、条形码检测、图像匹配和一般特征跟踪。它也支持使用自定义 Core ML 模型来完成分类或对象检测等任务。

在这篇文章里,我将使用 Vision 的文本识别功能来进行身份证信息的提取。废话不多说,让我们开始吧!

示例代码

swift 复制代码
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 即可
相关推荐
程序猿看视界1 小时前
如何在 UniApp 中实现 iOS 版本更新检测
ios·uniapp·版本更新
dr李四维5 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
️ 邪神5 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱17 小时前
flutter项目苹果编译运行打包上线
flutter·ios
网络安全-老纪18 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
1024小神21 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
lzhdim1 天前
iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录
ios·iphone
安和昂1 天前
【iOS】知乎日报第四周总结
ios
麦田里的守望者江1 天前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
_黎明1 天前
【Swift】字符串和字符
开发语言·ios·swift