Mit der Aufgabe „MediaPipe Image Embedder“ können Sie Bilddaten in eine numerische Darstellung konvertieren um ML-bezogene Bildverarbeitungsaufgaben zu erledigen, z. B. den Vergleich der Ähnlichkeit von zwei Bildern. In dieser Anleitung erfahren Sie, wie Sie die Bildeinbetter mit Android-Apps
Weitere Informationen zu Funktionen, Modellen und Konfigurationsoptionen Sehen Sie sich die Übersicht an.
Codebeispiel
Der MediaPipe Tasks-Beispielcode ist eine einfache Implementierung eines Image Embedders. für Android. In diesem Beispiel wird die Kamera eines physischen Android-Geräts verwendet, um Bilder kontinuierlich einbetten und die Einbettung auch für gespeicherte Bilddateien ausführen auf dem Gerät.
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 das Einbinden von Bildern 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:
- Klonen Sie das Git-Repository mit dem folgenden Befehl:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Konfigurieren Sie optional Ihre Git-Instanz für den Sparse-Checkout, damit Sie
nur die Dateien für die Beispielanwendung zum Einbinden von Bildern:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_embedder/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 hierzu finden Sie im Einrichtungsleitfaden für Android-Geräte
Schlüsselkomponenten
Die folgenden Dateien enthalten den wichtigen Code für dieses Beispiel für den Bildeinbetter. Anwendung:
- ImageEmbedderHelper.kt: Initialisiert den Bildeinbetter und verwaltet das Modell und den Bevollmächtigten Auswahl.
- MainActivity.kt: Implementiert die Anwendung und stellt die Komponenten der Benutzeroberfläche zusammen.
Einrichtung
In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten Ihrer Entwicklungsumgebung und für die Verwendung von Bildeinbetter programmieren. Allgemeine Informationen zum Einrichten der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich Plattformversion finden Sie im Einrichtungsleitfaden für Android-Geräte
<ph type="x-smartling-placeholder">Abhängigkeiten
Der Bildeinbetter verwendet die com.google.mediapipe:tasks-vision
-Bibliothek. Dieses Element hinzufügen
Abhängigkeit zur Datei build.gradle
Ihres Android-App-Entwicklungsprojekts.
Importieren Sie die erforderlichen Abhängigkeiten mit dem folgenden Code:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Modell
Für die Aufgabe „MediaPipe Image Embedder“ ist ein trainiertes Modell erforderlich, . Weitere Informationen zu verfügbaren trainierten Modellen für den Bildeinbetter findest du 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
Geben Sie den Pfad des Modells innerhalb des Parameters ModelAssetPath
an. Im
Beispielcode haben, wird das Modell in der setupImageEmbedder()
-Funktion im
ImageEmbedderHelper.kt
Datei:
Verwenden Sie die Methode BaseOptions.Builder.setModelAssetPath()
, um den Pfad anzugeben.
die vom Modell verwendet werden. Diese Methode wird im Codebeispiel in den
.
Aufgabe erstellen
Zum Erstellen der Aufgabe können Sie die Funktion createFromOptions
verwenden. Die
Die Funktion createFromOptions
akzeptiert Konfigurationsoptionen, um den Einbettungscode festzulegen
Optionen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfiguration
Übersicht.
Bei der Aufgabe „Bild einbetten“ werden drei Arten von Eingabedaten unterstützt: 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
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.IMAGE) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Video
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.VIDEO) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Livestream
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener((result, inputImage) -> { // Process the embedding result here. }) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Die Beispielcode-Implementierung ermöglicht es dem Nutzer, zwischen den Verarbeitungsvorgängen
Modi. Dieser Ansatz macht den Code zur Aufgabenerstellung komplizierter und ist möglicherweise nicht
für Ihren Anwendungsfall geeignet. Sie sehen diesen Code in der
setupImageEmbedder()
in der Spalte
ImageEmbedderHelper.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 |
l2_normalize |
Gibt an, ob der zurückgegebene Featurevektor mit der L2-Norm normalisiert werden soll. Verwenden Sie diese Option nur, wenn das Modell noch keine native L2_NORMALIZATION TFLite Op. In den meisten Fällen ist dies bereits der Fall und Die L2-Normalisierung wird somit über TFLite-Inferenz ohne Notwendigkeit erreicht. für diese Option. | Boolean |
False |
quantize |
Ob die zurückgegebene Einbettung in Byte quantisiert werden soll mithilfe von eine skalare Quantisierung. Bei Einbettungen wird implizit angenommen, Daher hat jede Dimension garantiert einen Wert in [-1,0; 1,0]. Verwenden Sie die Option „l2_normalize“ verwenden, wenn dies nicht der Fall ist. | Boolean |
False |
resultListener |
Legt den Ergebnis-Listener fest, der die Einbettungsergebnisse empfangen soll
asynchron, wenn sich der Bildeinbetter 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 Bildeinbetter funktioniert mit Bildern, Videodateien und Videos per Livestream. 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
Aufgabe „Bild einbetten“.
Bild
import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; // Load an image on the user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s 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 video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s 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 CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s Image object. android.media.Image mediaImage = imageProxy.getImage() Image mpImage = new MediaImageBuilder(mediaImage).build();
Im Beispielcode wird die Datenvorbereitung in der ImageEmbedderHelper.kt -Datei.
Aufgabe ausführen
Sie können die Funktion embed
für Ihren Laufmodus aufrufen, um
Rückschlüsse. Die Image Embedder API gibt die Einbettungsvektoren für die Eingabe zurück.
Bild oder Rahmen.
Bild
ImageEmbedderResult embedderResult = imageEmbedder.embed(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. ImageEmbedderResult embedderResult = imageEmbedder.embedForVideo(image, frameTimestampMs);
Livestream
// Run inference on the frame. The embedding results will be available // via the `resultListener` provided in the `ImageEmbedderOptions` when // the image embedder was created. imageEmbedder.embedAsync(image, frameTimestampMs);
Wichtige Hinweise:
- Im Video- oder Livestreammodus musst du außerdem den Zeitstempel des Eingabe-Frames für die Aufgabe „Bildeinbetter“ angeben.
- Im Bild- oder Videomodus wird die Aufgabe „Bild einbetten“ den aktuellen Thread blockieren, bis die Verarbeitung des Eingabebildes abgeschlossen ist, Frame. Um das Blockieren des aktuellen Threads zu vermeiden, führen Sie die Verarbeitung in einem im Hintergrund.
- Im Livestreammodus blockiert die Aufgabe „Bild einbetten“ nicht
im aktuellen Thread zu lesen,
aber sofort wieder zurück. Das Ergebnis wird aufgerufen.
Listener mit dem Erkennungsergebnis, sobald er die Verarbeitung eines
Eingabe-Frame. Ob die Funktion
embedAsync
aufgerufen wird, wenn der Bildeinbetter die Aufgabe mit der Verarbeitung eines anderen Frames beschäftigt ist, ignoriert die Aufgabe den neuen Eingabeframe.
Im Beispielcode wird die Funktion embed
im
ImageEmbedderHelper.kt
-Datei.
Ergebnisse verarbeiten und anzeigen
Beim Ausführen einer Inferenz gibt die Aufgabe zum Einbinden von Bildern ein ImageEmbedderResult
zurück.
das eine Liste von Einbettungen (entweder Gleitkomma- oder
skalar quantisiert) für das Eingabebild.
Im Folgenden sehen Sie ein Beispiel für die Ausgabedaten dieser Aufgabe:
ImageEmbedderResult:
Embedding #0 (sole embedding head):
float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
head_index: 0
Dieses Ergebnis wurde durch Einbetten des folgenden Bildes erhalten:
Sie können die Ähnlichkeit von zwei Einbettungen mithilfe der Funktion
ImageEmbedder.cosineSimilarity
. Im folgenden Code finden Sie eine
Beispiel.
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));