Objekte mit ML Kit für iOS erkennen und verfolgen

Sie können ML Kit verwenden, um Objekte in aufeinanderfolgenden Videoframes zu erkennen und zu verfolgen.

Wenn Sie ein Bild an ML Kit übergeben, werden bis zu fünf Objekte im Bild erkannt sowie die Position jedes Objekts im Bild. Bei der Erkennung von Objekten Video-Streams hat jedes Objekt eine eindeutige ID, mit der Sie das Objekt von Frame zu Frame. Optional können Sie auch das grobe Objekt aktivieren. -Klassifizierung, bei der Objekte mit allgemeinen Kategoriebeschreibungen gekennzeichnet werden.

Jetzt ausprobieren

Hinweis

  1. Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei ein:
    pod 'GoogleMLKit/ObjectDetection', '3.2.0'
    
  2. Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit dem .xcworkspace ML Kit wird ab Xcode-Version 12.4 unterstützt.

1. Objektdetektor konfigurieren

Um Objekte zu erkennen und zu verfolgen, erstellen Sie zuerst eine Instanz von ObjectDetector und geben Sie optional die gewünschten Detektoreinstellungen an von der Standardeinstellung ändern.

  1. Konfigurieren Sie die Objekterkennung für Ihren Anwendungsfall mit einem ObjectDetectorOptions-Objekt. Sie können Folgendes ändern: Einstellungen:

    Einstellungen für Objektdetektoren
    Erkennungsmodus .stream (Standard) | .singleImage

    Im Stream-Modus (Standardeinstellung) läuft die Objekterkennung mit sehr niedrigen Latenz, kann jedoch zu unvollständigen Ergebnissen (z. B. nicht spezifizierte Begrenzungsrahmen oder Kategorien) auf die ersten Aufrufe von Detektor an. Im Streammodus weist der Detektor IDs zu Objekten, mit denen Sie Objekte über Frames hinweg verfolgen können. Verwenden Sie diesen Modus, wenn Sie Objekte verfolgen möchten oder wenn die Latenz niedrig ist ist wichtig, etwa bei der Verarbeitung von Videostreams in .

    Im Einzelbildmodus gibt die Objekterkennung das Ergebnis nachdem der Begrenzungsrahmen des Objekts bestimmt wurde. Wenn Sie auch Klassifizierung gibt, wird das Ergebnis nach dem Begrenzungsrahmen zurückgegeben. Kategorie-Label sind beide verfügbar. Infolgedessen hat die Erkennung ist die Latenz potenziell höher. Im Einzelbildmodus wird das Tracking IDs sind nicht zugewiesen. Verwenden Sie diesen Modus, wenn die Latenz nicht kritisch ist und nicht mit Teilergebnissen zu tun haben.

    Mehrere Objekte erkennen und verfolgen false (Standard) | true

    Erkennung und Verfolgung von bis zu fünf Objekten oder nur den auffälliges Objekt (Standardeinstellung).

    Objekte klassifizieren false (Standard) | true

    Gibt an, ob erkannte Objekte in groben Kategorien klassifiziert werden sollen. Wenn diese Option aktiviert ist, klassifiziert die Objekterkennung Objekte in der folgenden Kategorien: Modeartikel, Lebensmittel, Haushaltswaren, Orte und Pflanzen.

    Die Objekterkennungs- und -verfolgungs-API ist für diese beiden Hauptzwecke optimiert. Cases:

    • Live-Erkennung und Verfolgung des auffälligsten Objekts in der Kamera Sucher.
    • Die Erkennung mehrerer Objekte in einem statischen Bild.

    So konfigurieren Sie die API für diese Anwendungsfälle:

Swift

// Live detection and tracking
let options = ObjectDetectorOptions()
options.shouldEnableClassification = true

// Multiple object detection in static images
let options = ObjectDetectorOptions()
options.detectorMode = .singleImage
options.shouldEnableMultipleObjects = true
options.shouldEnableClassification = true

Objective-C

// Live detection and tracking
MLKObjectDetectorOptions *options = [[MLKObjectDetectorOptions alloc] init];
options.shouldEnableClassification = YES;

// Multiple object detection in static images
MLKObjectDetectorOptions *options = [[MLKOptions alloc] init];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableMultipleObjects = YES;
options.shouldEnableClassification = YES;
  1. Rufen Sie eine Instanz von ObjectDetector ab:

Swift

let objectDetector = ObjectDetector.objectDetector()

// Or, to change the default settings:
let objectDetector = ObjectDetector.objectDetector(options: options)

Objective-C

MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetector];

// Or, to change the default settings:
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];

2. Eingabebild vorbereiten

Gehen Sie für jedes Bild oder jeden Frame des Videos folgendermaßen vor, um Objekte zu erkennen und zu verfolgen: Wenn Sie den Streammodus aktiviert haben, müssen Sie VisionImage-Objekte erstellen aus CMSampleBuffers.

Erstellen Sie ein VisionImage-Objekt mithilfe von UIImage oder einem CMSampleBuffer

Wenn du ein UIImage verwendest, gehe so vor:

  • Erstellen Sie ein VisionImage-Objekt mit der UIImage. Geben Sie die richtige .orientation an.

    Swift

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

    Objective-C

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

Wenn du ein CMSampleBuffer verwendest, gehe so vor:

  • Geben Sie die Ausrichtung der Bilddaten an, die in der CMSampleBuffer

    So ermitteln Sie die Bildausrichtung:

    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;
      }
    }
          
  • Erstellen Sie ein VisionImage-Objekt mithilfe der CMSampleBuffer-Objekt und Ausrichtung:

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

3. Bild verarbeiten

Übergib VisionImage an einen der Bildverarbeitungsprogramme des Objektdetektors . Sie können entweder die asynchrone process(image:)-Methode oder die synchrone Methode results().

So erkennen Sie Objekte asynchron:

Swift

objectDetector.process(image) { objects, error in
  guard error == nil else {
    // Error.
    return
  }
  guard !objects.isEmpty else {
    // No objects detected.
    return
  }

  // Success. Get object info here.
  // ...
}

Objective-C

[objectDetector processImage:image
                  completion:^(NSArray * _Nullable objects,
                               NSError * _Nullable error) {
                    if (error == nil) {
                      return;
                    }
                    if (objects.count == 0) {
                      // No objects detected.
                      return;
                    }

                    // Success. Get object info here.
                  }];

So erkennen Sie Objekte synchron:

Swift

var objects: [Object]
do {
  objects = try objectDetector.results(in: image)
} catch let error {
  print("Failed to detect object with error: \(error.localizedDescription).")
  return
}
guard !objects.isEmpty else {
  print("Object detector returned no results.")
  return
}

// Success. Get object info here.

Objective-C

NSError *error;
NSArray *objects = [objectDetector resultsInImage:image error:&error];
if (error == nil) {
  return;
}
if (objects.count == 0) {
  // No objects detected.
  return;
}

// Success. Get object info here.

4. Informationen zu erkannten Objekten abrufen

Wenn der Aufruf an den Bildprozessor erfolgreich ist, wird entweder eine Liste mit Objects an den Abschluss-Handler oder gibt die Liste zurück, je nachdem, unabhängig davon, ob Sie die asynchrone oder die synchrone Methode aufgerufen haben.

Jedes Object enthält die folgenden Attribute:

frame Ein CGRect, der die Position des Objekts im Bild.
trackingID Ganzzahl, die das Objekt in Bildern identifiziert, oder "nil" in Einzelbildmodus.
labels Ein Array von Labels, die das vom Detektor zurückgegebene Objekt beschreiben. Das Attribut ist leer, wenn die Detektoroption shouldEnableClassification ist auf false gesetzt.

Swift

// objects contains one item if multiple object detection wasn't enabled.
for object in objects {
  let frame = object.frame
  let trackingID = object.trackingID

  // If classification was enabled:
  let description = object.labels.enumerated().map { (index, label) in
    "Label \(index): \(label.text), \(label.confidence)"
    }.joined(separator:"\n")

}

Objective-C

// The list of detected objects contains one item if multiple
// object detection wasn't enabled.
for (MLKObject *object in objects) {
  CGRect frame = object.frame;
  NSNumber *trackingID = object.trackingID;
  for (MLKObjectLabel *label in object.labels) {
    NSString *labelString = [NSString stringWithFormat: @"%@, %f, %lu",
      label.text, label.confidence, (unsigned long)label.index];
    ...
  }
}

Nutzerfreundlichkeit und Leistung verbessern

Beachten Sie für eine optimale Nutzererfahrung in Ihrer App die folgenden Richtlinien:

  • Die erfolgreiche Objekterkennung hängt von der visuellen Komplexität des Objekts ab. In müssen Objekte mit einer geringen Anzahl visueller Merkmale einen größeren Teil des Bildes einnehmen. Sie sollten Nutzenden dabei helfen, Eingabedaten erfassen, die mit der Art von Objekten, die Sie erkennen möchten, gut funktionieren.
  • Wenn Sie bei der Klassifizierung Objekte erkennen möchten, die nicht fallen in die unterstützten Kategorien einzuordnen, spezielle Behandlungen für unbekannte Objekte.

Schauen Sie sich auch das Material Design- Sammlung Muster für Funktionen, die auf maschinellem Lernen basieren

Wenn Sie den Streamingmodus in einer Echtzeitanwendung verwenden, beachten Sie die folgenden Richtlinien zur um die besten Frame-Rates zu erzielen:

  • Verwenden Sie im Streamingmodus nicht die Mehrfachobjekterkennung, da die meisten Geräte dies angemessene Framerates zu erzielen.
  • Deaktivieren Sie die Klassifizierung, wenn Sie sie nicht benötigen.
  • Verwende zum Verarbeiten von Videoframes die synchrone results(in:) API des Detektors. Anruf diese Methode aus dem AVCaptureVideoDataOutputSampleBufferDelegate <ph type="x-smartling-placeholder"></ph> captureOutput(_, didOutput:from:)-Funktion, um synchron Ergebnisse aus dem angegebenen Video zu erhalten Frame. beibehalten von AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames als true, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer verfügbar wird, während der Detektor läuft, wird er verworfen.
  • Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken Eingabebild, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie das Bild in einem Schritt übereinanderlegen. Dadurch rendern Sie auf der Anzeigeoberfläche pro verarbeitetem Eingabeframe nur einmal. Weitere Informationen finden Sie im Abschnitt updatePreviewOverlayViewWithLastFrame. im Beispiel der ML Kit-Kurzanleitung finden Sie ein Beispiel.