Etiqueta imágenes con ML Kit en iOS

Puedes usar ML Kit para etiquetar objetos reconocidos en una imagen. El modelo predeterminado que se proporciona con ML Kit admite más de 400 etiquetas diferentes.

Probar

Antes de comenzar

  1. Incluye los siguientes pods del ML Kit en tu Podfile:
    pod 'GoogleMLKit/ImageLabeling', '3.2.0'
    
  2. Después de instalar o actualizar los Pods de tu proyecto, abre el proyecto de Xcode a través de su .xcworkspace El Kit de AA es compatible con Xcode 12.4 o versiones posteriores.

Ahora está todo listo para etiquetar imágenes.

1. Prepara la imagen de entrada

Crea un objeto VisionImage con un objeto UIImage o CMSampleBuffer

Si usas un UIImage, sigue estos pasos:

  • Crea un objeto VisionImage con UIImage. Asegúrate de especificar el .orientation correcto.

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

Si usas un CMSampleBuffer, sigue estos pasos:

  • Especificar la orientación de los datos de imagen que se incluyen en la CMSampleBuffer

    Para obtener la orientación de la imagen, haz lo siguiente:

    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;
      }
    }
          
  • Crea un objeto VisionImage con el elemento Objeto CMSampleBuffer y orientación:

    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. Configura y ejecuta el etiquetador de imágenes

Para etiquetar objetos de una imagen, pasa el objeto VisionImage a la Método processImage() de ImageLabeler

  1. Primero, obtén una instancia de 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];
  1. Por último, pasa la imagen al 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 *_Nullable labels,
            NSError *_Nullable error) {
   if (error != nil) { return; }

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

3. Obtén información sobre los objetos etiquetados

Si el etiquetado de imágenes se realiza correctamente, el controlador de finalización recibe un array de ImageLabel. Cada objeto ImageLabel representa un elemento que se etiquetada en la imagen. El modelo base admite más de 400 etiquetas diferentes. Puedes obtener la descripción de texto de cada etiqueta, el índice entre todas las etiquetas compatibles con el modelo y la puntuación de confianza de la coincidencia. Por ejemplo:

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

Sugerencias para mejorar el rendimiento en tiempo real

Si quieres etiquetar imágenes en una aplicación en tiempo real, sigue estos pasos: pautas para lograr la mejor velocidad de fotogramas:

  • Para procesar fotogramas de video, usa la API síncrona results(in:) del etiquetador de imágenes. Llamada este método desde el De AVCaptureVideoDataOutputSampleBufferDelegate La función captureOutput(_, didOutput:from:) para obtener resultados de un video determinado de forma síncrona marco. Mantener de AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames como true para limitar las llamadas al etiquetador de imágenes Si un nuevo cliente El fotograma estará disponible mientras se esté ejecutando el etiquetador de imágenes, el cual se descartará.
  • Si usas la salida del etiquetador de imágenes para superponer gráficos la imagen de entrada, primero obtén el resultado del Kit de AA y, luego, renderiza la imagen y superponerla en un solo paso. De esta manera, renderizas en la superficie de visualización. solo una vez por cada trama de entrada procesada. Consulta updatePreviewOverlayViewWithLastFrame. en la muestra de inicio rápido del Kit de AA para ver un ejemplo.