Erstellen einer Gesichtserkennungs-App mit OpenCV ·Ziel ・ Erfahren Sie vorerst, wie Sie Android Studio (Anfänger) installieren und verwenden. ・ Führen Sie OpenCV unter Android aus ・ Es können sowohl mit der Kamera aufgenommene Bilder als auch in der Galerie gespeicherte Bilder verwendet werden.
Ich habe versucht, eine einfache Gesichtserkennungs-Android-Anwendung mit OpenCV zu erstellen https://qiita.com/Kuroakira/items/094ecb236da89949d702 Ergänzung zum absichtlichen Aufrufen der Kamera (hauptsächlich für das Xperia 2.1-Problem) https://gabu.hatenablog.com/entry/20101125/1290681748
Android Studio 3.5.3 OpenCV 4.2.0
Die Implementierung werde ich kurz schreiben, da ich mich auf die obigen Vorgänger beziehe.
Drücken Sie die Kamera- und Galerie-Taste ↓ Holen Sie sich Bilder von Kamera, Galerie ↓ Konvertieren Sie das erfasste Bild von der Bitmap in das Mat-Format ↓ Übergeben Sie das Bild im Mat-Format an OpenCV ↓ Erfasst Gesichtserkennungsinformationen und zeigt sie auf dem Bildschirm an
Solche Koordinateninformationen kamen heraus.
·Kamera Wenn Sie das von der Kamera aufgenommene Bild in hoher Auflösung erfassen möchten, schreiben Sie es einmal in die URL und erfassen Sie das Bild von der URL. getImg = (Bitmap) data.getExtras (). get ("data"); kann nur Bilder mit niedriger Auflösung für Miniaturansichten abrufen. (Das Bild für die Bilderkennung wird von getImg = (Bitmap) data.getExtras () erhalten. Get ("data"); es scheint jedoch unpraktisch zu sein, wenn die Anzahl der Personen zunimmt oder wenn es sich um ein Zeichenbild handelt.)
MainActivity.java
getImg = (Bitmap) data.getExtras().get("data");
MainActivity.java
/**Abkürzung**/
imageView.setImageURI(mImageUri);
/**Abkürzung**/
/**
*Für die Fotografie
*Exportieren Sie das aufgenommene Foto einmal in die URL und speichern Sie die Ziel-URL in 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);
}
・ Klassenteilung nur zur Gesichtserkennung Anfangs habe ich versucht, es durch Klassifizierung zu implementieren, aber ich habe aufgegeben, weil ich nicht wusste, wie ich die folgenden Teile klassifizieren soll. (Sie können nicht mit derselben Beschreibung wie MainActivity.java von einer anderen Klasse auf res / raw zugreifen?)
MainActivity.java
File cascadeDir = getDir("cscade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
・ Bildaufnahme von ImageView Durch das Erfassen von Bildern von ImageVIew wird bei Kameras und Galerien die Implementierung jeweils unnötig, sodass möglicherweise der Code reduziert werden kann.
・ Implementierung in Kotlin Ich habe es in einem gut geschriebenen Java implementiert, weil es sich vorerst daran gewöhnen sollte, aber ich würde Kotlin gerne bei der zukünftigen Entwicklung für Android verwenden
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; //Für Kameras
private final static int REQUEST_GALLERY = 1000; //Für die Galerie
private Uri mImageUri; //Instanzvariable zum Speichern der URL des Bildes
private Bitmap getImg = null; //Bilder von der Kamera oder Galerie aufgenommen
private ImageView imageView;//Deklaration der Bildansicht
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image_view);//Verknüpfen Sie zuerst ImageView mit der Layoutansicht-ID
Button cameraButton = findViewById(R.id.camera_button);
cameraButton.setOnClickListener(new View.OnClickListener() {//Implementierung mit einer normalen inneren Klasse
@Override
public void onClick(View v) {
takePhoto();
}
});
Button galleyButton = findViewById(R.id.gallery_button);
galleyButton.setOnClickListener(new View.OnClickListener() {//Implementierung mit einer normalen inneren Klasse
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUEST_GALLERY);
}
});
}
//Ich werde das in der Bildansicht aufgenommene Foto von nun an einfügen.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == RESULT_CAMERA || requestCode == REQUEST_GALLERY) {
TextView textView = findViewById(R.id.text1); //Textvorschau(Anzeigen, um den anzuzeigenden Text zu speichern)
String outputText = ""; //Anzuzeigender Text
MatOfRect faceRects; //Speichern Sie Gesichtserkennungsdaten
//Bei der Auswahl eines Bildes von der Kamera
if (requestCode == RESULT_CAMERA) {
//Einschließlich stornierter Fälle
if (data.getExtras() == null) {
Log.d("debug", "cancel ?");
return;
} else {
imageView.setImageURI(mImageUri);
getImg = (Bitmap) data.getExtras().get("data");
}
}
//Bei der Auswahl eines Bildes aus der Galerie
if (requestCode == REQUEST_GALLERY && resultCode == RESULT_OK) {
try {
InputStream in = getContentResolver().openInputStream(data.getData());
getImg = BitmapFactory.decodeStream(in);
in.close();
//Zeigen Sie das ausgewählte Bild an
imageView.setImageBitmap(getImg);
} catch (Exception e) {
//Wenn keine Datei vorhanden ist
textView.setText("Datei nicht gefunden");
}
}
//Bild in imageView eingefügt(Erhalten von Kamera, Galerie)Gesichtserkennung von
try {
faceRects = checkFaceExistence(getImg);
outputText = makeOutputText(faceRects);\
//Zeigen Sie das ausgewählte Bild an
imageView.setImageBitmap(getImg);
} catch (IOException e) {
outputText = "Gesichtserkennungsfehler";
e.printStackTrace();
}
Toast.makeText(this,outputText,Toast.LENGTH_LONG).show();
textView.setText(outputText);
}
}
/**
*Für die Fotografie
*Exportieren Sie das aufgenommene Foto einmal in die URL und speichern Sie die Ziel-URL in 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);
}
/**
*Führen Sie eine Gesichtserkennung basierend auf dem übergebenen Bild durch
* @param Bitmap Bild zur Gesichtserkennung
* @Rückgabetext Gesichtserkennungsinformationen
* @throws IOException
*/
protected MatOfRect checkFaceExistence(Bitmap bitmap) throws IOException{
System.loadLibrary("opencv_java4");
//Bilddaten gesendet(bitmap)Zum Mattenformat
Mat matImg = new Mat();
Utils.bitmapToMat(bitmap, matImg);
String text = ""; //Text zum Speichern von Gesichtserkennungsinformationen
//Generieren einer Kaskadenklassifikatorinstanz zur Gesichtserkennung(Exportieren Sie die Datei einmal und erhalten Sie den Dateipfad)
//Holen Sie sich die XML-Datei, sobald sie unter raw gespeichert ist
InputStream inStream = getResources().openRawResource(R.raw.haarcascade_frontalface_alt);
MatOfRect faceRects = new MatOfRect(); //Speichern Sie Gesichtserkennungsdaten
try {
//Legen Sie den Pfad der XML-Ausgabedatei auf das Argument von Cascade Classfle fest
CascadeClassifier faceDetetcor = outputCascadeFile(inStream);
//Gesichtserkennung durch Übergabe von Bilddaten an den Kaskadenklassifizierer
faceDetetcor.detectMultiScale(matImg, faceRects);
}
catch (IOException e){
Toast.makeText(this,"Fehler beim Öffnen der Analyseinformationsdatei.",Toast.LENGTH_SHORT).show();
}
return faceRects;
}
/**
*Importieren Sie den vorbereiteten openCV-Klassifikator einmal und stellen Sie ihn für den Export zur Verfügung.
* @param inStream Originaldaten des Klassifikators
* @Rückgabe der FaceDetector-Klassifikatordaten
* @throws IOException
*/
protected CascadeClassifier outputCascadeFile(InputStream inStream) throws IOException {
File cascadeDir = getDir("cscade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
//Geben Sie die erfasste XML-Datei in ein bestimmtes Verzeichnis aus
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();
}
}
//Legen Sie den Pfad der XML-Ausgabedatei auf das Argument von Cascade Classfle fest
CascadeClassifier faceDetetcor = new CascadeClassifier((cascadeFile.getAbsolutePath()));
outputStream.close();
return faceDetetcor;
}
/**
*Texterstellung für die Ausgabe
*Stellen Sie die Koordinateninformationen basierend auf den Gesichtserkennungsinformationen auf Text ein
* @param faceRects
* @return
*/
protected String makeOutputText(MatOfRect faceRects){
String text = "";
//Geben Sie das Ergebnis der Gesichtserkennung als Zeichenfolge zurück
if(faceRects.toArray().length > 0){
for(Rect face: faceRects.toArray()) {
text = "Vertikale Breite des Gesichts:" + face.height + "\n" +
"Gesichtsbreite" + face.width + "\n" +
"Gesichtsposition(Y-Koordinate)" + face.y + "\n" +
"Gesichtsposition(X-Koordinate)" + face.x;
}
}
else{
text = "Es wurde kein Gesicht erkannt.";
}
return text;
}
Recommended Posts