Détection de visages (détection de faces)

 

Sous Android, il est possible de lancer une détection de visages sur les images qui sont envoyées par la caméra.

Pour cela, il faut que vous ayez locké une caméra et que celle-ci soit en mode preview.

L'ajout de votre code se fera donc au moins en grande partie dans la procédure callback surfaceCreated(SurfaceHolder holder) de votre SurfaceHolder.

 

Détection possible ?

Première chose à faire, vérifier que votre appareil peut détecter des visages:

camera.getParameters().getMaxNumDetectedFaces();

 

Listener de détection de visage

Si c'est le cas, positionner un listener sur la caméra:

Vous utiliserez la méthode setFaceDetectionListener()

Lorsque le listener se déclenche, celui-ci indique l'instance de camera pour laquelle au moins un visage est détecté ainsi qu'un tableau de type Camera.Face contenant l'ensemble des informations des visages détectés:

public int id identifiant unique par visage.

public Point leftEye Coordonnées de l'oeil gauche (au centre)

public Point rightEye Coordonnées de l'oeil droit (au centre)

public Point mouth Coordonnées de la bouche (au centre)
public Rect rect Coordonnées d'un rectangle entourant le visage pour la caméra. (cf. Rect), voir note ci-après.

public int score Probabilité de détection variant de 1 à 100, 100 pour 100% fiable. Il est recommandé d'oublier les faces dont la valeur de score est inférieure à 50%.

Image non trouvée !Les coordonnées du rectangle entourant le visage sont les coordonnées dans le repère de la caméra, et non celui de l'écran. Les coordonnées dans ce repère pouvant aller de (-1000, 1000) à (1000, -1000)

 

Démarrer la détection

Maintenant que tout est prêt, il ne reste plus qu'à demander à lancer le traitement des visages:

camera.startFaceDetection();

Simple non ?

Des erreurs peuvent se produire:

IllegalArgumentException Dans le cas ou la détection de visages n'est pas supportée
RuntimeException Echec dans la méthode ou déjà lancée

 

Stopper la détection

Vous pouvez bien entendu stopper la détection des visages !

public final void stopFaceDetection ()

 

Informations complémentaires

setWhiteBalance(String), setFocusAreas(List), and setMeteringAreas(List) seront sans effet, la caméra passant tout en automatique durant la détection.

La détection de visage sera désactivée si vous utilisez l'autoFocus(AutoFocusCallback). Elle reprendra automatiquement à la fin de l'autofocus ou suite à un abandon autofocus (cancelAutoFocus()).

 

Exemple

Le code est assez important !

But:

Lancer une caméra (arrière car numCamera=0) pour qu'elle détecte des visages (FaceDetectionListener()).

Si au moins un visage est détecté, prise d'une photo de l'intru.

L'affichage du preview sera effectué sur la surfaceView1

 

De plus, sera affiché en superposé une seconde SurfaceView (surfaceView2) qui affiche des boîtes autour des visages détectés. Cette surface aura un fond transparent.

Avec le gros problème de conversion des coordonnées provenant de la caméra avec celui qu'utilise la SurfaceView1 (pour le preview) et 2 (pour afficher les boîtes. Conversion via la classe imbriquée FactoryBoxVisage) en prenant en compte la position de l'appareil entre les mains de l'utilisateur.

L'affichage des boîtes autour des visages se fait dans un thread pouvant dessiner sur la SurfaceView 2

D'autres méthodes pour les caméras sont mises en oeuvre ici.

 

Et le layout nommé activity_main.xml

Sera défini 2 SurfaceViews:

  • La première pour la caméra, elle affichera dedans son image preview.
  • La seconde, pour nous, superposée sur la première et en mode transparent pour afficher du texte, des boîtes ou autres informations. Ici, des boites autour des visages

Image non trouvée !Je fait exprès de dessiner la SurfaceView destinée à la caméra en dernier, alors qu'elle devrait être la première à être dessinée pour se retrouver sous celle qui nous est destinée.

C'est en effet par code que l'ordre d'affichage sera traité. Ce que je pense être préférable, cela évitera des erreurs suite à manipulation de ce fichier activity_main.xml via le "Graphical Layout" qui pourrait justement désordonner ces SurfaceViews !

Et strings.xml (très secondaire)

Image non trouvée !La sauvegarde est très basique ici (et mis en commentaire). De plus, des informations exif pourraient être ajoutées...

 

Pour finir avec le fichier AndroidManifest.xml