La tâche de l'intégrateur d'images MediaPipe vous permet de convertir des données d'image en représentation numérique pour effectuer des tâches de traitement d'images liées au ML, comme comparer les la similitude de deux images. Ces instructions vous expliquent comment utiliser Outil d'intégration d'images avec des applications Android
Pour en savoir plus sur les fonctionnalités, les modèles et les options de configuration de cette tâche, consultez la section Présentation.
Exemple de code
L'exemple de code MediaPipe Tasks est une implémentation simple d'un intégrateur d'images pour Android. L'exemple utilise l'appareil photo d'un appareil Android physique pour d'intégrer des images en continu et d'exécuter l'outil d'intégration sur les fichiers image stockés sur l'appareil.
Vous pouvez utiliser l'application comme point de départ pour votre propre application Android ou vous y référer. lorsque vous modifiez une application existante. L'exemple de code de l'outil d'intégration d'images est hébergé GitHub
Télécharger le code
Les instructions suivantes vous expliquent comment créer une copie locale de l'exemple à l'aide de l'outil de ligne de commande git.
<ph type="x-smartling-placeholder">Pour télécharger l'exemple de code:
- Clonez le dépôt Git à l'aide de la commande suivante:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Si vous le souhaitez, vous pouvez configurer votre instance Git pour utiliser le paiement creuse.
Seuls les fichiers de l'application exemple de l'outil d'intégration d'images:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_embedder/android
Après avoir créé une version locale de l'exemple de code, vous pouvez importer le projet dans Android Studio et exécuter l'application. Pour obtenir des instructions, consultez le Guide de configuration Android
Composants clés
Les fichiers suivants contiennent le code essentiel pour cet exemple d'outil d'intégration d'images application:
- ImageEmbedderHelper.kt: initialise l'intégrateur d'images, et gère le modèle et la délégation de votre choix.
- MainActivity.kt: implémente l'application et assemble les composants de l'interface utilisateur.
Configuration
Cette section décrit les étapes clés à suivre pour configurer votre environnement de développement pour utiliser l'outil d'intégration d'images. Pour obtenir des informations générales sur la configuration environnement de développement permettant d'utiliser des tâches MediaPipe, y compris la version de la plate-forme configuration requise, consultez le Guide de configuration Android
<ph type="x-smartling-placeholder">Dépendances
L'outil d'intégration d'images utilise la bibliothèque com.google.mediapipe:tasks-vision
. Ajouter
au fichier build.gradle
de votre projet de développement d'applications Android.
Importez les dépendances requises avec le code suivant:
dependencies {
...
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Modèle
La tâche de l'intégrateur d'images MediaPipe nécessite un modèle entraîné compatible avec tâche. Pour en savoir plus sur les modèles entraînés disponibles pour l'intégrateur d'images, consultez la section Modèles de la présentation des tâches.
Sélectionnez et téléchargez le modèle, puis stockez-le dans le répertoire de votre projet:
<dev-project-root>/src/main/assets
Spécifiez le chemin d'accès du modèle dans le paramètre ModelAssetPath
. Dans
exemple de code, le modèle est défini dans la fonction setupImageEmbedder()
ImageEmbedderHelper.kt
:
Utiliser la méthode BaseOptions.Builder.setModelAssetPath()
pour spécifier le chemin d'accès
utilisées par le modèle. Cette méthode est mentionnée dans l'exemple de code de la
.
Créer la tâche
Vous pouvez utiliser la fonction createFromOptions
pour créer la tâche. La
La fonction createFromOptions
accepte les options de configuration pour définir l'intégrateur
options. Pour plus d'informations sur les options de configuration, consultez la section Configuration
Présentation.
La tâche de l'intégrateur d'images accepte trois types de données d'entrée: images fixes, fichiers vidéo, et les flux vidéo en direct. Vous devez spécifier le mode d'exécution correspondant votre type de données d'entrée lors de la création de la tâche. Choisissez l'onglet correspondant votre type de données d'entrée pour découvrir comment créer la tâche et exécuter l'inférence.
Image
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.IMAGE) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Vidéo
ImageEmbedderOptions options = ImageEmbedderOptions.builder() .setBaseOptions( BaseOptions.builder().setModelAssetPath("model.tflite").build()) .setQuantize(true) .setRunningMode(RunningMode.VIDEO) .build(); imageEmbedder = ImageEmbedder.createFromOptions(context, options);
Diffusion en direct
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);
L'exemple d'implémentation de code permet à l'utilisateur de basculer entre les modes de traitement
différents modes. L'approche rend le code de création de la tâche plus compliqué et peut ne pas être
adapté à votre cas d'utilisation. Ce code figure dans la
fonction setupImageEmbedder()
dans
ImageEmbedderHelper.kt
.
Options de configuration
Cette tâche comporte les options de configuration suivantes pour les applications Android:
Nom de l'option | Description | Plage de valeurs | Valeur par défaut |
---|---|---|---|
runningMode |
Définit le mode d'exécution de la tâche. Il y en a trois
modes: IMAGE: mode utilisé pour la saisie d'une seule image. VIDEO: mode des images décodées d'une vidéo. LIVE_STREAM: mode d'une diffusion en direct des entrées provenant d'un appareil photo, par exemple. Dans ce mode, resultListener doit être appelé pour configurer un écouteur afin de recevoir les résultats ; de manière asynchrone. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
l2_normalize |
Indique s'il faut normaliser le vecteur de caractéristiques renvoyé avec la norme L2. N'utilisez cette option que si le modèle ne contient pas encore d'élément natif L2_NORMALIZATION TFLite Op. Dans la plupart des cas, c'est déjà le cas et La normalisation L2 est ainsi obtenue via l'inférence TFLite sans avoir besoin pour cette option. | Boolean |
False |
quantize |
Indique si la représentation vectorielle continue renvoyée doit être quantifiée en octets via la quantification scalaire. Les représentations vectorielles continues sont implicitement considérées comme étant une norme unitaire Par conséquent, toute dimension aura une valeur comprise dans [-1.0, 1.0]. Utilisez l'option l2_normalize si ce n'est pas le cas. | Boolean |
False |
resultListener |
Définit l'écouteur des résultats pour qu'il reçoive les résultats de la représentation vectorielle continue.
de manière asynchrone lorsque l'intégrateur d'images est dans la diffusion en direct
. Ne peut être utilisé que lorsque le mode d'exécution est défini sur LIVE_STREAM |
N/A | Non défini |
errorListener |
Définit un écouteur d'erreurs facultatif. | N/A | Non défini |
Préparer les données
L'outil d'intégration d'images fonctionne avec les images, les fichiers vidéo et les diffusions en direct. La tâche gère le prétraitement de l'entrée des données, y compris le redimensionnement, la rotation et la valeur. normalisation.
Vous devez convertir l'image ou le cadre d'entrée en
com.google.mediapipe.framework.image.MPImage
avant de le transmettre à
Tâche d'intégration d'images.
Image
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();
Vidéo
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();
Diffusion en direct
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();
Dans l'exemple de code, la préparation des données est gérée dans le ImageEmbedderHelper.kt .
Exécuter la tâche
Vous pouvez appeler la fonction embed
correspondant à votre mode de course pour déclencher
les inférences. L'API Image Embedder renvoie les vecteurs de représentation vectorielle continue de l'entrée
comme une image ou un cadre.
Image
ImageEmbedderResult embedderResult = imageEmbedder.embed(image);
Vidéo
// 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);
Diffusion en direct
// 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);
Veuillez noter les points suivants :
- Lorsque vous êtes en mode vidéo ou flux en direct, vous devez également fournir le code temporel de la trame d'entrée à la tâche de l'intégrateur d'images.
- Lors de l'exécution en mode image ou vidéo, la tâche "Outil d'intégration d'images" bloquer le thread actuel jusqu'à ce qu'il ait fini de traiter l'image d'entrée ou cadre. Pour éviter de bloquer le thread actuel, exécutez le traitement dans une thread d'arrière-plan.
- Lors de l'exécution en mode de diffusion en direct, la tâche de l'intégrateur d'images ne bloque pas
le thread actuel, mais renvoie immédiatement. Elle appellera son résultat
avec le résultat de la détection chaque fois que le traitement d'une
trame d'entrée. Si la fonction
embedAsync
est appelée lorsque l'intégrateur d'images est occupée à traiter une autre trame, la tâche ignore la nouvelle trame d'entrée.
Dans l'exemple de code, la fonction embed
est définie dans
ImageEmbedderHelper.kt
.
Gérer et afficher les résultats
Lors de l'exécution de l'inférence, la tâche d'intégration d'images renvoie un ImageEmbedderResult
contenant une liste de représentations vectorielles continues (à virgule flottante ou
quantifiée scalaire) pour l'image d'entrée.
Voici un exemple de données de sortie de cette tâche:
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
Ce résultat a été obtenu en intégrant l'image suivante:
Vous pouvez comparer la similarité de deux représentations vectorielles continues à l'aide de la fonction
fonction ImageEmbedder.cosineSimilarity
. Consultez le code suivant pour obtenir
à titre d'exemple.
// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
result.embeddingResult().embeddings().get(0),
otherResult.embeddingResult().embeddings().get(0));