您可以使用机器学习套件识别图片或视频中的文字,例如路牌的文字。此功能的主要特点包括:
文本识别 API | |
---|---|
说明 | 识别图片或视频中的拉丁字母文本。 |
SDK 名称 | GoogleMLKit/TextRecognition (version 2.2.0) |
实现 | 资源在构建时以静态方式关联到您的应用。 |
应用大小影响 | 约 20 MB |
性能 | 在大多数设备上都是实时的。 |
试试看
准备工作
- 在 Podfile 中添加以下机器学习套件 pod:
pod 'GoogleMLKit/TextRecognition','2.2.0'
- 安装或更新项目的 Pod 之后,请使用 Xcode 项目的
.xcworkspace
打开该项目。Xcode 12.4 版或更高版本支持机器学习套件。
1. 创建 TextRecognizer
实例
通过调用 +textRecognizer
创建 TextRecognizer
的实例:Swift
let textRecognizer = TextRecognizer.textRecognizer()
Objective-C
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
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 的图片尺寸要求。