您可以使用机器学习套件识别图片或视频中的文本,例如路牌的文字。此功能的主要特点包括:
文本识别 v2 API | |
---|---|
说明 | 识别图片或视频中的文本,支持拉丁语、中文、梵文、日语和韩语文字以及众多语言。 |
SDK 名称 | GoogleMLKit/TextRecognition |
实现 | 在构建时将资源静态关联到您的应用 |
应用大小影响 | 每个脚本 SDK 约 38 MB |
性能 | 对于拉丁脚本 SDK,在大多数设备上实时运行;对于其他设备,则速度较慢。 |
试试看
准备工作
- 在 Podfile 中添加以下机器学习套件 Pod:
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '3.2.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '3.2.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '3.2.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '3.2.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '3.2.0'
- 安装或更新项目的 Pod 之后,请使用 Xcode 项目的
.xcworkspace
来打开项目。Xcode 12.4 或更高版本支持机器学习套件。
1. 创建 TextRecognizer
实例
通过调用 +textRecognizer(options:)
并传递与您声明为上述依赖项的 SDK 相关的选项,创建 TextRecognizer
的实例:
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
实例。