Objekte in Bildern mit einem von AutoML trainierten Modell unter Android erkennen

Nachdem Sie Ihr eigenes Modell mit AutoML Vision Edge trainiert haben, können Sie es in Ihrer App verwenden, um Objekte in Bildern zu erkennen.

Es gibt zwei Möglichkeiten, mit AutoML Vision Edge trainierte Modelle zu integrieren: Sie können das Modell im Asset-Ordner Ihrer App bündeln oder es dynamisch von Firebase herunterladen.

Optionen für die Modellkombination
In Ihrer App gebündelt
  • Das Modell ist Teil des APK Ihrer App.
  • Das Modell ist sofort verfügbar, auch wenn das Android-Gerät offline ist.
  • Kein Firebase-Projekt erforderlich
Mit Firebase gehostet
  • Hosten Sie das Modell, indem Sie es in Firebase Machine Learning hochladen.
  • Verringert die APK-Größe
  • Das Modell wird auf Anfrage heruntergeladen.
  • Modellupdates per Push senden, ohne die App noch einmal zu veröffentlichen
  • Einfache A/B-Tests mit Firebase Remote Config
  • Erfordert ein Firebase-Projekt

Hinweis

  1. Wenn Sie ein Modell herunterladen möchten, müssen Sie Ihrem Android-Projekt Firebase hinzufügen, falls Sie dies noch nicht getan haben. Das ist nicht erforderlich, wenn Sie das Modell bündeln.

  2. Fügen Sie die Abhängigkeiten für die TensorFlow Lite Task-Bibliothek der Gradle-Datei des Moduls auf Anwendungsebene hinzu, die in der Regel app/build.gradle lautet:

    So bündeln Sie ein Modell mit Ihrer App:

    dependencies {
      // ...
      // Object detection with a bundled Auto ML model
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly-SNAPSHOT'
    }
    

    Wenn Sie ein Modell dynamisch von Firebase herunterladen möchten, fügen Sie auch die Firebase ML-Abhängigkeit hinzu:

    dependencies {
      // ...
      // Object detection with an Auto ML model deployed to Firebase
      implementation platform('com.google.firebase:firebase-bom:26.1.1')
      implementation 'com.google.firebase:firebase-ml-model-interpreter'
    
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.0.0-nightly'
    }
    

1. Modell laden

Lokale Modellquelle konfigurieren

So bündeln Sie das Modell mit Ihrer App:

  1. Extrahieren Sie das Modell aus dem ZIP-Archiv, das Sie aus der Google Cloud-Konsole heruntergeladen haben.
  2. Fügen Sie Ihr Modell in Ihr App-Paket ein:
    1. Wenn Sie in Ihrem Projekt noch keinen Assets-Ordner haben, erstellen Sie einen. Klicken Sie dazu mit der rechten Maustaste auf den Ordner app/ und dann auf Neu > Ordner > Assets-Ordner.
    2. Kopieren Sie die tflite-Modelldatei mit eingebetteten Metadaten in den Ordner „Assets“.
  3. Fügen Sie der build.gradle-Datei Ihrer App Folgendes hinzu, damit Gradle die Modelldatei beim Erstellen der App nicht komprimiert:

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    Die Modelldatei wird in das App-Paket aufgenommen und als Roh-Asset verfügbar gemacht.

Firebase-gehostete Modellquelle konfigurieren

Wenn Sie das remote gehostete Modell verwenden möchten, erstellen Sie ein RemoteModel-Objekt und geben Sie den Namen an, den Sie dem Modell bei der Veröffentlichung zugewiesen haben:

Java

// Specify the name you assigned when you deployed the model.
FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin

// Specify the name you assigned when you deployed the model.
val remoteModel =
    FirebaseCustomRemoteModel.Builder("your_model_name").build()

Starten Sie dann die Aufgabe zum Herunterladen des Modells und geben Sie die Bedingungen an, unter denen der Download zulässig sein soll. Wenn das Modell nicht auf dem Gerät vorhanden ist oder eine neuere Version des Modells verfügbar ist, wird es von der Aufgabe asynchron von Firebase heruntergeladen:

Java

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

Viele Apps starten die Downloadaufgabe in ihrem Initialisierungscode, Sie können dies aber auch jederzeit tun, bevor Sie das Modell verwenden müssen.

Objekterkennung aus Ihrem Modell erstellen

Nachdem Sie Ihre Modellquellen konfiguriert haben, erstellen Sie ein ObjectDetector-Objekt aus einer der Quellen.

Wenn Sie nur ein lokal bereitgestelltes Modell haben, erstellen Sie einfach einen Objektdetektor aus Ihrer Modelldatei und konfigurieren Sie den gewünschten Grenzwert für den Konfidenzwert (siehe Modell bewerten):

Java

// Initialization
ObjectDetectorOptions options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build();
ObjectDetector objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options);

Kotlin

// Initialization
val options = ObjectDetectorOptions.builder()
    .setScoreThreshold(0)  // Evaluate your model in the Google Cloud console
                           // to determine an appropriate value.
    .build()
val objectDetector = ObjectDetector.createFromFileAndOptions(context, modelFile, options)

Wenn Sie ein extern gehostetes Modell haben, müssen Sie prüfen, ob es heruntergeladen wurde, bevor Sie es ausführen. Sie können den Status der Modelldownloadaufgabe mit der isModelDownloaded()-Methode des Modellmanagers prüfen.

Sie müssen dies zwar nur vor dem Ausführen des Objekterkennungsmodells bestätigen, wenn Sie jedoch sowohl ein remote gehostetes Modell als auch ein lokal gebündeltes Modell haben, kann es sinnvoll sein, diese Prüfung beim Instanziieren des Objekterkennungsmodells durchzuführen: Erstellen Sie ein Objekterkennungsmodell aus dem Remote-Modell, wenn es heruntergeladen wurde, andernfalls aus dem lokalen Modell.

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
            }
        });

Kotlin

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener { success ->

        }

Wenn Sie nur ein extern gehostetes Modell haben, sollten Sie modellverwandte Funktionen deaktivieren, z. B. einen Teil der Benutzeroberfläche grau ausblenden oder ausblenden, bis Sie bestätigen, dass das Modell heruntergeladen wurde. Dazu fügen Sie der download()-Methode des Modellmanagers einen Listener hinzu.

Sobald Sie wissen, dass Ihr Modell heruntergeladen wurde, erstellen Sie einen Objektdetektor aus der Modelldatei:

Java

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnCompleteListener(new OnCompleteListener<File>() {
            @Override
            public void onComplete(@NonNull Task<File> task) {
                File modelFile = task.getResult();
                if (modelFile != null) {
                    ObjectDetectorOptions options = ObjectDetectorOptions.builder()
                            .setScoreThreshold(0)
                            .build();
                    objectDetector = ObjectDetector.createFromFileAndOptions(
                            getApplicationContext(), modelFile.getPath(), options);
                }
            }
        });

Kotlin

FirebaseModelManager.getInstance().getLatestModelFile(remoteModel)
        .addOnSuccessListener { modelFile ->
            val options = ObjectDetectorOptions.builder()
                    .setScoreThreshold(0f)
                    .build()
            objectDetector = ObjectDetector.createFromFileAndOptions(
                    applicationContext, modelFile.path, options)
        }

2. Eingabebild vorbereiten

Erstellen Sie dann für jedes Bild, das Sie beschriften möchten, ein TensorImage-Objekt aus dem Bild. Mit der Methode fromBitmap können Sie ein TensorImage-Objekt aus einem Bitmap erstellen:

Java

TensorImage image = TensorImage.fromBitmap(bitmap);

Kotlin

val image = TensorImage.fromBitmap(bitmap)

Wenn sich Ihre Bilddaten nicht in einer Bitmap befinden, können Sie ein Pixelarray laden, wie in den TensorFlow Lite-Dokumenten beschrieben.

3. Objektdetektor ausführen

Wenn Sie Objekte in einem Bild erkennen möchten, übergeben Sie das TensorImage-Objekt an die detect()-Methode von ObjectDetector.

Java

List<Detection> results = objectDetector.detect(image);

Kotlin

val results = objectDetector.detect(image)

4. Informationen zu gekennzeichneten Objekten abrufen

Wenn der Vorgang zur Objekterkennung erfolgreich war, wird eine Liste von Detection-Objekten zurückgegeben. Jedes Detection-Objekt steht für etwas, das im Bild erkannt wurde. Sie können den Begrenzungsrahmen und die Labels jedes Objekts abrufen.

Beispiel:

Java

for (Detection result : results) {
    RectF bounds = result.getBoundingBox();
    List<Category> labels = result.getCategories();
}

Kotlin

for (result in results) {
    val bounds = result.getBoundingBox()
    val labels = result.getCategories()
}

Tipps zur Verbesserung der Echtzeitleistung

Wenn Sie Bilder in einer Echtzeitanwendung taggen möchten, beachten Sie die folgenden Richtlinien, um die beste Framerate zu erzielen:

  • Aufrufe an den Bildbeschrifter drosseln Wenn während der Ausführung des Bildestikkers ein neuer Videoframe verfügbar wird, legen Sie ihn ab. Ein Beispiel finden Sie in der Klasse VisionProcessorBase in der Beispiel-App für die Schnellstartanleitung.
  • Wenn Sie die Ausgabe des Bildes-Labelers verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. So wird für jeden Eingabeframe nur einmal auf die Displayoberfläche gerendert. Eines dieser Beispiele finden Sie in der Beispiel-App für den Schnellstart in den Klassen CameraSourcePreview und GraphicOverlay.
  • Wenn Sie die Camera2 API verwenden, sollten Sie Bilder im ImageFormat.YUV_420_888-Format aufnehmen.

    Wenn Sie die ältere Camera API verwenden, nehmen Sie Bilder im ImageFormat.NV21-Format auf.