Créer une application de reconnaissance faciale avec OpenCV ·Cible ・ Pour le moment, découvrez comment installer et utiliser Android Studio (débutant) ・ Exécutez OpenCV sur Android ・ Les images prises avec l'appareil photo et les images enregistrées dans la galerie peuvent être utilisées.
J'ai essayé de créer une simple application Android de reconnaissance faciale en utilisant OpenCV https://qiita.com/Kuroakira/items/094ecb236da89949d702 Supplément sur la façon d'appeler la caméra avec intention (principalement pour le problème Xperia 2.1) https://gabu.hatenablog.com/entry/20101125/1290681748
Android Studio 3.5.3 OpenCV 4.2.0
Quant à la mise en œuvre, je vais l'écrire brièvement car je me réfère aux prédécesseurs ci-dessus.
Appuyez sur le bouton de l'appareil photo et de la galerie ↓ Obtenir des images de la caméra, de la galerie ↓ Convertir l'image acquise du format bitmap au format Mat ↓ Passer l'image au format Mat à OpenCV ↓ Acquiert les informations de reconnaissance faciale et les affiche à l'écran
Des informations de coordination comme celle-là sont sorties.
·caméra Si vous souhaitez acquérir l'image prise par la caméra en haute résolution, écrivez-la une fois dans l'URL et acquérez l'image à partir de l'URL. getImg = (Bitmap) data.getExtras (). get ("data"); ne peut obtenir que des images basse résolution pour les vignettes. (L'image pour la reconnaissance d'image est obtenue par getImg = (Bitmap) data.getExtras (). Get ("data");, mais cela semble gênant si le nombre de personnes augmente ou s'il s'agit d'une image de dessin)
MainActivity.java
getImg = (Bitmap) data.getExtras().get("data");
MainActivity.java
/**Abréviation**/
imageView.setImageURI(mImageUri);
/**Abréviation**/
/**
*Pour la photographie
*Exportez une fois la photo prise vers l'URL et stockez l'URL de destination dans mImageUri
*/
protected void takePhoto(){
String filename = System.currentTimeMillis() + ".jpg ";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,filename);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
mImageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, RESULT_CAMERA);
}
・ Division de classe uniquement pour la reconnaissance faciale Au départ, j'ai essayé de l'implémenter en le classant, mais j'ai abandonné car je ne savais pas comment classer les parties suivantes. (Vous ne pouvez pas accéder à res / raw avec la même description que MainActivity.java depuis une autre classe?)
MainActivity.java
File cascadeDir = getDir("cscade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
・ Acquisition d'images depuis ImageView En acquérant des images d'ImageVIew, dans le cas des caméras et des galeries, la mise en œuvre dans chaque cas devient inutile, il peut donc être possible de réduire le code.
・ Implémentation à Kotlin Je l'ai implémenté dans un Java bien écrit parce que c'était pour m'y habituer pour le moment, mais j'aimerais utiliser Kotlin lors du développement pour Android à l'avenir
MainActivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
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;
public class MainActivity extends AppCompatActivity {
private final static int RESULT_CAMERA = 1001; //Pour les caméras
private final static int REQUEST_GALLERY = 1000; //Pour la galerie
private Uri mImageUri; //Variable d'instance pour stocker l'URL de l'image
private Bitmap getImg = null; //Images prises depuis l'appareil photo ou la galerie
private ImageView imageView;//Déclaration de vue d'image
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image_view);//Associez d'abord ImageView à l'ID de la vue de mise en page
Button cameraButton = findViewById(R.id.camera_button);
cameraButton.setOnClickListener(new View.OnClickListener() {//Implémentation utilisant une classe interne normale
@Override
public void onClick(View v) {
takePhoto();
}
});
Button galleyButton = findViewById(R.id.gallery_button);
galleyButton.setOnClickListener(new View.OnClickListener() {//Implémentation utilisant une classe interne normale
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUEST_GALLERY);
}
});
}
//Je vais désormais coller la photo prise dans la vue Image.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == RESULT_CAMERA || requestCode == REQUEST_GALLERY) {
TextView textView = findViewById(R.id.text1); //Affichage(Afficher pour stocker le texte à afficher)
String outputText = ""; //Texte à afficher
MatOfRect faceRects; //Stocker les données de reconnaissance faciale
//Lors de la sélection d'une image de l'appareil photo
if (requestCode == RESULT_CAMERA) {
//Y compris les cas annulés
if (data.getExtras() == null) {
Log.d("debug", "cancel ?");
return;
} else {
imageView.setImageURI(mImageUri);
getImg = (Bitmap) data.getExtras().get("data");
}
}
//Lors de la sélection d'une image dans la galerie
if (requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) {
try {
InputStream in = getContentResolver().openInputStream(data.getData());
getImg = BitmapFactory.decodeStream(in);
in.close();
//Afficher l'image sélectionnée
imageView.setImageBitmap(getImg);
} catch (Exception e) {
//Quand il n'y a pas de fichier
textView.setText("Fichier non trouvé");
}
}
//Image collée sur imageView(Obtenu de la caméra, de la galerie)Reconnaissance faciale de
try {
faceRects = checkFaceExistence(getImg);
outputText = makeOutputText(faceRects);\
//Afficher l'image sélectionnée
imageView.setImageBitmap(getImg);
} catch (IOException e) {
outputText = "Erreur de reconnaissance faciale";
e.printStackTrace();
}
Toast.makeText(this,outputText,Toast.LENGTH_LONG).show();
textView.setText(outputText);
}
}
/**
*Pour la photographie
*Exportez une fois la photo prise vers l'URL et stockez l'URL de destination dans mImageUri
*/
protected void takePhoto(){
String filename = System.currentTimeMillis() + ".jpg ";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,filename);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
mImageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, RESULT_CAMERA);
}
/**
*Effectuer la reconnaissance faciale en fonction de l'image transmise
* @image bitmap param pour la reconnaissance faciale
* @texte de retour informations de reconnaissance faciale
* @throws IOException
*/
protected MatOfRect checkFaceExistence(Bitmap bitmap) throws IOException{
System.loadLibrary("opencv_java4");
//Données d'image envoyées(bitmap)Au format de tapis
Mat matImg = new Mat();
Utils.bitmapToMat(bitmap, matImg);
String text = ""; //Texte pour stocker les informations de reconnaissance faciale
//Génération d'une instance de classificateur en cascade pour la reconnaissance faciale(Exportez le fichier une fois et obtenez le chemin du fichier)
//Obtenez le fichier xml une fois stocké sous raw
InputStream inStream = getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
MatOfRect faceRects = new MatOfRect(); //Stocker les données de reconnaissance faciale
try {
//Définissez le chemin du fichier xml de sortie sur l'argument de Cascade Classfle
CascadeClassifier faceDetetcor = outputCascadeFile(inStream);
//Reconnaissance faciale en donnant des données d'image au classificateur en cascade
faceDetetcor.detectMultiScale(matImg, faceRects);
}
catch (IOException e){
Toast.makeText(this,"Échec de l'ouverture du fichier d'informations d'analyse.",Toast.LENGTH_SHORT).show();
}
return faceRects;
}
/**
*Importez une fois le classificateur openCV pré-préparé et rendez-le disponible pour l'exportation.
* @param inStream Données d'origine du classificateur
* @retour des données du classificateur faceDetector
* @throws IOException
*/
protected CascadeClassifier outputCascadeFile(InputStream inStream) throws IOException {
File cascadeDir = getDir("cscade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
//Sortir le fichier xml acquis dans un répertoire spécifique
FileOutputStream outputStream = new FileOutputStream(cascadeFile);
byte[] buf = new byte[2048];
int rdBytes;
while ((rdBytes = inStream.read(buf)) != -1) {
try {
outputStream.write(buf, 0, rdBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
//Définissez le chemin du fichier xml de sortie sur l'argument de Cascade Classfle
CascadeClassifier faceDetetcor = new CascadeClassifier((cascadeFile.getAbsolutePath()));
outputStream.close();
return faceDetetcor;
}
/**
*Création de texte pour la sortie
*Définissez les informations de coordonnées sur du texte en fonction des informations de reconnaissance faciale
* @param faceRects
* @return
*/
protected String makeOutputText(MatOfRect faceRects){
String text = "";
//Renvoie le résultat de la reconnaissance faciale sous forme de chaîne
if(faceRects.toArray().length > 0){
for(Rect face: faceRects.toArray()) {
text = "Largeur verticale du visage:" + face.height + "\n" +
"Largeur du visage" + face.width + "\n" +
"Position du visage(Coordonnée Y)" + face.y + "\n" +
"Position du visage(Coordonnée X)" + face.x;
}
}
else{
text = "Aucun visage n'a été détecté.";
}
return text;
}
Recommended Posts