Erkennen Sie Objekte in Bildern mit einem AutoML-trainierten Modell auf Android

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 bündeln, indem Sie es im Asset-Ordner Ihrer App ablegen, oder Sie können es dynamisch von Firebase herunterladen.

Optionen zur Modellbündelung
In Ihrer App gebündelt
  • Das Modell ist Teil der APK Ihrer App
  • Das Modell ist sofort verfügbar, auch wenn das Android-Gerät offline ist
  • Kein Firebase-Projekt erforderlich
Gehostet mit Firebase
  • Hosten Sie das Modell, indem Sie es auf Firebase Machine Learning hochladen
  • Reduziert die APK-Größe
  • Das Modell wird bei Bedarf heruntergeladen
  • Pushen Sie Modellaktualisierungen, ohne Ihre App erneut zu veröffentlichen
  • Einfaches A/B-Testen mit Firebase Remote Config
  • Erfordert ein Firebase-Projekt

Bevor Sie beginnen

  1. Wenn Sie ein Modell herunterladen möchten , stellen Sie sicher, dass Sie Firebase zu Ihrem Android-Projekt hinzufügen , sofern Sie dies noch nicht getan haben. Dies ist nicht erforderlich, wenn Sie das Modell bündeln.

  2. Fügen Sie die Abhängigkeiten für die TensorFlow Lite Task-Bibliothek zur Gradle-Datei auf App-Ebene Ihres Moduls hinzu, die normalerweise 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'
    }
    

    Um ein Modell dynamisch von Firebase herunterzuladen, 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. Laden Sie das Modell

Konfigurieren Sie eine lokale Modellquelle

So bündeln Sie das Modell mit Ihrer App:

  1. Extrahieren Sie das Modell aus dem ZIP-Archiv, das Sie von der Google Cloud Console heruntergeladen haben.
  2. Fügen Sie Ihr Modell in Ihr App-Paket ein:
    1. Wenn Ihr Projekt keinen Ordner „Assets“ enthält, erstellen Sie einen, indem Sie mit der rechten Maustaste auf den Ordner app/ klicken und dann auf „Neu > Ordner > Ordner „Assets““ klicken.
    2. Kopieren Sie Ihre tflite Modelldatei mit eingebetteten Metadaten in den Assets-Ordner.
  3. Fügen Sie der build.gradle Datei Ihrer App Folgendes hinzu, um sicherzustellen, dass Gradle die Modelldatei beim Erstellen der App nicht komprimiert:

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

    Die Modelldatei wird im App-Paket enthalten und als Roh-Asset verfügbar.

Konfigurieren Sie eine von Firebase gehostete Modellquelle

Um das remote gehostete Modell zu verwenden, erstellen Sie ein RemoteModel Objekt und geben Sie dabei den Namen an, den Sie dem Modell beim Veröffentlichen 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 Sie den Download zulassen möchten. Wenn sich das Modell nicht auf dem Gerät befindet oder eine neuere Version des Modells verfügbar ist, lädt die Aufgabe das Modell asynchron von Firebase herunter:

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 Download-Aufgabe in ihrem Initialisierungscode, Sie können dies jedoch jederzeit tun, bevor Sie das Modell verwenden müssen.

Erstellen Sie aus Ihrem Modell einen Objektdetektor

Nachdem Sie Ihre Modellquellen konfiguriert haben, erstellen Sie aus einer davon ein ObjectDetector Objekt.

Wenn Sie nur über ein lokal gebündeltes Modell verfügen, erstellen Sie einfach einen Objektdetektor aus Ihrer Modelldatei und konfigurieren Sie den Schwellenwert für die Konfidenzbewertung, den Sie benötigen möchten (siehe Bewerten Sie Ihr Modell ):

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 über ein remote gehostetes Modell verfügen, müssen Sie überprüfen, ob es heruntergeladen wurde, bevor Sie es ausführen. Sie können den Status der Modell-Download-Aufgabe mit der Methode isModelDownloaded() des Modellmanagers überprüfen.

Obwohl Sie dies nur bestätigen müssen, bevor Sie den Objektdetektor ausführen, kann es sinnvoll sein, diese Prüfung bei der Instanziierung des Objektdetektors durchzuführen, wenn Sie sowohl ein remote gehostetes Modell als auch ein lokal gebündeltes Modell haben: Erstellen Sie einen Objektdetektor von der Fernbedienung aus Modell, wenn es heruntergeladen wurde, und andernfalls vom 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 über ein remote gehostetes Modell verfügen, sollten Sie modellbezogene Funktionen deaktivieren – zum Beispiel einen Teil Ihrer Benutzeroberfläche ausgrauen oder ausblenden –, bis Sie bestätigen, dass das Modell heruntergeladen wurde. Sie können dies tun, indem Sie einen Listener an download() Methode des Modellmanagers anhängen.

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. Bereiten Sie das Eingabebild vor

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

Java

TensorImage image = TensorImage.fromBitmap(bitmap);

Kotlin

val image = TensorImage.fromBitmap(bitmap)

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

3. Führen Sie den Objektdetektor aus

Um Objekte in einem Bild zu erkennen, übergeben Sie das TensorImage Objekt an die Methode detect() von ObjectDetector .

Java

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

Kotlin

val results = objectDetector.detect(image)

4. Informieren Sie sich über gekennzeichnete Objekte

Wenn der Objekterkennungsvorgang erfolgreich ist, wird eine Liste von Detection zurückgegeben. Jedes Detection stellt etwas dar, das im Bild erkannt wurde. Sie können den Begrenzungsrahmen und die Beschriftungen jedes Objekts abrufen.

Zum 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 beschriften möchten, befolgen Sie diese Richtlinien, um die besten Frameraten zu erzielen:

  • Drosseln Sie Aufrufe an den Bildbezeichner. Wenn ein neues Videobild verfügbar wird, während der Bildbeschrifter ausgeführt wird, löschen Sie das Bild. Ein Beispiel finden Sie in der VisionProcessorBase Klasse in der Schnellstart-Beispiel-App.
  • Wenn Sie die Ausgabe des Bildbeschrifters verwenden, um Grafiken auf dem Eingabebild zu überlagern, rufen Sie zuerst das Ergebnis ab und rendern Sie dann das Bild und überlagern Sie es in einem einzigen Schritt. Auf diese Weise rendern Sie für jeden Eingaberahmen nur einmal auf der Anzeigeoberfläche. Ein Beispiel finden Sie in den Klassen CameraSourcePreview und GraphicOverlay in der Schnellstart-Beispiel-App.
  • Wenn Sie die Camera2-API verwenden, erfassen Sie Bilder im ImageFormat.YUV_420_888 Format.

    Wenn Sie die ältere Kamera-API verwenden, erfassen Sie Bilder im ImageFormat.NV21 Format.