本系列的前几篇文件,详细了介绍了 Vision 框架中关于静态图片区域识别的内容。本篇文章,我们将着重介绍静态图片中物体的识别与分类。物体识别和分类也是 Machine Learning 领域重要的应用。通过大量的图片数据进行训练后,模型可以轻易的分析出图片的属性以及图片中物体的属性。
1 - 文字识别
文字识别是应用非常广泛的一种图片识别技术。在 Vision 框架中,使用 VNRecognizeTextRequest 来进行文字识别,并且其支持多种语言,且有不错的识别精度。VNRecognizeTextRequest 的创建示例如下:
private lazy var recognizeTextRequest: VNRecognizeTextRequest = {
let textDetectionRequest = VNRecognizeTextRequest { request, error in
DispatchQueue.main.async {
self.drawTask(request: request as! VNRecognizeTextRequest)
}
}
// 设置语言
textDetectionRequest.recognitionLanguages = ["zh-Hans"]
// 设置识别级别 accurate为最精准 fast为最快速
textDetectionRequest.recognitionLevel = .accurate
// 设置是否使用语言矫正
textDetectionRequest.usesLanguageCorrection = true
// 获取所支持的语言
let set = try? textDetectionRequest.supportedRecognitionLanguages()
print(set)
return textDetectionRequest
}()
复制代码
可以通过对 VNRecognizeTextRequest 实例进行配置来调整识别精度,识别的语言,是否进行矫正的选项,VNRecognizeTextRequest 类的定义如下:
open class VNRecognizeTextRequest : VNImageBasedRequest, VNRequestProgressProviding {
// 所支持的语言列表
open class func supportedRecognitionLanguages(for recognitionLevel: VNRequestTextRecognitionLevel, revision requestRevision: Int) throws -> [String]
open func supportedRecognitionLanguages() throws -> [String]
// 识别过程中所使用的语言
open var recognitionLanguages: [String]
// 自定义的词汇,在识别单词时,自定义的词汇优先级会高于默认词典
open var customWords: [String]
// 识别等级,精度优先会更加消耗性能
// accurate: 精度优先 fast: 速度优先
open var recognitionLevel: VNRequestTextRecognitionLevel
// 设置是否使用自动矫正,自动矫正会更加消耗性能
open var usesLanguageCorrection: Bool
// 设置是否自动识别语言类型,当不确定输入的语种时,可以设置其自动识别,会更消耗性能
open var automaticallyDetectsLanguage: Bool
// 设置可识别文本的最小高度(为相对原图的比例值)
open var minimumTextHeight: Float
// 结果数组
open var results: [VNRecognizedTextObservation]? { get }
}
复制代码
VNRecognizeTextRequest 的识别结果为 VNRecognizedTextObservation 类,此类也是继承自 VNRectangleObservation 的,因此我们也同时可以获取到所识别的文本所在原图的位置。VNRecognizedTextObservation 类的定义如下:
open class VNRecognizedTextObservation : VNRectangleObservation {
// 获取候选结果
open func topCandidates(_ maxCandidateCount: Int) -> [VNRecognizedText]
}
复制代码
topCandidate 会返回一组候选结果,其参数设置最多返回的候选结果个数,需要注意此参数所支持的最大值为 10。候选结果是指对于同一段文字,可能会识别出多个相似的结果,最终识别的文本结果 VNRecognizedText 类的定义如下:
open class VNRecognizedText : NSObject, NSCopying, NSSecureCoding, VNRequestRevisionProviding {
// 识别出的文本字符串
open var string: String { get }
// 本次识别结果的可信度(0-1之间)
open var confidence: VNConfidence { get }
}
复制代码
对于 confidence 可信度属性来说,越接近 1,可信度越高。
下图演示了照片中文本的识别效果:
可以看到,Vision 对于中文印刷体的识别能力还是比较准确的。
目前,所支持识别的语种列举如下:
en-US:美式英语
fr-FR:法语
it-IT:意大利语
de-DE:德语
es-ES:西班牙语
pt-BR:葡萄牙语
zh-Hans:简体中文
zh-Hant:繁体中文
yue-Hans:粤语简体
yue-Hant:粤语繁体
ko-KR:韩语
ja-JP:日语
ru-RU:俄语
uk-UA:乌克兰语
复制代码
2 - 动物识别
虽说是动物识别,但其实目前的 API 仅仅支持猫和狗的识别。使用 VNRecognizeAnimalsRequest 类来创建动物识别请求:
open class VNRecognizeAnimalsRequest : VNImageBasedRequest {
// 获取所支持识别的动物种类
open class func knownAnimalIdentifiers(forRevision requestRevision: Int) throws -> [VNAnimalIdentifier]
open func supportedIdentifiers() throws -> [VNAnimalIdentifier]
// 结果列表
open var results: [VNRecognizedObjectObservation]? { get }
}
复制代码
识别的结果 VNRecognizedObjectObservation 类也是继承自 VNDetectedObjectObservation,其会包装所识别的动物所在图片中的区域,且 VNRecognizedObjectObservation 类中会封装一组 VNClassificationObservation 对象,如下:
open class VNRecognizedObjectObservation : VNDetectedObjectObservation {
// 识别的动物标签
open var labels: [VNClassificationObservation] { get }
}
复制代码
VNClassificationObservatio 类即表示识别出的物体具体的标签,定义如下:
open class VNClassificationObservation : VNObservation {
// 标签字符串
open var identifier: String { get }
}
复制代码
对于 VNRecognizeAnimalsRequest 请求来说,此标签的值可能为 Cat 或 Dog。识别效果如下图:
3 - 图片物体分类
图片物体分类是指对静态图片继续分析,将其中可能存在的物体分析出来。使用 VNClassifyImageRequest 创建图片物体分析请求。此类非常简单,没有太多需要配置的,定义如下:
open class VNClassifyImageRequest : VNImageBasedRequest {
// 获取支持识别的物体
open class func knownClassifications(forRevision requestRevision: Int) throws -> [VNClassificationObservation]
open func supportedIdentifiers() throws -> [String]
// 结果数组
open var results: [VNClassificationObservation]? { get }
}
复制代码
VNClassifyImageRequest 所支持识别的物体种类非常多,有千余种,这里就不再列举。其识别后的结果也是 VNClassificationObservation 类,其内部的 identifier 表示所识别出的物体的标签。
需要注意,对于略微复杂的图片来说,识别的结果可能非常多,我们需要根据需求来设置一个可信度的阈值,只有达到此可信度的才被采用,例如:
private func drawTask(request: VNClassifyImageRequest) {
boxViews.forEach { v in
v.removeFromSuperview()
}
for result in request.results ?? [] where result.confidence > 0.8 {
// 解析出文本
textView.text = textView.text.appending(result.identifier + "\n")
}
}
复制代码
识别效果如下图所示:
可以看到,我们选择了大于 0.8 可信度的结果,所识别出的关键字有:建筑,加工木材,动物,哺乳动物,犬类,狗,博美。(不知为何对猫的识别度很差)
本中所涉及到的代码,都可以在如下 Demo 中找到:
https://github.com/ZYHshao/MachineLearnDemo
到此,我们已经将静态图片的分析做了详尽的介绍,相信很多 AI 能力都是开发中会使用到的。本系列后面文章,将介绍对象追踪的相关 API 的用法。
评论