Détecter des objets dans des images avec ML Kit: Android

1. Avant de commencer

ML Kit est un SDK pour mobile qui permet d'appliquer aux applications Android et iOS l'expertise de Google en machine learning sur l'appareil. Puissantes et simples à utiliser, les API Vision et Natural Language peuvent vous aider à résoudre les problèmes courants rencontrés dans vos applications ou à créer de toutes nouvelles expériences utilisateur. Tous sont basés sur les modèles de ML de pointe de Google et vous sont proposés sans frais.

Les API de ML Kit s'exécutent toutes sur l'appareil, ce qui permet des cas d'utilisation en temps réel où vous souhaitez traiter un flux de caméra en direct, par exemple. Cela signifie également que la fonctionnalité est disponible hors connexion.

Cet atelier de programmation vous explique comment ajouter la détection et le suivi des objets (ODT) d'une image donnée à votre application Android existante. Veuillez noter que cet atelier de programmation comporte des raccourcis pour mettre en avant l'utilisation de la version à la demande de ML Kit.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez créer une application Android avec ML Kit. Votre application utilisera l'API ML Kit de détection et de suivi des objets pour détecter les objets dans une image donnée.Au final, vous devriez voir quelque chose de semblable à l'image de droite.

Points abordés

  • Intégrer le SDK ML Kit à votre application Android
  • API ML Kit Object Detection and Tracking

Prérequis

  • Une version récente d'Android Studio (version 4.1.2 ou ultérieure)
  • Android Studio Emulator ou un appareil Android physique
  • L'exemple de code
  • Vous disposez de connaissances de base en développement Android en Kotlin.

Cet atelier de programmation est consacré à ML Kit. Les concepts et les blocs de codes non pertinents ne sont pas abordés, et vous sont fournis afin que vous puissiez simplement les copier et les coller.

2. Configuration

Télécharger le code

Cliquez sur le lien ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Décompressez le fichier ZIP téléchargé. Cette opération a pour effet de décompresser un dossier racine (mlkit-android-main) contenant toutes les ressources dont vous avez besoin. Pour cet atelier de programmation, vous n'aurez besoin que des sources du sous-répertoire object-detection.

Le sous-répertoire de détection d'objets du dépôt mlkit-android contient deux répertoires:

  • android_studio_folder.pngstarter : code de démarrage sur lequel s'appuie cet atelier de programmation.
  • android_studio_folder.pngfinal : code final de l'application exemple terminée.

3. Ajouter l'API de détection et de suivi des objets ML Kit au projet

Importer l'application dans Android Studio

Commençons par importer l'application de démarrage dans Android Studio.

Ouvrez Android Studio, sélectionnez Import Project (Gradle, Eclipse ADT, etc.) (Importer un projet (Gradle, Eclipse ADT, etc.), puis sélectionnez le dossier starter dans le code source que vous avez téléchargé précédemment.

7c0f27882a2698ac.png

Ajouter les dépendances pour la détection et le suivi d'objets ML Kit

Les dépendances de ML Kit vous permettent d'intégrer le SDK ODT de ML Kit à votre application. Ajoutez les lignes suivantes à la fin du fichier app/build.gradle de votre projet:

build.gradle

dependencies {
  // ...
  implementation 'com.google.mlkit:object-detection:16.2.4'
}

Synchroniser votre projet avec des fichiers Gradle

Pour vous assurer que toutes les dépendances sont disponibles pour votre application, vous devez à ce stade synchroniser votre projet avec les fichiers Gradle.

Sélectionnez Sync Project with Gradle Files (Synchroniser le projet avec les fichiers Gradle) (b451ab2d04d835f9.png) dans la barre d'outils d'Android Studio.

(Si ce bouton est désactivé, veillez à importer uniquement starter/app/build.gradle , et non l'intégralité du dépôt.)

4. Exécuter l'application de démarrage

Maintenant que vous avez importé le projet dans Android Studio et ajouté les dépendances pour la détection et le suivi des objets ML Kit, vous êtes prêt à exécuter l'application pour la première fois.

Connectez votre appareil Android à votre hôte via USB, ou démarrez l'émulateur Android Studio,puis cliquez sur Run ( execute.png) dans la barre d'outils d'Android Studio.

Exécuter et explorer l'application

L'application doit se lancer sur votre appareil Android. Il contient du code récurrent qui vous permet de prendre une photo ou de sélectionner une image prédéfinie, puis de l'alimenter dans un pipeline de détection et de suivi d'objets que vous allez créer dans cet atelier de programmation. Explorons un peu l'application avant d'écrire du code.

Tout d'abord, il y a un Button ( c6d965d639c3646.png) en bas. Il permet d'accéder aux éléments suivants:

  • afficher l'application Appareil photo intégrée à votre appareil/émulateur
  • prenez une photo dans l'application Appareil photo
  • recevoir l'image capturée dans l'application de démarrage ;
  • afficher l'image

Essayez le bouton Prendre une photo, suivez les instructions pour prendre une photo, acceptez la photo et observez qu'elle s'affiche dans l'application de démarrage.

Répétez l'opération plusieurs fois pour voir comment cela fonctionne:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

Deuxièmement, vous pouvez choisir parmi trois images prédéfinies. Vous pouvez utiliser ces images ultérieurement pour tester le code de détection d'objets si vous utilisez un émulateur Android.

Sélectionnez une image parmi les trois prédéfinies. Vérifiez que l'image s'affiche dans la vue agrandie:

1dd41b3ec978f1d9.png

5. Ajouter la détection d'objets sur l'appareil

Au cours de cette étape, vous allez ajouter à l'application de démarrage la fonctionnalité permettant de détecter des objets dans des images. Comme vous l'avez vu à l'étape précédente, l'application de démarrage contient du code récurrent permettant de prendre des photos avec l'application Appareil photo de l'appareil. L'application propose également trois images prédéfinies sur lesquelles vous pouvez essayer la détection d'objets si vous exécutez l'atelier de programmation sur un émulateur Android.

Lorsque vous avez sélectionné une image à partir des images prédéfinies ou que vous avez pris une photo avec l'application Appareil photo, le code récurrent la décode dans une instance Bitmap, l'affiche à l'écran et appelle la méthode runObjectDetection avec l'image.

Au cours de cette étape, vous allez ajouter du code à la méthode runObjectDetection pour effectuer une détection d'objets.

Configurer et exécuter la détection d'objets sur l'appareil sur une image

La configuration de ML Kit ODT se fait en trois étapes simples avec trois API:

  • préparer une image: InputImage
  • Créez un objet détecteur: ObjectDetection.getClient(options)
  • connectez les deux objets ci-dessus: process(image)

Ces opérations sont effectuées dans la fonction runObjectDetection(bitmap: Bitmap) du fichier MainActivity.kt.

/**
 * ML Kit Object Detection Function
 */
private fun runObjectDetection(bitmap: Bitmap) {
}

Pour le moment, la fonction est vide. Passez aux étapes suivantes pour implémenter la fonctionnalité ODT de ML Kit. En cours de route, Android Studio vous invite à ajouter les importations nécessaires:

  • com.google.mlkit.vision.common.InputImage
  • com.google.mlkit.vision.objects.ObjectDetection
  • com.google.mlkit.vision.objects.defaults.ObjectDetectorOptions

Étape 1: Créez une InputImage

ML Kit fournit une API simple pour créer un InputImage à partir d'un Bitmap. Vous pouvez ensuite alimenter un InputImage dans les API ML Kit.

// Step 1: create ML Kit's InputImage object
val image = InputImage.fromBitmap(bitmap, 0)

Ajoutez le code ci-dessus en haut de runObjectDetection(bitmap:Bitmap).

Étape 2: Créez une instance de détecteur

ML Kit suit le modèle de conception du compilateur. Vous allez transmettre la configuration au compilateur, puis vous procurer un détecteur. Vous pouvez configurer trois options (les options en gras sont utilisées dans cet atelier de programmation):

  • mode détecteur (image unique ou flux)
  • le mode de détection (détection une ou plusieurs objets) ;
  • Mode de classification (activé ou désactivé)

Cet atelier de programmation concerne une seule image : détection de plusieurs objets la classification. Ajoutez-le maintenant:

// Step 2: acquire detector object
val options = ObjectDetectorOptions.Builder()
   .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
   .enableMultipleObjects()
   .enableClassification()
   .build()
val objectDetector = ObjectDetection.getClient(options)

Étape 3: Importez les images dans le détecteur

La détection et la classification d'objets sont un traitement asynchrone:

  • Vous envoyez une image au détecteur (via process()).
  • Le détecteur travaille dur pour résoudre ce problème.
  • Le détecteur vous renvoie le résultat via un rappel.

C'est exactement ce que fait le code suivant (copiez-le et ajoutez-le au code existant dans fun runObjectDetection(bitmap:Bitmap)):.

// Step 3: feed given image to detector and setup callback
objectDetector.process(image)
   .addOnSuccessListener {
       // Task completed successfully
        debugPrint(it)
   }
   .addOnFailureListener {
       // Task failed with an exception
       Log.e(TAG, it.message.toString())
   }

Une fois l'opération terminée, le détecteur vous envoie les notifications suivantes:

  • Nombre total d'objets détectés. Chaque objet détecté est décrit avec les éléments suivants:
  • trackingId: nombre entier que vous utilisez pour effectuer le suivi des images entre les images (NON utilisé dans cet atelier de programmation).
  • boundingBox: cadre de délimitation de l'objet.
  • labels: : liste des libellés de l'objet détecté (uniquement lorsque la classification est activée) :
  • index (obtenir l'index de ce libellé)
  • text (Récupérer le texte de ce libellé, y compris "Fashion Goods" (Articles de mode), "Food", "Home Goods" (Articles ménagers), "Place" (Place) et "Plant" (Plante)
  • confidence ( une valeur flottante comprise entre 0,0 et 1,0 avec 1,0 signifie 100%)

Vous avez probablement remarqué que le code effectue un traitement de type printf pour le résultat détecté avec debugPrint().

Ajoutez-le à la classe MainActivity:

private fun debugPrint(detectedObjects: List<DetectedObject>) {
   detectedObjects.forEachIndexed { index, detectedObject ->
       val box = detectedObject.boundingBox

       Log.d(TAG, "Detected object: $index")
       Log.d(TAG, " trackingId: ${detectedObject.trackingId}")
       Log.d(TAG, " boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")
       detectedObject.labels.forEach {
           Log.d(TAG, " categories: ${it.text}")
           Log.d(TAG, " confidence: ${it.confidence}")
       }
   }
}

Vous pouvez désormais détecter des images !

Exécutons l'atelier de programmation en cliquant sur Run (Exécuter) (execute.png) dans la barre d'outils d'Android Studio. Essayez de sélectionner une image prédéfinie ou prenez une photo, puis regardez la fenêtre Logcat( 16bd6ea224cf8cf1.png) dans l'IDE.

Le résultat doit ressembler à ceci :

D/MLKit Object Detection: Detected object: 0
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (481, 2021) - (2426,3376)
D/MLKit Object Detection:  categories: Food
D/MLKit Object Detection:  confidence: 0.90234375
D/MLKit Object Detection: Detected object: 1
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (2639, 2633) - (3058,3577)
D/MLKit Object Detection: Detected object: 2
D/MLKit Object Detection:  trackingId: null
D/MLKit Object Detection:  boundingBox: (3, 1816) - (615,2597)
D/MLKit Object Detection:  categories: Home good
D/MLKit Object Detection:  confidence: 0.75390625

...ce qui signifie que le détecteur a détecté trois objets:

  • Les catégories sont Nourriture et Articles pour la maison.
  • Aucune catégorie n'a été renvoyée pour la 2e classe, car il s'agit d'une classe inconnue.
  • Aucun trackingId (car il s'agit du mode de détection d'image unique).
  • La position à l'intérieur du rectangle boundingBox (par exemple, (481, 2021) – (2426, 3376))
  • Le détecteur a de fortes chances de confirmer que le premier est un aliment (niveau de confiance de 90 % : c'était une salade).

Techniquement, c'est tout ce dont vous avez besoin pour faire fonctionner la détection d'objets ML Kit: vous savez tout pour le moment. Félicitations !

En ce qui concerne l'interface utilisateur, vous êtes toujours à l'étape au début, mais vous pouvez utiliser les résultats détectés dans l'interface utilisateur, par exemple en dessinant le cadre de délimitation pour créer une meilleure expérience. Passons à l'étape suivante: post-traitez les résultats détectés.

6. Post-traiter les résultats de la détection

Lors des étapes précédentes, vous avez imprimé le résultat détecté dans Logcat: simple et rapide.

Dans cette section, vous allez utiliser le résultat dans l'image:

  • tracer le cadre de délimitation sur l'image
  • tracer le nom de la catégorie et le niveau de confiance dans le cadre de délimitation.

Comprendre les utilitaires de visualisation

Cet atelier de programmation inclut du code récurrent qui vous aidera à visualiser le résultat de la détection. Utilisez ces utilitaires pour simplifier notre code de visualisation:

  • data class BoxWithText(val box: Rect, val text: String) Il s'agit d'une classe de données permettant de stocker un résultat de détection d'objets à des fins de visualisation. box est le cadre de délimitation dans lequel se situe l'objet, et text est la chaîne de résultats de la détection à afficher avec le cadre de délimitation de l'objet.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<BoxWithText>): Bitmap : cette méthode dessine les résultats de détection d'objets dans detectionResults sur l'bitmap d'entrée et renvoie la copie modifiée de celui-ci.

Voici un exemple de résultat de la méthode utilitaire drawDetectionResult:

58c6f1d4ddb00dfa.png

Visualiser le résultat de la détection de ML Kit

Utilisez les utilitaires de visualisation pour tracer le résultat de la détection d'objets de ML Kit au-dessus de l'image d'entrée.

Accédez à l'emplacement où vous appelez debugPrint() et ajoutez l'extrait de code suivant en dessous:

// Parse ML Kit's DetectedObject and create corresponding visualization data
val detectedObjects = it.map { obj ->
    var text = "Unknown"

    // We will show the top confident detection result if it exist
    if (obj.labels.isNotEmpty()) {
        val firstLabel = obj.labels.first()
        text = "${firstLabel.text}, ${firstLabel.confidence.times(100).toInt()}%"
    }
    BoxWithText(obj.boundingBox, text)
}

// Draw the detection result on the input bitmap
val visualizedResult = drawDetectionResult(bitmap, detectedObjects)

// Show the detection result on the app screen
runOnUiThread {
    inputImageView.setImageBitmap(visualizedResult)
}
  • Vous commencerez par analyser le fichier DetectedObject de ML Kit et créer une liste d'objets BoxWithText pour afficher le résultat de la visualisation.
  • Ensuite, tracez le résultat de la détection par-dessus l'image d'entrée à l'aide de la méthode utilitaire drawDetectionResult, puis affichez-le à l'écran.

Exécuter le code

Cliquez à présent sur Run (Exécuter) (execute.png) dans la barre d'outils d'Android Studio.

Une fois l'application chargée, appuyez sur le bouton avec l'icône de l'appareil photo, dirigez votre appareil photo vers un objet, prenez une photo, acceptez la photo (dans l'application Appareil photo) ou appuyez facilement sur n'importe quelle image prédéfinie. Les résultats de la détection doivent s'afficher. appuyez à nouveau sur le bouton ou sélectionnez une autre image pour la répéter plusieurs fois afin de découvrir la dernière version de ML Kit ODT.

a03109cb30d5014d.png

7. Félicitations !

Vous avez utilisé ML Kit pour ajouter des fonctionnalités de détection d'objets à votre application:

  • 3 étapes avec 3 API
  • Créer une image d'entrée
  • Créer un détecteur
  • Envoyer l'image au détecteur

C'est tout ce dont vous avez besoin pour le mettre en service !

À mesure que vous continuez, vous souhaiterez peut-être améliorer le modèle. Comme vous pouvez le constater, le modèle par défaut ne peut reconnaître que cinq catégories. Le modèle ne reconnaît même pas les couteaux, les fourchettes et les bouteilles. Consultez l'autre atelier de programmation de notre parcours de formation Machine Learning – Détection d'objets sur l'appareil pour apprendre à entraîner un modèle personnalisé.

Points abordés

  • Ajouter la détection et le suivi d'objets ML Kit à votre application Android
  • Utiliser la détection d'objets sur l'appareil et le suivi dans ML Kit pour détecter des objets dans des images

Étapes suivantes

  • Explorez davantage avec ML Kit ODT avec plus d'images et de vidéos en direct pour tester la détection et la précision et les performances de la classification
  • Pour apprendre à entraîner un modèle personnalisé, consultez le parcours de formation "Détection d'objets" sur le machine learning sur l'appareil.
  • Appliquer ML Kit ODT dans votre propre application Android

En savoir plus