Etichetta le immagini con ML Kit su iOS

Puoi utilizzare ML Kit per etichettare gli oggetti riconosciuti in un'immagine. Il modello predefinito fornito con ML Kit supporta oltre 400 etichette diverse.

Prova

Prima di iniziare

  1. Includi i seguenti pod ML Kit nel podfile:
    pod 'GoogleMLKit/ImageLabeling', '3.2.0'
    
  2. Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando il relativo .xcworkspace. ML Kit è supportato in Xcode versione 12.4 o successiva.

Ora è tutto pronto per etichettare le immagini.

1. Prepara l'immagine di input

Crea un oggetto VisionImage utilizzando UIImage o CMSampleBuffer.

Se usi un UIImage, segui questi passaggi:

  • Crea un oggetto VisionImage con il UIImage. Assicurati di specificare il valore .orientation corretto.

    Swift

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

    Objective-C

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

Se usi un CMSampleBuffer, segui questi passaggi:

  • Specifica l'orientamento dei dati immagine contenuti in CMSampleBuffer.

    Per ottenere l'orientamento dell'immagine:

    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 oggetto VisionImage utilizzando l'oggetto CMSampleBuffer e l'orientamento:

    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 ed esegui l'etichettatore di immagini

Per etichettare gli oggetti in un'immagine, passa l'oggetto VisionImage al metodo processImage() di ImageLabeler.

  1. Innanzitutto, recupera un'istanza di 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. Quindi, passa l'immagine al metodo 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. Recuperare informazioni sugli oggetti etichettati

Se l'etichettatura delle immagini ha esito positivo, il gestore di completamento riceve un array di oggetti ImageLabel. Ogni oggetto ImageLabel rappresenta un elemento etichettato nell'immagine. Il modello di base supporta oltre 400 etichette diverse. Puoi ottenere la descrizione testuale di ogni etichetta, l'indice tra tutte le etichette supportate dal modello e il punteggio di affidabilità della corrispondenza. Ad esempio:

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

Suggerimenti per migliorare il rendimento in tempo reale

Se vuoi etichettare le immagini in un'applicazione in tempo reale, segui queste linee guida per ottenere le frequenze fotogrammi migliori:

  • Per elaborare i fotogrammi dei video, utilizza l'API sincrona results(in:) dell'etichettatore di immagini. Richiama questo metodo dalla funzione captureOutput(_, didOutput:from:) di AVCaptureVideoDataOutputSampleBufferDelegate per ottenere in modo sincrono i risultati dal frame video specificato. Mantieni alwaysDiscardsLateVideoFrames di AVCaptureVideoDataOutput come true per limitare le chiamate all'etichettatore di immagini. Se un nuovo frame video diventa disponibile mentre l'etichettatore di immagini è in esecuzione, questo verrà eliminato.
  • Se utilizzi l'output dell'etichettatore di immagini per sovrapporre gli elementi grafici all'immagine di input, recupera prima il risultato da ML Kit, quindi esegui il rendering dell'immagine e dell'overlay in un solo passaggio. In questo modo, esegui il rendering sulla piattaforma di visualizzazione solo una volta per ogni frame di input elaborato. Per un esempio, vedi updatePreviewOverlayViewWithLastFrame nell'esempio della guida rapida di ML Kit.