您可以使用机器学习套件给图片中识别出的对象加标签。提供的 机器学习套件支持 400 多种不同标签。
试试看
- 您可以试用示例应用, 查看此 API 的用法示例。
准备工作
- 在 Podfile 中添加以下机器学习套件 Pod:
pod 'GoogleMLKit/ImageLabeling', '15.5.0'
- 安装或更新项目的 Pod 之后,使用 Xcode 项目的
.xcworkspace
。Xcode 12.4 或更高版本支持机器学习套件。
现在,您可以给图片加标签了。
1. 准备输入图片
使用 UIImage
或VisionImage
CMSampleBuffer
。
如果您使用 UIImage
,请按以下步骤操作:
- 使用
UIImage
创建一个VisionImage
对象。请务必指定正确的.orientation
。let image = VisionImage(image: UIImage)
visionImage.orientation = image.imageOrientationMLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
visionImage.orientation = image.imageOrientation;
如果您使用 CMSampleBuffer
,请按以下步骤操作:
-
指定
CMSampleBuffer
。如需获取图片方向,请执行以下操作:
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
}
}
- (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;
}
}
- 使用
VisionImage
CMSampleBuffer
对象和方向:let image = VisionImage(buffer: sampleBuffer)
image.orientation = imageOrientation(
deviceOrientation: UIDevice.current.orientation,
cameraPosition: cameraPosition)MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
image.orientation =
[self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
cameraPosition:cameraPosition];
2. 配置并运行图片标记器
如需给图片中的对象加标签,请将VisionImage
对象传递给
ImageLabeler
的 processImage()
方法。
- 首先,获取
ImageLabeler
的一个实例。
let labeler = ImageLabeler.imageLabeler()
// Or, to set the minimum confidence required:
// let options = ImageLabelerOptions()
// options.confidenceThreshold = 0.7
// let labeler = ImageLabeler.imageLabeler(options: options)
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()
方法:
labeler.process(image) { labels, error in
guard error == nil, let labels = labels else { return }
// Task succeeded.
// ...
}
[labeler processImage:image
completion:^(NSArray
3. 获取已加标签的对象的相关信息
如果图片标记成功,完成处理程序会收到
ImageLabel
对象。每个 ImageLabel
对象都代表
标签。基本模型支持 400 多个不同的标签。
您可以获取每个标签的文本说明,以及
模型和匹配的置信度分数。例如:
for label in labels {
let labelText = label.text
let confidence = label.confidence
let index = label.index
}
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 。