Etiquetar imágenes con ML Kit en iOS

Puede utilizar ML Kit para etiquetar objetos reconocidos en una imagen, utilizando un modelo en el dispositivo o un modelo en la nube. Consulte la descripción general para conocer los beneficios de cada enfoque.

Antes de que empieces

  1. Si aún no has agregado Firebase a tu aplicación, hazlo siguiendo los pasos de la guía de introducción .
  2. Incluya las bibliotecas del kit ML en su Podfile:
    pod 'Firebase/MLVision', '6.25.0'

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

    Después de instalar o actualizar los Pods de su proyecto, asegúrese de abrir su proyecto Xcode usando su .xcworkspace .
  3. En tu aplicación, importa Firebase:
    import Firebase
    @import Firebase;
  4. Si desea utilizar el modelo basado en la nube y aún no ha habilitado las API basadas en la nube para su proyecto, hágalo ahora:

    1. Abra la página API del kit de aprendizaje automático de Firebase console.
    2. Si aún no ha actualizado su proyecto a un plan de precios de Blaze, haga clic en Actualizar para hacerlo. (Se le pedirá que actualice solo si su proyecto no está en el plan Blaze).

      Solo los proyectos de nivel Blaze pueden utilizar API basadas en la nube.

    3. Si las API basadas en la nube aún no están habilitadas, haga clic en Habilitar API basadas en la nube .

    Si desea utilizar solo el modelo del dispositivo, puede omitir este paso.

Ahora está listo para etiquetar imágenes utilizando un modelo en el dispositivo o un modelo basado en la nube.

1. Prepare la imagen de entrada

Cree un objeto VisionImage utilizando UIImage o CMSampleBufferRef .

Para usar una UIImage :

  1. Si es necesario, gire la imagen para que su propiedad imageOrientation sea .up .
  2. Cree un objeto VisionImage utilizando UIImage girado correctamente. No especifique ningún metadato de rotación; se debe utilizar el valor predeterminado, .topLeft .
    let image = VisionImage(image: uiImage)
    FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

Para utilizar CMSampleBufferRef :

  1. Cree un objeto VisionImageMetadata que especifique la orientación de los datos de la imagen contenidos en el búfer CMSampleBufferRef .

    Para obtener la orientación de la imagen:

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

    Luego, crea el objeto de metadatos:

    let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
    let metadata
    = VisionImageMetadata()
    metadata
    .orientation = imageOrientation(
        deviceOrientation
    : UIDevice.current.orientation,
        cameraPosition
    : cameraPosition
    )
    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. Cree un objeto VisionImage utilizando el objeto CMSampleBufferRef y los metadatos de rotación:
    let image = VisionImage(buffer: sampleBuffer)
    image
    .metadata = metadata
    FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
    image
    .metadata = metadata;

2. Configure y ejecute el etiquetador de imágenes.

Para etiquetar objetos en una imagen, pase el objeto VisionImage al método processImage() de VisionImageLabeler .

  1. Primero, obtenga una instancia de VisionImageLabeler .

    Si desea utilizar el etiquetador de imágenes del dispositivo:

    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)
    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];

    Si desea utilizar el etiquetador de imágenes en la nube:

    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)
    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. Luego, pasa la imagen al método processImage() :

    labeler.process(image) { labels, error in
        guard error
    == nil, let labels = labels else { return }

       
    // Task succeeded.
       
    // ...
    }
    [labeler processImage:image
               completion
    :^(NSArray<FIRVisionImageLabel *> *_Nullable labels,
                           
    NSError *_Nullable error) {
                   
    if (error != nil) { return; }

                   
    // Task succeeded.
                   
    // ...
               
    }];

3. Obtener información sobre objetos etiquetados.

Si el etiquetado de imágenes se realiza correctamente, se pasará una matriz de objetos VisionImageLabel al controlador de finalización. De cada objeto, puede obtener información sobre una característica reconocida en la imagen.

Por ejemplo:

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

Consejos para mejorar el rendimiento en tiempo real

Si desea etiquetar imágenes en una aplicación en tiempo real, siga estas pautas para lograr las mejores velocidades de fotogramas:

  • Acelera las llamadas al etiquetador de imágenes. Si hay un nuevo cuadro de video disponible mientras se ejecuta el etiquetador de imágenes, suelte el cuadro.
  • Si está utilizando la salida del etiquetador de imágenes para superponer gráficos en la imagen de entrada, primero obtenga el resultado del ML Kit, luego renderice la imagen y superpóngala en un solo paso. Al hacerlo, renderiza en la superficie de visualización solo una vez por cada cuadro de entrada. Consulte las clases previaOverlayView y FIRDetectionOverlayView en la aplicación de muestra de presentación para ver un ejemplo.

Próximos pasos