在 Apple 平台上使用 Firebase ML 为图片加标签

您可以使用 Firebase ML 给图片中识别出的对象加标签。如需了解此 API 的功能,请参阅概览

准备工作

    如果您尚未将 Firebase 添加到自己的应用中,请按照入门指南中的步骤进行添加。

    使用 Swift Package Manager 安装和管理 Firebase 依赖项。

    1. 在 Xcode 中打开您的应用项目,依次点击 File(文件)> Add Packages(添加软件包)
    2. 出现提示时,添加 Firebase Apple 平台 SDK 代码库:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. 选择 Firebase ML 库。
    5. 完成之后,Xcode 将会自动开始在后台解析和下载您的依赖项。

    接下来,执行一些应用内设置:

    1. 在您的应用中导入 Firebase:

      Swift

      import FirebaseMLModelDownloader

      Objective-C

      @import FirebaseMLModelDownloader;
  1. 如果您尚未为项目启用基于 Cloud 的 API,请立即完成以下操作:

    1. 打开 Firebase 控制台的 Firebase ML API 页面
    2. 如果您尚未将项目升级到 Blaze 定价方案,请点击升级以执行此操作。(只有在您的项目未采用 Blaze 方案时,系统才会提示您进行升级。)

      只有 Blaze 级项目才能使用基于 Cloud 的 API。

    3. 如果尚未启用基于 Cloud 的 API,请点击启用基于 Cloud 的 API

现在,您可以给图片加标签了。

1. 准备输入图片

使用 UIImageCMSampleBufferRef 创建一个 VisionImage 对象。

如需使用 UIImage,请按以下步骤操作:

  1. 在必要时旋转图片,以使其 imageOrientation 属性为 .up
  2. 使用方向正确的 UIImage 创建一个 VisionImage 对象。不要指定任何旋转方式元数据,必须使用默认值 .topLeft

    Swift

    let image = VisionImage(image: uiImage)

    Objective-C

    FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

如需使用 CMSampleBufferRef,请按以下步骤操作:

  1. 创建一个 VisionImageMetadata 对象,用其指定 CMSampleBufferRef 缓冲区中所含图片数据的方向。

    如需获取图片方向,请运行以下代码:

    Swift

    func imageOrientation(
        deviceOrientation: UIDeviceOrientation,
        cameraPosition: AVCaptureDevice.Position
        ) -> VisionDetectorImageOrientation {
        switch deviceOrientation {
        case .portrait:
            return cameraPosition == .front ? .leftTop : .rightTop
        case .landscapeLeft:
            return cameraPosition == .front ? .bottomLeft : .topLeft
        case .portraitUpsideDown:
            return cameraPosition == .front ? .rightBottom : .leftBottom
        case .landscapeRight:
            return cameraPosition == .front ? .topRight : .bottomRight
        case .faceDown, .faceUp, .unknown:
            return .leftTop
        }
    }

    Objective-C

    - (FIRVisionDetectorImageOrientation)
        imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                               cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationLeftTop;
          } else {
            return FIRVisionDetectorImageOrientationRightTop;
          }
        case UIDeviceOrientationLandscapeLeft:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationBottomLeft;
          } else {
            return FIRVisionDetectorImageOrientationTopLeft;
          }
        case UIDeviceOrientationPortraitUpsideDown:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationRightBottom;
          } else {
            return FIRVisionDetectorImageOrientationLeftBottom;
          }
        case UIDeviceOrientationLandscapeRight:
          if (cameraPosition == AVCaptureDevicePositionFront) {
            return FIRVisionDetectorImageOrientationTopRight;
          } else {
            return FIRVisionDetectorImageOrientationBottomRight;
          }
        default:
          return FIRVisionDetectorImageOrientationTopLeft;
      }
    }

    然后,创建元数据对象:

    Swift

    let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
    let metadata = VisionImageMetadata()
    metadata.orientation = imageOrientation(
        deviceOrientation: UIDevice.current.orientation,
        cameraPosition: cameraPosition
    )

    Objective-C

    FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
    AVCaptureDevicePosition cameraPosition =
        AVCaptureDevicePositionBack;  // Set to the capture device you used.
    metadata.orientation =
        [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                     cameraPosition:cameraPosition];
  2. 使用 CMSampleBufferRef 对象和旋转方式元数据创建一个 VisionImage 对象:

    Swift

    let image = VisionImage(buffer: sampleBuffer)
    image.metadata = metadata

    Objective-C

    FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
    image.metadata = metadata;

2. 配置并运行图片标记器

如需给图片中的对象加标签,请将 VisionImage 对象传递给 VisionImageLabelerprocessImage() 方法。

  1. 首先,获取 VisionImageLabeler 的一个实例:

    Swift

    let labeler = Vision.vision().cloudImageLabeler()
    
    // Or, to set the minimum confidence required:
    // let options = VisionCloudImageLabelerOptions()
    // options.confidenceThreshold = 0.7
    // let labeler = Vision.vision().cloudImageLabeler(options: options)
    

    Objective-C

    FIRVisionImageLabeler *labeler = [[FIRVision vision] cloudImageLabeler];
    
    // Or, to set the minimum confidence required:
    // FIRVisionCloudImageLabelerOptions *options =
    //         [[FIRVisionCloudImageLabelerOptions alloc] init];
    // options.confidenceThreshold = 0.7;
    // FIRVisionImageLabeler *labeler =
    //         [[FIRVision vision] cloudImageLabelerWithOptions:options];
    
  2. 然后,将图片传递给 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<FIRVisionImageLabel *> *_Nullable labels,
                            NSError *_Nullable error) {
                   if (error != nil) { return; }
    
                   // Task succeeded.
                   // ...
               }];
    

3. 获取已加标签的对象的相关信息

如果图片标记成功,系统会向完成处理程序传递一组 VisionImageLabel 对象。您可以从各个对象获取在该图片中识别出的特征的相关信息。

例如:

Swift

for label in labels {
    let labelText = label.text
    let entityId = label.entityID
    let confidence = label.confidence
}

Objective-C

for (FIRVisionImageLabel *label in labels) {
   NSString *labelText = label.text;
   NSString *entityId = label.entityID;
   NSNumber *confidence = label.confidence;
}

后续步骤