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

1. Avant de commencer

ML Kit est un SDK mobile qui intègre l'expertise de Google en machine learning sur l'appareil aux applications Android et iOS. Vous pouvez utiliser les API Vision et Natural Language, puissantes et simples à utiliser, pour résoudre les défis courants de vos applications ou créer de toutes nouvelles expériences utilisateur. Ils sont tous basés sur les meilleurs modèles de ML de Google et sont proposés sans frais.

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

Cet atelier de programmation vous explique comment ajouter simplement la détection et le suivi d'objets (ODT) pour une image donnée dans votre application Android existante. Veuillez noter que cet atelier de programmation utilise des raccourcis pour mettre en avant l'utilisation de la fonctionnalité ODT 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 Object Detection and Tracking pour détecter des objets dans une image donnée.À la fin, 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é. Cela décompresse un dossier racine (mlkit-android-main) contenant toutes les ressources dont vous avez besoin. Pour cet atelier de programmation, vous n'avez besoin que des sources du sous-répertoire object-detection.

Le sous-répertoire "object-detection" 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'exemple d'application terminée.

3. Ajouter l'API ML Kit Object Detection and Tracking 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 choisissez 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 des objets ML Kit

Les dépendances ML Kit vous permettent d'intégrer le SDK ML Kit ODT à 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 les fichiers Gradle

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

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 à n'importer que 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 d'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 ( Exécuter) 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 standard qui vous permet de prendre une photo ou de sélectionner une image prédéfinie, puis de l'envoyer à un pipeline de détection et de suivi d'objets que vous allez créer dans cet atelier de programmation. Examinons un peu l'application avant d'écrire du code.

Tout d'abord, un bouton ( c6d965d639c3646.png) en bas vous permet de:

  • Ouvrez l'application Appareil photo intégrée à votre appareil/émulateur.
  • prendre une photo dans votre 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-la s'afficher dans l'application de démarrage.

Répétez ces étapes plusieurs fois pour voir comment cela fonctionne:

9ec541980dbe2d31.png 8312dde41425ba4b.png fa8492bfc1914ff0.png

Vous avez le choix entre trois images prédéfinies. Vous pourrez utiliser ces images plus tard pour tester le code de détection d'objets si vous exécutez le code sur un émulateur Android.

Sélectionnez une image parmi les trois images 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

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

Lorsque vous avez sélectionné une image, soit parmi les images prédéfinies, soit en prenant une photo avec l'application Appareil photo, le code standard décode cette image dans une instance Bitmap, l'affiche à l'écran et appelle la méthode runObjectDetection avec l'image.

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

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

La configuration de l'ODT ML Kit ne nécessite que 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)

Vous devez les effectuer 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 l'ODT ML Kit. Android Studio vous invite à ajouter les importations nécessaires au fur et à mesure:

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

Étape 1: Créer une InputImage

ML Kit fournit une API simple pour créer un InputImage à partir d'un Bitmap. Vous pouvez ensuite transmettre un InputImage aux 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 schéma de conception du compilateur. Vous transmettrez la configuration au compilateur, puis vous en obtiendrez un détecteur. Trois options sont disponibles à configurer (les options en gras sont utilisées dans cet atelier de programmation):

  • mode du détecteur (image unique ou flux)
  • mode de détection (détection d'un ou de plusieurs objets)
  • mode de classification (activé ou désactivé)

Cet atelier de programmation concerne la détection et la classification de plusieurs objets dans une seule image. 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: Fournissez une ou plusieurs images au détecteur

La détection et la classification des objets sont des traitements asynchrones:

  • Vous envoyez une image au détecteur (via process()).
  • Le détecteur s'en occupe.
  • Le détecteur vous renvoie le résultat via un rappel.

Le code suivant fait exactement cela (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 informations suivantes:

  • Nombre total d'objets détectés. Chaque objet détecté est décrit avec les éléments suivants:
  • trackingId: entier que vous utilisez pour le suivre entre les cadres (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 (Obtenir le texte de ce libellé, y compris "Articles de mode", "Aliments", "Articles pour la maison", "Lieu", "Plante")
  • confidence ( nombre à virgule flottante compris entre 0,0 et 1,0, où 1,0 correspond à 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 êtes maintenant prêt à accepter des images pour la détection.

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 de prendre une photo, puis examinez 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 vu trois objets:

  • Les catégories sont Aliments et Articles de maison.
  • Aucune catégorie n'est renvoyée pour le deuxième, car il s'agit d'une classe inconnue.
  • Aucun trackingId (car il s'agit du mode de détection d'une seule image).
  • Position dans le rectangle boundingBox (par exemple, (481, 2021) – (2426, 3376))
  • Le détecteur est assez sûr que le premier est un aliment (90% de confiance, il s'agissait d'une salade).

Techniquement, c'est tout ce dont vous avez besoin pour que la détection d'objets ML Kit fonctionne. Vous avez tout ce qu'il vous faut pour le moment ! Félicitations !

Du côté de l'interface utilisateur, vous êtes toujours au stade où vous avez commencé, mais vous pouvez utiliser les résultats détectés dans l'interface utilisateur, par exemple en dessinant le cadre de délimitation pour améliorer l'expérience. Passons à l'étape suivante: post-traitons les résultats détectés.

6. Post-traitement des résultats de détection

Dans les é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:

  • dessiner le cadre de délimitation sur l'image
  • dessiner le nom de la catégorie et le score de confiance dans le cadre de délimitation

Comprendre les utilitaires de visualisation

L'atelier de programmation contient du code générique pour vous aider à visualiser le résultat de la détection. Exploitez ces utilitaires pour simplifier le 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 correspond au cadre de délimitation dans lequel se trouve l'objet, et text à la chaîne de résultats de 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 la détection d'objets dans detectionResults sur l'entrée bitmap et renvoie la copie modifiée.

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

58c6f1d4ddb00dfa.png

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

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

Accédez à l'endroit où vous appelez debugPrint(), puis 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)
}
  • Commencez par analyser le DetectedObject de ML Kit et créez une liste d'objets BoxWithText pour afficher le résultat de la visualisation.
  • Vous dessinez ensuite le résultat de la détection au-dessus de l'image d'entrée à l'aide de la méthode utilitaire drawDetectionResult, puis l'affichez à l'écran.

Exécuter le code

Cliquez maintenant 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 Appareil photo, pointez l'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. Vous devriez voir les résultats de la détection. Appuyez à nouveau sur le bouton ou sélectionnez une autre image pour répéter l'opération plusieurs fois et découvrir la dernière version de l'ODT ML Kit.

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 une image au détecteur

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

Vous pouvez améliorer le modèle au fur et à mesure. Comme vous pouvez le constater, le modèle par défaut ne peut reconnaître que cinq catégories. Il ne reconnaît même pas le couteau, la fourchette et la bouteille. Consultez l'autre atelier de programmation de notre parcours d'apprentissage "Machine learning sur l'appareil : détection d'objets" pour découvrir comment entraîner un modèle personnalisé.

Points abordés

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

Étapes suivantes

  • Découvrez plus d'images et de vidéos en direct avec ML Kit ODT pour profiter de la précision et des performances de détection et de classification
  • Consultez le parcours de formation sur la détection d'objets pour découvrir comment entraîner un modèle personnalisé.
  • Appliquer l'ODT ML Kit dans votre propre application Android

En savoir plus