[JAVA] J'ai essayé de créer une simple application Android de reconnaissance faciale en utilisant OpenCV

introduction

La technologie de reconnaissance faciale elle-même existe depuis longtemps, mais récemment, des applications pour smartphone utilisant la reconnaissance faciale telles que Snow sont apparues et elles sont de plus en plus familières. Comment est-ce arrivé avant? Cela m'intéresse aussi, et si je prends moi-même une photo de visage, j'aimerais créer une application qui remplace le visage de la personne sur la photo par un autre! J'ai pensé. Cependant, lorsque j'ai recherché en ligne la reconnaissance faciale et l'analyse d'image, beaucoup d'entre eux se sont concentrés sur l'apprentissage automatique, et j'ai été submergé par la difficulté ... Cependant, lorsque j'ai créé une partie de la fonction de reconnaissance faciale en utilisant OpenCV avec une application Android cette fois, c'était plus facile que ce que j'imaginais, alors j'aimerais la présenter. Ce que j'ai trouvé en le faisant, c'est qu'il était plus difficile d'implémenter la fonction de caméra que d'utiliser OpenCV pour reconnaître le visage à partir de l'image.

Qu'est-ce qu'OpenCV en premier lieu?

OpenCV (Open Source Computer Vision Library) est une bibliothèque open source pour le traitement de vidéos et d'images. Pour OpenCV, cet article a été utile.

Ce que je voulais faire

Utilisez OpenCV pour déterminer si un visage est présent sur une photo prise avec la fonction appareil photo Android

  1. Effectuez un apprentissage automatique pour acquérir des fonctionnalités
  2. Implémentez la fonction de caméra dans l'application Android
  3. Mise en œuvre de la fonction de reconnaissance faciale pour les données d'image prises avec un appareil photo ← Pièce à introduire cette fois
  4. Traitement d'image et jugement à l'aide des résultats de reconnaissance (taille du visage, informations de position)

Ce qui est utilisé pour réaliser la fonction de reconnaissance faciale avec OpenCV

OpenCV fournit des interfaces pour C, C ++, Python et Java. Lors de l'intégration dans une application pour smartphone, des SDK sont préparés pour iOS et Android, et en important ce SDK dans le projet, vous pouvez facilement préparer un environnement pour utiliser OpenCV. De plus, dans la reconnaissance faciale, le résultat de l'apprentissage automatique est nécessaire pour juger du «visage», mais il y en a déjà préparé par OpenCV. Le résultat de cet apprentissage automatique * est inclus dans le package SDK.

Environnement d'utilisation / bibliothèque

Flux de processus

Chargement de la bibliothèque OpenCV

FaceClassifier.java



  //Chargement de la bibliothèque OpenCV
  static {
    System.loadLibrary("opencv_java3"); 
  }

Convertir les données d'image au format Mat

--Convertissez les données d'image au format OpenCV Mat. --Dans l'exemple, nous avons converti du format Bitmap au format Mat.

FaceClassifier.java



    //Convertir les données d'image (conversion de fichier Bitmap Mat)
    Mat matImg = new Mat();
    Utils.bitmapToMat(image,matImg); 

Création d'une instance Cascade Classifier pour la reconnaissance faciale

--Utilisez "haarcascade_frontalface_alt.xml" qui est une cascade de visages. Étant donné que le fichier de quantité de fonctionnalités est également téléchargé lorsque le SDK est téléchargé, stockez le fichier cible sous res / raw du projet Android. ――Je suis resté coincé ici pendant un moment ...

FaceClassifier.java



    //Générer une instance de classificateur en cascade qui effectue la reconnaissance faciale (écrivez le fichier une fois et obtenez le chemin du fichier)
    //Obtenez le fichier xml une fois stocké sous raw
    InputStream inStream = this.activity.getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
    File cascadeDir = this.activity.getDir("cascade", Context.MODE_PRIVATE);
    File cascadeFile = new File(cascadeDir, "haarcascade_frontalface_alt.xml");
    //Sortir le fichier xml acquis dans un répertoire spécifique
    FileOutputStream outStream = new FileOutputStream(cascadeFile);
    byte[] buf = new byte[2048];
    int rdBytes;
    while ((rdBytes = inStream.read(buf)) != -1) {
      outStream.write(buf, 0, rdBytes);
    }
    outStream.close();
    inStream.close();
    //Utilisez le chemin du fichier xml de sortie comme argument de CascadeClassifier
    CascadeClassifier faceDetetcor = new CascadeClassifier(cascadeFile.getAbsolutePath());
    //Une fois l'instance CascadeClassifier créée, le fichier de sortie est inutile, supprimez-le.
    if (faceDetetcor.empty()) {
      faceDetetcor = null;
    } else {
      cascadeDir.delete();
      cascadeFile.delete();
    }

Reconnaissance faciale en donnant des données d'image à Cascade Classifier

FaceClassifier.java



    //Reconnaissance faciale en donnant des données d'image au classificateur en cascade
    MatOfRect faceRects = new MatOfRect();
    faceDetetcor.detectMultiScale(matImg, faceRects);

Obtenez le nombre de visages reconnus dans l'image et la position des visages à partir du résultat stocké dans l'occurrence MatOfRect.

FaceClassifier.java



    //Confirmation des résultats de la reconnaissance faciale
    Log.i(TAG ,"Nombre de visages reconnus:" + faceRects.toArray().length); 
    if (faceRects.toArray().length > 0) {
      for (Rect face : faceRects.toArray()) {
        Log.i(TAG ,"Largeur verticale du visage" + face.height);
        Log.i(TAG ,"Largeur du visage" + face.width);
        Log.i(TAG ,"Position du visage (coordonnée Y)" + face.y);
        Log.i(TAG ,"Position de la face (coordonnée X)" + face.x);
      }
      return true;
    } else {
      Log.i(TAG ,"Aucun visage n'a été détecté");
      return false;
    }

Code source

FaceClassifier.java



import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.objdetect.CascadeClassifier;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class FaceClassifier {
  //Chargement de la bibliothèque OpenCV
  static {
    System.loadLibrary("opencv_java3"); 
  }
  private Activity activity;
  public FaceClassifier (Activity activity) {
    this.activity = activity;
  }
  public boolean checkFaceExistence (Bitmap image) throws IOException {
    //Convertir les données d'image (conversion de fichier Bitmap Mat)
    Mat matImg = new Mat();
    Utils.bitmapToMat(image,matImg); 
    //Générer une instance de classificateur en cascade qui effectue la reconnaissance faciale (écrivez le fichier une fois et obtenez le chemin du fichier)
    //Obtenez le fichier xml une fois stocké sous raw
    InputStream inStream = this.activity.getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
    File cascadeDir = this.activity.getDir("cascade", Context.MODE_PRIVATE);
    File cascadeFile = new File(cascadeDir, "haarcascade_frontalface_alt.xml");
    //Sortir le fichier xml acquis dans un répertoire spécifique
    FileOutputStream outStream = new FileOutputStream(cascadeFile);
    byte[] buf = new byte[2048];
    int rdBytes;
    while ((rdBytes = inStream.read(buf)) != -1) {
      outStream.write(buf, 0, rdBytes);
    }
    outStream.close();
    inStream.close();
    //Utilisez le chemin du fichier xml de sortie comme argument de CascadeClassifier
    CascadeClassifier faceDetetcor = new CascadeClassifier(cascadeFile.getAbsolutePath());
    //Une fois l'instance CascadeClassifier créée, le fichier de sortie est inutile, supprimez-le.
    if (faceDetetcor.empty()) {
      faceDetetcor = null;
    } else {
      cascadeDir.delete();
      cascadeFile.delete();
    }
    //Reconnaissance faciale en donnant des données d'image au classificateur en cascade
    MatOfRect faceRects = new MatOfRect();
    faceDetetcor.detectMultiScale(matImg, faceRects);
    //Confirmation des résultats de la reconnaissance faciale
    Log.i(TAG ,"Nombre de visages reconnus:" + faceRects.toArray().length); 
    if (faceRects.toArray().length > 0) {
      for (Rect face : faceRects.toArray()) {
        Log.i(TAG ,"Largeur verticale du visage" + face.height);
        Log.i(TAG ,"Largeur du visage" + face.width);
        Log.i(TAG ,"Position du visage (coordonnée Y)" + face.y);
        Log.i(TAG ,"Position de la face (coordonnée X)" + face.x);
      }
      return true;
    } else {
      Log.i(TAG ,"Aucun visage n'a été détecté");
      return false;
    }
  }
}

Résumé

Le SDK OpenCV est beaucoup plus facile à utiliser, il est donc plus facile que vous ne le pensez. Si vous souhaitez reconnaître autre chose que le visage, vous devez vérifier l'apprentissage automatique à l'aide d'OpenCV, mais comme il existe divers résultats publiés (fichiers XML) de l'apprentissage automatique pour OpenCV, une fois Il est recommandé de vérifier. Si vous souhaitez créer une application qui utilise la technologie de reconnaissance faciale comme moi, veuillez utiliser OpenCV.

Recommended Posts

J'ai essayé de créer une simple application Android de reconnaissance faciale en utilisant OpenCV
J'ai essayé de créer une application simple en utilisant Dockder + Rails Scaffold
Un débutant Java a essayé de créer une application Web simple à l'aide de Spring Boot
J'ai essayé de créer une application de conversation en Java à l'aide de l'IA «A3RT»
J'ai essayé de créer une application cartographique simple dans Android Studio
[Unity] J'ai essayé de créer un plug-in natif UniNWPathMonitor en utilisant NWPathMonitor
J'ai essayé de créer une application Android avec MVC maintenant (Java)
java j'ai essayé de casser un simple bloc
[iOS] J'ai essayé de créer une application de traitement de type insta avec Swift
J'ai essayé d'implémenter un serveur en utilisant Netty
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part3 ~ Practice ~
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (inachevé)
[Android] J'ai créé un écran de liste de matériaux avec ListView + Bottom Sheet
J'ai essayé d'utiliser une connexion à une base de données dans le développement Android
J'ai essayé de créer une fonction de connexion avec Java
[Introduction au développement d'applications Android] Faisons un compteur
J'ai essayé de faire un jeu simple avec Javafx ① "Trouvons le jeu du bonheur" (version inachevée ②)
J'ai essayé de faire une demande en 3 mois d'inexpérimenté
J'ai essayé d'ajouter une ligne de séparation à TabLayout sur Android
J'ai essayé de moderniser une application Java EE avec OpenShift.
J'ai essayé d'implémenter une application web pleine de bugs avec Kotlin
J'ai créé un client RESAS-API en Java
Essayez d'introduire OpenCV dans l'application Android
Essayez de faire un simple rappel
J'ai essayé de convertir l'exemple d'application en microservice selon l'idée du livre "Microservice Architecture".
[Android] J'ai essayé d'utiliser la disposition du coordinateur.
J'ai essayé d'en faire une URL arbitraire en utilisant l'imbrication de routage
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "J'ai essayé de créer une fenêtre avec Bootstrap 3"
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part2 ~ Façon basique d'écrire Dash ~
Après avoir appris Progate, j'ai essayé de créer une application SNS en utilisant Rails dans l'environnement local
Je souhaite développer une application web!
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
Application de reconnaissance faciale avec OpenCV + Android Studio
J'ai essayé de créer une classe parent d'objet de valeur dans Ruby
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
J'ai essayé de créer mon propre guide de transfert en utilisant OpenTrip Planner et GTFS
J'ai créé un bot de transaction d'arbitrage de monnaie virtuelle et essayé de gagner de l'argent
J'ai essayé de créer une application d'apprentissage automatique avec Dash (+ Docker) part1 ~ Construction de l'environnement et vérification du fonctionnement ~
J'ai essayé de créer un exemple de programme en utilisant le problème du spécialiste des bases de données dans la conception pilotée par domaine
En utilisant la fonction de détection de visage de Watson Visual Recognition, j'ai essayé de transformer une image corporelle entière d'une personne en une image de la partie du visage uniquement.
[LINE @] J'ai essayé de créer un BOT de conversion de calendrier occidental de calendrier japonais [API de messagerie]
J'ai essayé de faire une authentification de base avec Java
J'ai essayé d'implémenter une fonction équivalente à Felica Lite avec HCE-F d'Android
Une histoire où j'ai essayé de faire une vidéo en liant Traitement et Resolume
J'ai essayé de développer un outil de gestion des effectifs
Je l'ai fait en Java pour toujours rendre (a == 1 && a == 2 && a == 3) vrai
J'ai essayé de développer un site Web pour étudier DUO3.0.
[Android] J'ai quitté SQLite et essayé d'utiliser Realm
[Java] J'ai essayé de me connecter en utilisant le pool de connexion avec Servlet (tomcat) & MySQL & Java
Je voulais que (a == 1 && a == 2 && a == 3) vrai en Java
J'ai essayé de créer une application de clonage LINE
J'ai essayé de cloner une application Web pleine de bugs avec Spring Boot
[Azure] J'ai essayé de créer une application Java pour la création d'applications Web gratuites - [Débutant]
J'ai essayé de développer une application en 2 langues