您可以使用机器学习套件给图片中识别出的对象加标签。机器学习套件提供的默认模型支持 400 多种不同的标签。
试试看
- 试用示例应用,查看此 API 的用法示例。
准备工作
- 在您的 Podfile 中添加以下机器学习套件 Pod:
pod 'GoogleMLKit/ImageLabeling', '3.2.0'
- 安装或更新项目的 Pod 之后,请使用 Xcode 项目的
.xcworkspace
来打开项目。Xcode 12.4 版或更高版本支持机器学习套件。
现在,您可以给图片加标签了。
1. 准备输入图片
使用 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];
2. 配置并运行图片标记器
如需给图片中的对象加标签,请将VisionImage
对象传递给 ImageLabeler
的 processImage()
方法。
- 首先,获取
ImageLabeler
的一个实例。
Swift
let labeler = ImageLabeler.imageLabeler() // Or, to set the minimum confidence required: // let options = ImageLabelerOptions() // options.confidenceThreshold = 0.7 // let labeler = ImageLabeler.imageLabeler(options: options)
Objective-C
MLKImageLabeler *labeler = [MLKImageLabeler imageLabeler]; // Or, to set the minimum confidence required: // MLKImageLabelerOptions *options = // [[MLKImageLabelerOptions alloc] init]; // options.confidenceThreshold = 0.7; // MLKImageLabeler *labeler = // [MLKImageLabeler imageLabelerWithOptions:options];
- 然后,将图片传递给
processImage()
方法:
Swift
labeler.process(image) { labels, error in guard error == nil, let labels = labels else { return } // Task succeeded. // ... }
Objective-C
[labeler processImage:image completion:^(NSArray*_Nullable labels, NSError *_Nullable error) { if (error != nil) { return; } // Task succeeded. // ... }];
3. 获取有关已加标签的对象的信息
如果给图片加标签成功,则完成处理程序会收到一组 ImageLabel
对象。每个 ImageLabel
对象代表在图片中加了标签的某个事物。基本模型支持 400 多种不同的标签。您可以获取每个标签的文本说明、模型支持的所有标签的索引以及匹配的置信度分数。例如:
Swift
for label in labels { let labelText = label.text let confidence = label.confidence let index = label.index }
Objective-C
for (MLKImageLabel *label in labels) { NSString *labelText = label.text; float confidence = label.confidence; NSInteger index = label.index; }
提高实时性能的相关提示
如果要在实时应用中给图片加标签,请遵循以下准则以实现最佳帧速率:
- 如需处理视频帧,请使用图片标记器的
results(in:)
同步 API。从AVCaptureVideoDataOutputSampleBufferDelegate
的captureOutput(_, didOutput:from:)
函数调用此方法,以同步获取给定视频帧的结果。将AVCaptureVideoDataOutput
的alwaysDiscardsLateVideoFrames
保持为true
,以限制对图片标记器的调用。如果在图片标记器运行时有新的视频帧可用,该帧将被丢弃。 - 如果您使用图片标记器的输出将图形叠加在输入图片上,请先从机器学习套件获取结果,然后在一个步骤中完成图片的呈现和叠加。采用这一方法,每个已处理的输入帧只需在显示表面渲染一次。如需查看示例,请参阅机器学习套件快速入门示例中的 updatePreviewOverlayViewWithLastFrame。