Rotular imagens com o kit de ML no iOS

Você pode usar o Kit de ML para rotular objetos reconhecidos em uma imagem, usando um modelo no dispositivo ou baseado na nuvem. Consulte a visão geral para saber mais sobre os benefícios de cada abordagem.

Antes de começar

  1. Se você ainda não adicionou o Firebase ao seu app, siga as etapas no guia de iniciação.
  2. Inclua as bibliotecas do Kit de ML no seu Podfile:
    pod 'Firebase/MLVision', '6.25.0'

    # If using the on-device API: pod 'Firebase/MLVisionLabelModel', '6.25.0'

    Depois de instalar ou atualizar os pods do projeto, abra o projeto do Xcode usando o .xcworkspace.
  3. Importe o Firebase para seu app:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Se você quiser usar o modelo baseado em nuvem e ainda não tiver ativado as APIs baseadas em nuvem para seu projeto, siga estas etapas:

    1. Abra a página APIs do Kit de ML no Console do Firebase.
    2. Se você ainda não fez o upgrade de seu projeto para um plano de preços do Blaze, clique em Upgrade para fazer isso. Você só vai receber uma mensagem para fazer upgrade se o projeto não estiver no plano Blaze.

      Apenas projetos no nível Blaze podem usar APIs baseadas na nuvem.

    3. Caso as APIs baseadas na nuvem ainda não estejam ativadas, clique em Ativar APIs baseadas na nuvem.

    Se você quiser usar apenas o modelo no dispositivo, pule esta etapa.

Agora você já pode rotular imagens usando um modelo no dispositivo ou um modelo baseado na nuvem.

1. Preparar a imagem de entrada

Crie um objeto VisionImage usando um UIImage ou um CMSampleBufferRef.

Para usar um UIImage:

  1. Se necessário, gire a imagem para que a propriedade imageOrientation seja .up.
  2. Crie um objeto VisionImage usando a UIImage com a rotação correta. Não especifique metadados de rotação: o valor padrão, .topLeft, precisa ser usado.

    Swift

    let image = VisionImage(image: uiImage)

    Objective-C

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

Para usar um CMSampleBufferRef:

  1. Crie um objeto VisionImageMetadata que especifique a orientação dos dados da imagem contidos no buffer CMSampleBufferRef.

    Para ver a orientação da imagem:

    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;
      }
    }

    Em seguida, crie o objeto de metadados:

    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. Crie um objeto VisionImage usando o objeto CMSampleBufferRef e os metadados de rotação:

    Swift

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

    Objective-C

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

2. Configurar e executar o rotulador de imagens

Para rotular objetos em uma imagem, transmita o objeto VisionImage para o método processImage() do VisionImageLabeler.

  1. Primeiro, receba uma instância de VisionImageLabeler.

    Se você quiser usar o rotulador de imagens no dispositivo:

    Swift

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

    Objective-C

    FIRVisionImageLabeler *labeler = [[FIRVision vision] onDeviceImageLabeler];
    
    // Or, to set the minimum confidence required:
    // FIRVisionOnDeviceImageLabelerOptions *options =
    //         [[FIRVisionOnDeviceImageLabelerOptions alloc] init];
    // options.confidenceThreshold = 0.7;
    // FIRVisionImageLabeler *labeler =
    //         [[FIRVision vision] onDeviceImageLabelerWithOptions:options];
    

    Se você quiser usar o rotulador de imagens na nuvem:

    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. Em seguida, transmita a imagem para o método 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. Ver informações sobre os objetos rotulados

Se a rotulagem da imagem for bem-sucedida, uma matriz de objetos VisionImageLabel será transmitida para o gerenciador de conclusão. É possível obter informações sobre um atributo reconhecido na imagem em cada objeto.

Por exemplo:

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;
}

Dicas para melhorar o desempenho em tempo real

Caso você queira rotular imagens em um aplicativo em tempo real, siga estas diretrizes para ter as melhores taxas de frames:

  • Limite as chamadas para o rotulador de imagens. Se um novo frame de vídeo estiver disponível enquanto o rotulador de imagens estiver em execução, elimine o frame.
  • Se você estiver usando a saída do rotulador de imagens para sobrepor elementos gráficos na imagem de entrada, primeiro acesse o resultado do Kit de ML e, em seguida, renderize a imagem e a sobreposição em uma única etapa. Ao fazer isso, você renderiza a superfície de exibição apenas uma vez para cada frame de entrada. Consulte as classes previewOverlayView e FIRDetectionOverlayView no app de amostra da demonstração para ver um exemplo.

Próximas etapas