The Mobile Vision API is deprecated

Effectuer le suivi des visages et des codes-barres

Cette page explique comment créer une application qui utilise la caméra arrière pour afficher les visages et les codes-barres détectés devant vous. La capture d'écran ci-dessous le montre en action. Elle a été prise sur une tablette qui pointait vers un écran affichant plusieurs photos. Nous allons vous montrer comment suivre tous les codes-barres et dessiner un rectangle autour de chacun, en indiquant leur valeur, leur position et leur taille. De plus, nous dessinons un ovale autour de chaque visage détecté, en indiquant l'ID de visage (attribué de manière séquentielle), la position et la taille.

Si vous souhaitez suivre le code, ou si vous souhaitez simplement créer et tester l'application, celle-ci est disponible dans le dossier multi-tracker de nos exemples GitHub.

Ce tutoriel aborde les sujets suivants:

  1. Créez des détecteurs de visages et de codes-barres.
  2. Utilisez un MultiDetector pour combiner les codes-barres et les détecteurs de visages.
  3. Interrogez l'état opérationnel du détecteur.
  4. Configuration de la caméra pour la détection combinée.
  5. Créez des images distinctes pour les codes-barres et les visages.

Créer un détecteur de code-barres

Créez un détecteur de code-barres pour suivre les codes-barres:

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();

Par défaut, le détecteur de codes-barres recherche tous les formats de codes-barres compatibles.

Vous pouvez également spécifier un sous-ensemble de formats à détecter via la méthode BarcodeDetector.Builder.setFormats. Réduire le nombre de formats à détecter accélère la détection du code-barres.

Créer un multiprocesseur pour gérer les codes-barres détectés

Vous devez fournir un TrackerFactory afin de créer une instance Tracker pour chaque code-barres. Pour cet exemple, BarcodeTrackerFactory crée un BarcodeGraphic qui superpose le cadre de délimitation et la valeur pour chaque résultat de code-barres:

BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
barcodeDetector.setProcessor(
    new MultiProcessor.Builder<>(barcodeFactory).build());

Conceptuellement, une partie du pipeline de traitement de détection est créée comme suit:

Cette partie du pipeline fonctionne comme suit:

  1. Le détecteur de codes-barres détecte les codes-barres et crée une collection d'instances de codes-barres.

  2. Une instance multiprocesseur suit chaque code-barres actif. Il utilise une fabrique pour créer une instance de suivi graphique par code-barres.

  3. Le suivi des codes-barres sur les images vidéo permet au multiprocesseur de mettre à jour les instances correspondantes du code-barres. Dans ce cas, les mises à jour du code-barres sont simplement la position et la taille du code-barres dans le cadre de la vidéo.

Créer un détecteur de visages

Créez un détecteur de visages pour suivre les visages:

FaceDetector faceDetector = new FaceDetector.Builder(context).build();

Consultez le tutoriel sur l'API Face Tracker pour en savoir plus sur les paramètres de détection des visages par défaut, créés en créant cette méthode de détection de visages.

Créer un multiprocesseur pour gérer les visages détectés

Une instance multiprocesseur associée est configurée pour recevoir les résultats de la détection des visages. Une fabrique permet au multiprocesseur de créer une instance de coach électronique distincte pour chaque face:

FaceTrackerFactory faceFactory = new FaceTrackerFactory(mGraphicOverlay);
faceDetector.setProcessor(
    new MultiProcessor.Builder<>(faceFactory).build());

Conceptuellement, une partie du pipeline de traitement de détection est créée comme suit:

Cette partie du pipeline fonctionne comme suit:

  1. Le détecteur de visages détecte les visages et crée une collection d'instances de visage.

  2. Une instance multiprocesseur suit chaque visage actif. Elle utilise une fabrique pour créer une instance de suivi graphique par visage.

  3. Lorsque les visages sont suivis sur plusieurs images, le multiprocesseur envoie les mises à jour aux instances correspondantes de l'outil de suivi des visages. Dans ce cas, les mises à jour représentent simplement la position et la taille du visage dans le cadre de la vidéo. Mais dans d'autres cas, il peut s'agir aussi bien de points de repère de visages que de classifications qui sourient / y sont ouvertes.

Utiliser un multidétecteur pour combiner les codes-barres et les détecteurs de visages

Un détecteur multiple permet de regrouper les deux détecteurs en un seul détecteur. Toutes les images reçues par ce détecteur de la caméra seront déléguées au détecteur de code-barres et au détecteur de visage sous-jacents.

MultiDetector multiDetector = new MultiDetector.Builder()
    .add(barcodeDetector)
    .add(faceDetector)
    .build();

D'un point de vue conceptuel, cela unifie les parties du code-barres et des faces du pipeline comme suit:

Le multidétecteur reçoit une série d'images provenant de la source de l'appareil photo. Chaque image est envoyée au détecteur de code-barres et au détecteur de visage, ce qui entraîne à la fois la détection des codes-barres et la détection des visages sur chaque image.

Interroger l'état opérationnel du détecteur

La première fois qu'une application utilisant des codes-barres et/ou des API de reconnaissance faciale est installée sur un appareil, GMS télécharge une bibliothèque sur l'appareil afin de procéder à la détection des codes-barres et des visages. En règle générale, cette opération est effectuée par le programme d'installation avant l'exécution initiale de l'application. Les dépendances visuelles doivent être incluses dans le fichier AndroidManifest.xml de l'application dans l'expression "application" pour permettre l'installation automatique:

<meta-data
    android:name="com.google.android.gms.vision.DEPENDENCIES"
    android:value="barcode,face" />

Toutefois, si le téléchargement n'est pas encore terminé au démarrage de votre application, les détecteurs ci-dessus ne détecteront aucun code-barres ni aucun visage (du moins dans un premier temps). Cela peut se produire si l'utilisateur n'est pas en ligne, s'il n'a pas suffisamment d'espace de stockage sur son appareil ou si le téléchargement est retardé autrement (en raison d'un réseau lent, par exemple).

Les détecteurs deviendront automatiquement opérationnels une fois le téléchargement de la bibliothèque terminé sur l'appareil.

La méthode isOperational d'un détecteur permet de vérifier si la bibliothèque native requise est actuellement disponible:

if (!detector.isOperational()) {
    // ...
}

De plus, les résultats de détection créés pour chaque image indiquent si le détecteur correspondant est opérationnel via la méthode Detections.detectorIsOperational().

Votre application peut agir en fonction de l'état de fonctionnement d'un détecteur (par exemple, désactiver temporairement certaines fonctionnalités ou afficher une notification à l'utilisateur). Tant que les bibliothèques n'ont pas été téléchargées, les détecteurs sont des détecteurs "no-op" et ne détectent aucun résultat.

Configuration de la caméra pour la détection combinée

Créez la source de la caméra pour la caméra arrière, configurée pour envoyer des images d'aperçu au multidétecteur:

mCameraSource = new CameraSource.Builder(context, multiDetector)
    .setFacing(CameraSource.CAMERA_FACING_BACK)
    .setRequestedFps(15.0f)
    .build();

Notez que la résolution par défaut (1 024 x 768) sera plus élevée que celle de l'exemple précédent. Étant donné que le détecteur de code-barres fonctionne mieux à des résolutions élevées, il est plus facile de détecter les codes-barres.

Cependant, l'inconvénient d'une résolution plus élevée est que la détection des visages nécessite plus de temps. Pour compenser cela, nous avons également réduit la fréquence d'images (FPS) à 15 images par seconde. Cela réduira la fréquence des trames envoyées vers le pipeline.

Créer des images distinctes pour les codes-barres et les visages

Chacune des instances GraphicTracker créées dans les extraits de code précédents conserve les éléments graphiques dans une vue superposée à l'aperçu de la caméra:

Comme indiqué précédemment, les instances de fabrique sont associées à chaque multiprocesseur. Chacun crée une instance GraphicTracker ainsi qu'un type d'image spécifique à afficher (par exemple, une image de code-barres ou une image de visage):

class BarcodeTrackerFactory implements MultiProcessor.Factory<Barcode> {
    ...
    public Tracker<Barcode> create(Barcode barcode) {
        BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay);
        return new GraphicTracker<>(mGraphicOverlay, graphic);
    }
}

class FaceTrackerFactory implements MultiProcessor.Factory<Face> {
    ...
    public Tracker<Face> create(Face face) {
        FaceGraphic graphic = new FaceGraphic(mGraphicOverlay);
        return new GraphicTracker<>(mGraphicOverlay, graphic);
    }
}

Les classes BarcodeGraphic et FaceGraphic implémentent les spécificités de l'affichage des graphiques associés respectivement à une instance de code-barres ou de visage. Par exemple, BarcodeGraphic dessine la "valeur brute" et le cadre de délimitation du code-barres détecté:

class BarcodeGraphic extends TrackedGraphic<Barcode> {
    ...
    public void draw(Canvas canvas) {
        ...
        canvas.drawRect(rect, mRectPaint);
        canvas.drawText(barcode.rawValue, rect.left, rect.bottom, mTextPaint);
    }
}

FaceGraphic dessine l'ID de visage et le cadre de délimitation détectés (en tant qu'ovale):

class FaceGraphic extends TrackedGraphic<Face> {
    ...
    public void draw(Canvas canvas) {
        float cx = translateX(face.getPosition().x + face.getWidth() / 2);
        ...
        canvas.drawText("id: " + getId(), cx + ID_X_OFFSET, cy + ID_Y_OFFSET, mIdPaint);
        canvas.drawOval(left, top, right, bottom, mBoxPaint);
    }
}