SwiftOCR在手机号/数字识别App中的应用

SwiftOCR在手机号/数字识别App中的应用

数字识别的基本过程

SwiftOCR在手机号/数字识别App中的应用_第1张图片
数字识别的基本过程

在第一,二步图像获取与预处理后

步骤三使用 Connected-component labeling 技术实现了文字的分割,这是识别前关键的一步.

步骤四,对图片进行缩放 转换为16x20的二进制数组 做为神经网络输入前的准备

步骤五,对这组数据跑神经网络

步骤六,输出运算结果 98.99的可能性是数字1.

SwiftOCR简介

SwiftOCR是一个由Swift编写的快速简单的光学字符识别库,使用FFNN神经网络进行图像识别.针对0~9 A~Z的目标字符进行识别.

SwiftOCR的作者对为什么使用SwiftOCR代替经典的Tesseract 有如下论述:

If you want to recognize normal text like a poem or a news article, go with Tesseract, but if you want to recognize short, alphanumeric codes (e.g. gift cards), I would advise you to choose SwiftOCR because that's where it exceeds.

Tesseract is written in C++ and over 30 years old. To use it you first have to write a Objective-C++ wrapper for it. The main issue that's slowing down Tesseract is the way memory is managed. Too many memory allocations and releases slow it down.

改造过程

首先业务目标: 识别印刷体的手机号.

第一步,重新训练数据训练集,使用程序生成各种系统字体的0~9的数字进行训练,输出新的OCR-Network文件.

第二步,图像输入改为视频流.

第三步,优化--提高帧率.

优化逻辑与具体代码

1⃣️ 经过测试 识别算法运行中,仍然会有数据的到达.如果算法正在运行,则直接返回.

2⃣️ 识别算法在对数字串进行分割处理时,会调用比较重的由GPUImage库提供的Connected-component labeling,性能消耗较大.

所以首先调用iOS 9提供的文字检测API,判断输入图像中是否有文字.

有则识别文字,无则返回.

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {

    // 识别中 则返回
    if self.viewModel.isOCRRecognizing {
        return   
    }

    // 截取图片
    self.imgToRecognize = XGCameraScanWrapper.cropImageFromSampleBuffer(using: sampleBuffer, croppedSizeInScreen: (self.qRScanView?.getRetangeSize())!)

    // 调用 iOS 9 文字检测API. 若没有检测到文字 => 则返回 不跑数字识别算法
    if #available(iOS 9.0, *) {
        let ciDetector = CIDetector(ofType: CIDetectorTypeText, context: nil, options: nil)
        guard let ciImgToRecognize = self.convertUIImageToCIImage(uiImage: self.imgToRecognize!) else {
            return
        }

        let features = ciDetector?.features(in: ciImgToRecognize)

        if (features?.isEmpty)! {
            self.recognizedImgView?.isHidden = true
            return
        } else {
            self.recognizedImgView?.image = self.imgToRecognize
            self.recognizedImgView?.isHidden = false
        }
    }

    // 识别图像
    self.viewModel.isOCRRecognizing = true
    self.xgDigitalRecognizeService?.recognize(self.imgToRecognize!) { recognizedString in

        if recognizedString.utf16.count >= 11 {  // 简单通过识别结果的长度进行输出判断 实际可通过正则限制结果的输出
            DispatchQueue.main.async {
                self.viewModel.phoneNumStr = recognizedString
                self.resultLablePhoneNum?.text = "手机号: " + self.viewModel.phoneNumStr
            }
        }

        self.viewModel.isOCRRecognizing = false
    }
}

Other

手写字体的机器识别是一个很久远经典的问题.

也有一个近30年的标准训练集MNIST

可否支持手写字体的识别? 单个手写字体的识别不难,有兴趣可参考下面Tensorflow on iOS这篇文章.

难点是如何处理连笔书写的数字,此时通过 Connected-component labeling 技术进行文字的分割已经失效.

你可能感兴趣的:(SwiftOCR在手机号/数字识别App中的应用)