Leitfaden zur Bildklassifizierung für iOS

Mit der Aufgabe „Bildklassifikator“ können Sie Bilder klassifizieren. Mit dieser Aufgabe können Sie ermitteln, was ein Bild aus einer Reihe von Kategorien darstellt, die zum Zeitpunkt des Trainings definiert wurden. In dieser Anleitung erfahren Sie, wie Sie den Bildklassifikator in iOS-Apps verwenden. Das in dieser Anleitung beschriebene Codebeispiel ist auf GitHub verfügbar.

In dieser Webdemo können Sie diese Aufgabe in Aktion sehen. Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Der Beispielcode von MediaPipe Tasks ist eine grundlegende Implementierung einer Bildklassifikator-App für iOS. In diesem Beispiel wird die Kamera eines physischen iOS-Geräts verwendet, um Objekte kontinuierlich zu klassifizieren. Es können auch Bilder und Videos aus der Gerätegalerie verwendet werden, um Objekte statisch zu klassifizieren.

Sie können die App als Ausgangspunkt für Ihre eigene iOS-App verwenden oder darauf verweisen, wenn Sie eine vorhandene App ändern. Der Beispielcode für den Bildklassifikator wird auf GitHub gehostet.

Code herunterladen

Die folgende Anleitung zeigt, wie Sie mit dem git-Befehlszeilentool eine lokale Kopie des Beispielcodes erstellen.

So laden Sie den Beispielcode herunter:

  1. Klonen Sie das Git-Repository mit dem folgenden Befehl:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Optional können Sie die Git-Instanz für die Verwendung der dünnbesetzten Bezahlung konfigurieren, damit Sie nur die Dateien für die Beispielanwendung „Bildklassifikator“ haben:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_classification/ios/
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie die MediaPipe-Aufgabenbibliothek installieren, das Projekt mit Xcode öffnen und die App ausführen. Eine Anleitung finden Sie im Einrichtungsleitfaden für iOS.

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigsten Code für die Beispielanwendung „Bildklassifikator“:

  • ImageClassifierService.swift: Initialisiert den Bildklassifikator, übernimmt die Modellauswahl und führt eine Inferenz für die Eingabedaten aus.
  • CameraViewController.swift: Implementiert die Benutzeroberfläche für den Live-Kamerafeed-Eingabemodus und visualisiert die Ergebnisse.
  • MediaLibraryViewController.swift Implementiert die Benutzeroberfläche für den Eingabemodus für Standbilder und Videodateien und visualisiert die Ergebnisse.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und Codeprojekte für die Verwendung des Bildklassifikators beschrieben. Allgemeine Informationen zur Einrichtung der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für iOS.

Abhängigkeiten

Der Bildklassifikator verwendet die MediaPipeTasksVision-Bibliothek, die mit CocoaPods installiert werden muss. Die Bibliothek ist sowohl mit Swift- als auch mit Objective-C-Apps kompatibel und erfordert keine zusätzliche sprachspezifische Einrichtung.

Eine Anleitung zum Installieren von CocoaPods unter macOS finden Sie in der CocoaPods-Installationsanleitung. Eine Anleitung zum Erstellen eines Podfile mit den erforderlichen Pods für Ihre Anwendung finden Sie unter CocoaPods verwenden.

Fügen Sie den MediaPipeTasksVision-Pod mit dem folgenden Code in Podfile ein:

target 'MyImageClassifierApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Wenn deine App Einheitentestziele enthält, findest du im Einrichtungsleitfaden für iOS weitere Informationen zum Einrichten von Podfile.

Modell

Für die Aufgabe „MediaPipe Image Classifier“ ist ein trainiertes Modell erforderlich, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu den verfügbaren trainierten Modellen für den Bildklassifikator finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Wählen Sie ein Modell aus, laden Sie es herunter und fügen Sie es mit Xcode Ihrem Projektverzeichnis hinzu. Eine Anleitung zum Hinzufügen von Dateien zu Ihrem Xcode-Projekt finden Sie unter Dateien und Ordner im Xcode-Projekt verwalten.

Verwenden Sie das Attribut BaseOptions.modelAssetPath, um den Pfad zum Modell in Ihrem App Bundle anzugeben. Ein Codebeispiel finden Sie im nächsten Abschnitt.

Aufgabe erstellen

Sie können die Bildklassifikatoraufgabe erstellen, indem Sie einen seiner Initialisierer aufrufen. Der ImageClassifier(options:)-Initialisierer legt Werte für Konfigurationsoptionen wie den Ausführungsmodus, die Sprache der Anzeigenamen, die maximale Anzahl von Ergebnissen, den Konfidenzgrenzwert sowie die Zulassungsliste und Sperrliste für Kategorien fest.

Wenn Sie keinen Bildklassifikator benötigen, der mit benutzerdefinierten Konfigurationsoptionen initialisiert wurde, können Sie mit dem ImageClassifier(modelPath:)-Initialisierer einen Bildklassifikator mit den Standardoptionen erstellen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsübersicht.

Die Aufgabe „Bildklassifikator“ unterstützt drei Eingabedatentypen: Standbilder, Videodateien und Live-Videostreams. Standardmäßig initialisiert ImageClassifier(modelPath:) eine Aufgabe für Standbilder. Wenn Sie möchten, dass Ihre Aufgabe initialisiert wird, um Videodateien oder Live-Videostreams zu verarbeiten, verwenden Sie ImageClassifier(options:), um den Video- oder Livestream-Ausführungsmodus anzugeben. Für den Livestream-Modus ist außerdem die zusätzliche imageClassifierLiveStreamDelegate-Konfigurationsoption erforderlich. Damit kann der Bildklassifikator die Ergebnisse der Bildklassifizierung asynchron an den Bevollmächtigten senden.

Wählen Sie den Tab für Ihren Ausführungsmodus aus, um zu sehen, wie Sie die Aufgabe erstellen und eine Inferenz ausführen.

Swift

Bild

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ImageClassifierOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.maxResults = 5

let imageClassifier = try ImageClassifier(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = ImageClassifierOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.maxResults = 5

let imageClassifier = try ImageClassifier(options: options)
    

Livestream

import MediaPipeTasksVision

// Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and
// implements the method that the image classifier calls once it
// finishes performing classification on each input frame.
class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate {

   func imageClassifier(
    _ imageClassifier: ImageClassifier,
    didFinishClassification result: ImageClassifierResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the image classifier result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = ImageClassifierOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.maxResults = 5

// Assign an object of the class to the `imageClassifierLiveStreamDelegate`
// property.
let processor = ImageClassifierResultProcessor()
options.imageClassifierLiveStreamDelegate = processor

let imageClassifier = try ImageClassifier(options: options)
    

Objective-C

Bild

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.maxResults = 5;

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.maxResults = 5;

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Livestream

@import MediaPipeTasksVision;

// Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol
// and implements the method that the image classifier calls once it finishes
// performing classification on each input frame.

@interface APPImageClassifierResultProcessor : NSObject 

@end

@implementation APPImageClassifierResultProcessor

-   (void)imageClassifier:(MPPImageClassifier *)imageClassifier
    didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult
              timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                                error:(NSError *)error {

    // Process the image classifier result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.maxResults = 5;

// Assign an object of the class to the `imageClassifierLiveStreamDelegate`
// property.
APPImageClassifierResultProcessor *processor = [APPImageClassifierResultProcessor new];
options.imageClassifierLiveStreamDelegate = processor;

MPPImageClassifier *imageClassifier =
      [[MPPImageClassifier alloc] initWithOptions:options error:nil];
    

Konfigurationsoptionen

Diese Aufgabe bietet die folgenden Konfigurationsoptionen für iOS-Apps:

Option Beschreibung Wertebereich Standardwert
runningMode Legt den Ausführungsmodus für die Task fest. Es gibt drei Modi:

IMAGE: Der Modus für Einzelbildeingaben.

VIDEO: Der Modus für decodierte Frames eines Videos.

LIVE_STREAM: Der Modus für einen Livestream mit Eingabedaten, z. B. von einer Kamera. In diesem Modus muss resultListener aufgerufen werden, um einen Listener einzurichten, der Ergebnisse asynchron empfängt.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
displayNamesLocale Legt die Sprache der Labels fest, die für Anzeigenamen verwendet werden sollen, die in den Metadaten des Aufgabenmodells angegeben sind, sofern verfügbar. Der Standardwert für Englisch ist en. Mit der TensorFlow Lite Metadata Writer API können Sie den Metadaten eines benutzerdefinierten Modells lokalisierte Labels hinzufügen Gebietsschemacode en
maxResults Legt die optionale maximale Anzahl der am besten bewerteten Klassifizierungsergebnisse fest, die zurückgegeben werden sollen. Wenn < 0, werden alle verfügbaren Ergebnisse zurückgegeben. Beliebige positive Zahlen -1
scoreThreshold Legt den Schwellenwert für die Vorhersagepunktzahl fest, der den in den Modellmetadaten angegebenen Wert überschreibt (falls vorhanden). Ergebnisse unter diesem Wert werden abgelehnt. Beliebiger Gleitkommawert Nicht festgelegt
categoryAllowlist Legt die optionale Liste der zulässigen Kategorienamen fest. Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, deren Kategoriename nicht in diesem Satz enthalten ist. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option schließt sich mit categoryDenylist gegenseitig aus und die Verwendung beider führt zu einem Fehler. Alle Strings Nicht festgelegt
categoryDenylist Legt die optionale Liste der unzulässigen Kategorienamen fest. Ist dieses Feld nicht leer, werden Klassifizierungsergebnisse herausgefiltert, deren Kategoriename in diesem Satz enthalten ist. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option schließt sich mit categoryAllowlist gegenseitig aus und die Verwendung beider führt zu einem Fehler. Alle Strings Nicht festgelegt
resultListener Legt fest, dass der Ergebnis-Listener die Klassifizierungsergebnisse asynchron empfängt, wenn sich der Bildklassifikator im Livestreammodus befindet. Kann nur verwendet werden, wenn der Ausführungsmodus auf LIVE_STREAM festgelegt ist Nicht festgelegt

Livestreamkonfiguration

Wenn der Ausführungsmodus auf „Livestreaming“ festgelegt ist, benötigt der Bildklassifikator die zusätzliche Konfigurationsoption imageClassifierLiveStreamDelegate. Dadurch kann der Klassifikator Klassifizierungsergebnisse asynchron bereitstellen. Der Bevollmächtigte implementiert die Methode imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:), die der Bildklassifikator nach Verarbeitung der Klassifizierungsergebnisse für jeden Frame aufruft.

Optionsname Beschreibung Wertebereich Standardwert
imageClassifierLiveStreamDelegate Aktiviert den Bildklassifikator, um Klassifizierungsergebnisse asynchron im Livestream-Modus zu empfangen. Die Klasse, deren Instanz auf dieses Attribut gesetzt wird, muss die Methode imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) implementieren. Nicht zutreffend Nicht festgelegt

Daten vorbereiten

Sie müssen das Eingabebild oder den Eingabe-Frame in ein MPImage-Objekt konvertieren, bevor Sie es an den Bildklassifikator übergeben. MPImage unterstützt verschiedene Arten von iOS-Bildformaten und kann sie in jedem ausgeführten Modus für die Inferenz verwenden. Weitere Informationen zu MPImage finden Sie in der MPImage API.

Wählen Sie je nach Anwendungsfall und dem für Ihre Anwendung erforderlichen Ausführungsmodus ein iOS-Bildformat aus.MPImage akzeptiert die iOS-Bildformate UIImage, CVPixelBuffer und CMSampleBuffer.

UIImage

Das Format UIImage eignet sich gut für die folgenden Laufmodi:

  • Bilder: Bilder aus einem App Bundle, einer Nutzergalerie oder einem Dateisystem, die als UIImage-Bilder formatiert sind, können in ein MPImage-Objekt konvertiert werden.

  • Videos: Extrahieren Sie mit AVAssetImageGenerator Videoframes in das CGImage-Format und konvertieren Sie sie in UIImage-Bilder.

Swift

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Objective-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Im Beispiel wird ein MPImage mit der Standardausrichtung UIImage.Orientation.Up initialisiert. Sie können MPImage mit jedem der unterstützten Werte für UIImage.Orientation initialisieren. Der Bildklassifikator unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored oder .rightMirrored.

Weitere Informationen zu UIImage finden Sie in der Entwicklerdokumentation UIImage für Apple.

CVPixelBuffer

Das Format CVPixelBuffer eignet sich gut für Anwendungen, die Frames generieren und das iOS-Framework für CoreImage für die Verarbeitung verwenden.

Das Format CVPixelBuffer eignet sich gut für die folgenden Laufmodi:

  • Bilder: Apps, die nach einer Verarbeitung mit dem CoreImage-Framework von iOS CVPixelBuffer-Bilder generieren, können im Bildausführungsmodus an den Bildklassifikator gesendet werden.

  • Videos: Videoframes können zur Verarbeitung in das CVPixelBuffer-Format konvertiert und dann im Videomodus an den Bildklassifikator gesendet werden.

  • Livestream: Apps, die eine iOS-Kamera zum Generieren von Frames verwenden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an den Bildklassifikator gesendet werden.

Swift

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Objective-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Weitere Informationen zu CVPixelBuffer finden Sie in der Apple-Entwicklerdokumentation zu CVPixelBuffer.

CMSampleBuffer

Das Format CMSampleBuffer speichert Medienbeispiele eines einheitlichen Medientyps und eignet sich gut für den Livestream-Ausführungsmodus. Live-Frames von iOS-Kameras werden von iOS AVCaptureVideoDataOutput asynchron im CMSampleBuffer-Format bereitgestellt.

Swift

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Objective-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

Weitere Informationen zu CMSampleBuffer finden Sie in der Entwicklerdokumentation zu CMSampleBuffer Apple.

Aufgabe ausführen

Verwenden Sie zum Ausführen des Bildklassifikators die Methode classify() für den zugewiesenen Laufmodus:

  • Standbild: classify(image:)
  • Video: classify(videoFrame:timestampInMilliseconds:)
  • Livestream: classifyAsync(image:timestampInMilliseconds:)

Der Bildklassifikator gibt die möglichen Kategorien für das Objekt im Eingabebild oder -frame zurück.

Die folgenden Codebeispiele zeigen grundlegende Beispiele für die Ausführung des Image Classifier in diesen verschiedenen Laufmodi:

Swift

Bild

let result = try imageClassifier.classify(image: image)
    

Video

let result = try imageClassifier.classify(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Livestream

try imageClassifier.classifyAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Bild

MPPImageClassifierResult *result = [imageClassifier classifyImage:image
                                                            error:nil];
    

Video

MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image
                                               timestampInMilliseconds:timestamp
                                                                 error:nil];
    

Livestream

BOOL success = [imageClassifier classifyAsyncImage:image
                          timestampInMilliseconds:timestamp
                                            error:nil];
    

Im Codebeispiel für Bildklassifikatoren werden die Implementierungen der einzelnen Modi classify(image:), classify(videoFrame:timestampInMilliseconds:) und classifyAsync(image:timestampInMilliseconds:) ausführlicher dargestellt. Der Beispielcode ermöglicht es dem Nutzer, zwischen Verarbeitungsmodi zu wechseln, was für Ihren Anwendungsfall möglicherweise nicht erforderlich ist.

Wichtige Hinweise:

  • Im Video- oder Livestream-Modus müssen Sie der Bildklassifikatoraufgabe auch den Zeitstempel des Eingabe-Frames zur Verfügung stellen.

  • Im Bild- oder Videomodus blockiert die Aufgabe des Bildklassifikators den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‐frames abgeschlossen ist. Damit der aktuelle Thread nicht blockiert wird, führen Sie die Verarbeitung in einem Hintergrundthread mit den iOS-Frameworks Dispatch oder NSOperation aus.

  • Im Livestream-Modus wird die Aufgabe des Bildklassifikators sofort zurückgegeben und der aktuelle Thread wird nicht blockiert. Nach der Verarbeitung jedes Eingabeframes wird die Methode imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) mit dem Klassifizierungsergebnis aufgerufen. Der Bildklassifikator ruft diese Methode asynchron in einer dedizierten seriellen Weiterleitungswarteschlange auf. Übermitteln Sie die Ergebnisse nach Verarbeitung der Ergebnisse an die Hauptwarteschlange, um sie auf der Benutzeroberfläche anzuzeigen. Wird die Funktion classifyAsync aufgerufen, während in der Bildklassifikatoraufgabe ein anderer Frame verarbeitet wird, ignoriert der Bildklassifikator den neuen Eingabeframe.

Ergebnisse verarbeiten und anzeigen

Beim Ausführen einer Inferenz gibt die Aufgabe des Bildklassifikators ein ImageClassifierResult-Objekt zurück, das die Liste der möglichen Kategorien für die Objekte im Eingabebild oder -frame enthält.

Im Folgenden sehen Sie ein Beispiel für die Ausgabedaten dieser Aufgabe:

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

Dieses Ergebnis wurde erhalten, indem der Vogelklassifikator auf folgenden Geräten ausgeführt wurde:

Der Beispielcode für Bildklassifikatoren veranschaulicht, wie die von der Aufgabe zurückgegebenen Klassifizierungsergebnisse angezeigt werden. Weitere Informationen finden Sie im Codebeispiel.