您可以使用机器学习套件识别图片或视频中的文本,例如街道标志上的文本。此功能的主要特性包括:
Text Recognition v2 API | |
---|---|
说明 | 识别图片或视频中的文字,支持拉丁语、汉语、天城文、日语和韩语以及多种语言。 |
SDK 名称 | GoogleMLKit/TextRecognition |
实现 | 资源在构建时会静态链接到您的应用 |
对应用大小的影响 | 每个脚本 SDK 约 38 MB |
性能 | 对于拉丁脚本 SDK,在大多数设备上实时运行;对于其他设备,则速度较慢。 |
试试看
准备工作
- 在 Podfile 中添加以下机器学习套件 Pod:
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '15.5.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '15.5.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '15.5.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '15.5.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '15.5.0'
- 安装或更新项目的 Pod 之后,使用 Xcode 项目的
.xcworkspace
。Xcode 12.4 或更高版本支持机器学习套件。
1. 创建 TextRecognizer
实例
通过调用 +textRecognizer(options:)
创建 TextRecognizer
的实例,并传递与您在上面声明为依赖项的 SDK 相关的选项:
Swift
// When using Latin script recognition SDK let latinOptions = TextRecognizerOptions() let latinTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Chinese script recognition SDK let chineseOptions = ChineseTextRecognizerOptions() let chineseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Devanagari script recognition SDK let devanagariOptions = DevanagariTextRecognizerOptions() let devanagariTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Japanese script recognition SDK let japaneseOptions = JapaneseTextRecognizerOptions() let japaneseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Korean script recognition SDK let koreanOptions = KoreanTextRecognizerOptions() let koreanTextRecognizer = TextRecognizer.textRecognizer(options:options)
Objective-C
// When using Latin script recognition SDK MLKTextRecognizerOptions *latinOptions = [[MLKTextRecognizerOptions alloc] init]; MLKTextRecognizer *latinTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Chinese script recognition SDK MLKChineseTextRecognizerOptions *chineseOptions = [[MLKChineseTextRecognizerOptions alloc] init]; MLKTextRecognizer *chineseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Devanagari script recognition SDK MLKDevanagariTextRecognizerOptions *devanagariOptions = [[MLKDevanagariTextRecognizerOptions alloc] init]; MLKTextRecognizer *devanagariTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Japanese script recognition SDK MLKJapaneseTextRecognizerOptions *japaneseOptions = [[MLKJapaneseTextRecognizerOptions alloc] init]; MLKTextRecognizer *japaneseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Korean script recognition SDK MLKKoreanTextRecognizerOptions *koreanOptions = [[MLKKoreanTextRecognizerOptions alloc] init]; MLKTextRecognizer *koreanTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options];
2. 准备输入图片
将图片作为UIImage
或 CMSampleBufferRef
传递给 TextRecognizer
的 process(_:completion:)
方法:
使用 UIImage
或 CMSampleBuffer
创建一个 VisionImage
对象。
如果您使用 UIImage
,请按以下步骤操作:
- 使用
UIImage
创建一个VisionImage
对象。请务必指定正确的.orientation
。Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
如果您使用的是 CMSampleBuffer
,请按以下步骤操作:
-
指定
CMSampleBuffer
中所含图片数据的方向。如需获取图片方向,请执行以下操作:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- 使用
CMSampleBuffer
对象和方向创建一个VisionImage
对象:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. 处理图片
然后,将图片传递给 process(_:completion:)
方法:
Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // Error handling return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(MLKText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // Error handling return; } // Recognized text }];
4. 从识别出的文本块中提取文本
如果文本识别操作成功,它将返回一个
Text
对象。Text
对象包含完整文本
以及零个或多个 TextBlock
对象的操作。
每个 TextBlock
表示一个矩形文本块,其中包含零个或零个以上的 TextLine
对象。每个 TextLine
对象包含零个或零个以上的 TextElement
对象,这些对象表示字词和类似字词的实体,例如日期和数字。
对于每个 TextBlock
、TextLine
和
TextElement
对象,您可以获取在
和区域的边界坐标。
例如:
Swift
let resultText = result.text for block in result.blocks { let blockText = block.text let blockLanguages = block.recognizedLanguages let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for line in block.lines { let lineText = line.text let lineLanguages = line.recognizedLanguages let lineCornerPoints = line.cornerPoints let lineFrame = line.frame for element in line.elements { let elementText = element.text let elementCornerPoints = element.cornerPoints let elementFrame = element.frame } } }
Objective-C
NSString *resultText = result.text; for (MLKTextBlock *block in result.blocks) { NSString *blockText = block.text; NSArray<MLKTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages; NSArray<NSValue *> *blockCornerPoints = block.cornerPoints; CGRect blockFrame = block.frame; for (MLKTextLine *line in block.lines) { NSString *lineText = line.text; NSArray<MLKTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages; NSArray<NSValue *> *lineCornerPoints = line.cornerPoints; CGRect lineFrame = line.frame; for (MLKTextElement *element in line.elements) { NSString *elementText = element.text; NSArray<NSValue *> *elementCornerPoints = element.cornerPoints; CGRect elementFrame = element.frame; } } }
输入图片准则
-
为了让机器学习套件准确识别文本,输入图片必须包含 用足够的像素数据表示的文本。理想情况下 每个字符至少应为 16x16 像素。字符像素大于 24x24 通常不会增加准确性。
例如,640x480 像素的图片可能非常适合用于扫描占据图片整个宽度的名片。如需扫描打印在信纸大小纸张上的文档,可能需要 720x1280 像素的图片。
-
图片聚焦不佳会影响文本识别的准确性。如果您无法获得满意的结果,请尝试让用户重新采集图片。
-
如果您是在实时应用中识别文本,则应考虑输入图片的整体尺寸。较小 可以更快地处理图像。为了减少延迟时间,请确保文本在图片中占据尽可能大的画面,并以较低的分辨率捕获图片(但请牢记上述准确性要求)。如需了解详情,请参阅 改善效果的提示。
提升效果的提示
- 如需处理视频帧,请使用检测器的
results(in:)
同步 API。从AVCaptureVideoDataOutputSampleBufferDelegate
的captureOutput(_, didOutput:from:)
函数调用此方法,以同步从给定视频帧获取结果。将AVCaptureVideoDataOutput
的alwaysDiscardsLateVideoFrames
保持为true
,以限制对检测器的调用次数。如果新的 视频帧在检测器运行时可用,则会丢失。 - 如果您使用检测器的输出在图像上叠加显示 输入图片,首先从机器学习套件获取结果, 和叠加层。采用这一方法,每个处理过的输入帧只需在显示表面呈现一次。请参阅 updatePreviewOverlayViewWithLastFrame 。
- 建议以较低的分辨率捕获图片。但是,请注意此 API 的图片尺寸要求。
- 为避免性能可能出现下降,请勿同时运行具有不同脚本选项的多个
TextRecognizer
实例。