Leitfaden zur Bildklassifizierung für Android

Mit der Aufgabe „MediaPipe Image Classifier“ 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 verwenden. mit Android-Apps. Das in dieser Anleitung beschriebene Codebeispiel ist am GitHub

In unserer Webdemo können Sie diese Aufgabe in Aktion sehen. Weitere Informationen zu Funktionen, Modellen und Konfigurationsoptionen Sehen Sie sich die Übersicht an.

Codebeispiel

Der Beispielcode von MediaPipe Tasks ist eine einfache Implementierung eines Bildklassifikators. für Android. In diesem Beispiel wird die Kamera eines physischen Android-Geräts verwendet, um können Objekte kontinuierlich klassifizieren und auch Bilder und Videos aus dem Gerätegalerie verwenden, um Objekte statisch zu klassifizieren.

Du kannst die App als Ausgangspunkt für deine eigene Android-App verwenden oder darauf verweisen wenn Sie eine vorhandene App ändern. Der Beispielcode für den Bildklassifikator wird auf GitHub

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie eine lokale Kopie des Beispiels erstellen. mit dem Befehlszeilentool git erstellen.

<ph type="x-smartling-placeholder">

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. Konfigurieren Sie optional Ihre Git-Instanz für den Sparse-Checkout. Sie haben also nur die Dateien für die Beispiel-App "Bildklassifikator":
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_classification/android
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt importieren in Android Studio ein und führen die App aus. Anweisungen finden Sie in der Einrichtungsleitfaden für Android

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigen Code für dieses Bild. Beispielanwendung für die Klassifizierung:

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und für die Verwendung des Bildklassifikators programmieren. Allgemeine Informationen zu Einrichten Ihrer Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich Plattformversionsanforderungen finden Sie in der Einrichtungsleitfaden für Android

<ph type="x-smartling-placeholder">

Abhängigkeiten

Bildklassifikator verwendet die com.google.mediapipe:tasks-vision-Bibliothek. Dieses Element hinzufügen Abhängigkeit zur build.gradle-Datei Ihres Android-App-Entwicklungsprojekt Importieren Sie die erforderlichen Abhängigkeiten mit den folgenden Code:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

Modell

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

Wählen Sie das Modell aus, laden Sie es herunter und speichern Sie es dann in Ihrem Projektverzeichnis:

<dev-project-root>/src/main/assets

Verwenden Sie die Methode BaseOptions.Builder.setModelAssetPath(), um den Pfad anzugeben. die vom Modell verwendet werden. Diese Methode wird im Codebeispiel in den .

Im Beispielcode für Bildklassifikator Das Modell ist in ImageClassifierHelper.kt definiert. -Datei.

Aufgabe erstellen

Zum Erstellen der Aufgabe können Sie die Funktion createFromOptions verwenden. Die Die Funktion createFromOptions akzeptiert Konfigurationsoptionen, einschließlich der Ausführung Modus, Anzeigenamen, Sprache, maximale Anzahl von Ergebnissen, Konfidenzgrenzwert, und einer Sperr- oder Zulassungsliste für Kategorien. Weitere Informationen zur Konfiguration finden Sie unter Konfigurationsübersicht.

Die Aufgabe „Bildklassifikator“ unterstützt drei Eingabedatentypen: Standbilder, Videodateien, und Live-Videostreams. Sie müssen den Laufmodus für beim Erstellen der Aufgabe Ihren Eingabedatentyp. Wählen Sie die Registerkarte für um zu sehen, wie die Aufgabe erstellt und eine Inferenz ausgeführt wird.

Bild

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

Video

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

Livestream

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
         // Process the classification result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the classification errors here.
    })
    .build()
imageClassifier = ImageClassifier.createFromOptions(context, options)
    

Mit dem Beispielcode für den Bildklassifikator kann der Nutzer zwischen Verarbeitungsmodi. Dieser Ansatz macht den Code zur Aufgabenerstellung komplizierter und ist möglicherweise für Ihren Anwendungsfall ungeeignet. Sie sehen diesen Code in der setupImageClassifier()-Funktion des ImageClassifierHelper.kt -Datei.

Konfigurationsoptionen

Diese Aufgabe bietet die folgenden Konfigurationsoptionen für Android-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 Eingabe zum Beispiel von einer Kamera. In diesem Modus muss der resultListener wird aufgerufen, um einen Listener für den Empfang von Ergebnissen einzurichten asynchron programmiert.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
displayNamesLocale Legt die Sprache der Labels fest, die für Anzeigenamen in der Metadaten des Aufgabenmodells, falls verfügbar. Standardwert ist en für Englisch. Sie können den Metadaten eines benutzerdefinierten Modells lokalisierte Labels hinzufügen mit der TensorFlow Lite Metadata Writer API Gebietsschemacode de
maxResults Legt die optionale maximale Anzahl der am besten bewerteten Klassifizierungsergebnisse fest auf zurückgeben. Wenn < 0 setzen, werden alle verfügbaren Ergebnisse zurückgegeben. Beliebige positive Zahlen -1
scoreThreshold Legt den Schwellenwert für die Vorhersagepunktzahl fest, der den Wert in die Modellmetadaten (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, Klassifizierungsergebnisse, deren Kategoriename nicht in dieser Gruppe enthalten ist, werden herausgefiltert. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option schließt sich mit categoryDenylist gegenseitig aus und verwendet führt beides zu einem Fehler. Alle Strings Nicht festgelegt
categoryDenylist Legt die optionale Liste der unzulässigen Kategorienamen fest. Wenn nicht leer ist, werden Klassifizierungsergebnisse gefiltert, deren Kategoriename in diesem Satz enthalten ist. aus. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option ausschließlich mit categoryAllowlist und die Verwendung beider führt zu einem Fehler. Alle Strings Nicht festgelegt
resultListener Legt den Ergebnis-Listener so fest, dass er die Klassifizierungsergebnisse empfängt asynchron, wenn sich der Bildklassifikator im Livestream befindet . Kann nur verwendet werden, wenn der Ausführungsmodus auf LIVE_STREAM festgelegt ist Nicht festgelegt
errorListener Legt einen optionalen Fehler-Listener fest. Nicht festgelegt

Daten vorbereiten

Der Bildklassifikator kann mit Bildern, Videodateien und Videos per Livestream verwendet werden. Die Aufgabe übernimmt die Vorverarbeitung der Dateneingabe, einschließlich Größenanpassung, Rotation und Wert. Normalisierung.

Sie müssen das Eingabebild oder den Eingabe-Frame in ein com.google.mediapipe.framework.image.MPImage-Objekt vor der Übergabe an den Bildklassifikator.

Bild

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

Video

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

Livestream

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraXs ImageAnalysis to continuously receive frames 
// from the devices camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Androids ImageProxy object received from the ImageAnalysis, 
// extract the encapsulated Androids Image object and convert it to 
// a MediaPipes Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

Im Beispielcode für den Bildklassifikator verwendet, erfolgt die Datenvorbereitung im ImageClassifierHelper.kt -Datei.

Aufgabe ausführen

Sie können die Funktion classify für Ihren Ausführungsmodus aufrufen, um Inferenzen auszulösen. Die Image Classifier API gibt die möglichen Kategorien für das Objekt innerhalb des Eingabebilds oder -frames zurück.

Bild

ImageClassifierResult classifierResult = imageClassifier.classify(image);
    

Video

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageClassifierResult classifierResult =
    imageClassifier.classifyForVideo(image, frameTimestampMs);
    

Livestream

// Run inference on the frame. The classifications results will be available 
// via the `resultListener` provided in the `ImageClassifierOptions` when 
// the image classifier was created.
imageClassifier.classifyAsync(image, frameTimestampMs);
    

Wichtige Hinweise:

  • Im Video- oder Livestreammodus musst du außerdem Zeitstempel des Eingabe-Frames für die Aufgabe des Bildklassifikators bereitstellen.
  • Bei der Ausführung im Bild- oder Videomodus wird die Aufgabe blockiert den aktuellen Thread, bis die Verarbeitung des Eingabebildes Frame. Damit die Benutzeroberfläche nicht blockiert wird, führen Sie die Verarbeitung in einem im Hintergrund.
  • Im Livestreammodus blockiert die Aufgabe „Bildklassifikator“ nicht, aktuellen Thread angelehnt, aber sofort wieder zurück. Das Ergebnis wird aufgerufen. Listener mit dem Erkennungsergebnis, sobald er die Verarbeitung eines Eingabe-Frame. Ob die Funktion classifyAsync aufgerufen wird, wenn der Bildklassifikator die Aufgabe mit der Verarbeitung eines anderen Frames beschäftigt ist, ignoriert die Aufgabe den neuen Eingabeframe.

Im Beispielcode für den Bildklassifikator haben Sie die classify-Funktionen im ImageClassifierHelper.kt -Datei.

Ergebnisse verarbeiten und anzeigen

Beim Ausführen einer Inferenz gibt die Bildklassifikatoraufgabe ein ImageClassifierResult-Objekt zurück, das die Liste der möglichen Kategorien für die Objekte innerhalb des Eingabebilds oder -frames 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 erhalten Sie mit dem Vogelklassifikator. am:

Im Beispielcode für den Bildklassifikator, die Klasse ClassificationResultsAdapter in der ClassificationResultsAdapter.kt -Datei verarbeitet die Ergebnisse:

fun updateResults(imageClassifierResult: ImageClassifierResult? = null) {
    categories = MutableList(adapterSize) { null }
    if (imageClassifierResult != null) {
        val sortedCategories = imageClassifierResult.classificationResult()
            .classifications()[0].categories().sortedBy { it.index() }
        val min = kotlin.math.min(sortedCategories.size, categories.size)
        for (i in 0 until min) {
            categories[i] = sortedCategories[i]
        }
    }
}