Im Verlauf des letzten Jahres habe ich mich mit einigen Themen nach 20,30 Jahren wieder beschäftigt. Eines mit dem ich mich nie beschäftigt habe, ist Mustererkennung. Und ich hätte es vermutlich auch nie getan, wenn es das F1-Photo-Archiv nicht erfordert hätte. Na ja,erfordert ist übetrieben, es war eher das ich mir Arbeit (und vor allem Zeit) ersparen wollte.
Es geht immer noch um das "Taggen", sprich den Dateinamen. Nach dem Downloaden ist bei jedem Photo das Jahr, das Rennen und der Fahrername im Dateinamen vorhanden. Dann vervollständigt die Software aus der F1-Datenbank heraus den Namen mit der Bezeichnung des Teams, des Wagens und dem Motor. Wenn auf einem Photo kein Auto, sondern nur Personen zu sehen sind, braucht das Archiv im Namen der Datei nicht alle Attribute. Im Gegenteil, die überflüssigen Attribute (Wagen, Motor) bringen bei der Suche nur unerwünschte Resultate mit sich.
Das manuelle Korrigieren wäre Lebenszeitverschwendung. Eine Muster - genauer Gesichterkennung als JAVA Library - das muss es doch geben dachte ich. Na ja, im Prinzip war das richtig. Allerdings war es diesmal deutlich aufwändiger das ganze zum Laufen zu bringen. Und ich bin dabei doch wieder an einem "alten" Thema vorbei gekommen...
OpenCV (englische Abk. für Open Source Computer Vision Library[3]) ist eine freie Programmbibliothek mit Algorithmen für die Bildverarbeitung und Computer Vision. Sie ist für die Programmiersprachen C, C++, Python und Java geschrieben und steht als freie Software unter den Bedingungen der Apache 2 License. Die Entwicklung der Bibliothek wurde von Intel initiiert und bis 2013 von Willow Garage gepflegt. Nach deren Auflösung wurde sie von Itseez fortgeführt, das mittlerweile von Intel übernommen wurde.
OpenCV besteht aus Modulen für verschiedene Anwendungsfelder, u.a:
Um es kurz zu machen, das compilieren lief äußert zäh, die Standard Distribution liess sich nicht ohne weiteres compilieren.
Ich musste Homebrew installieren, aber die Installation scheiterte andauernd. Ich musste mich mit Homebrew beschäftigen und letztendlich dann ein anderes
opencv.rb File (Konfigurationsdatei für Homebrew) aus GitHib runterladen, an eine ganz bestimmte Stelle in der lolaklen Homebrew Installation
kopieren und dann endlich, nach Tagen, unter Ignorieren von diversen Fehlermeldungen liess sich OpenCV für meinen Mac compilieren. Um ehrlich zu sein, ich weiss nicht ob ich das Ding auf Anhieb nochmal installieren könnte.
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } die C++ Library erst verfügbar wird
faceDetector.load("/Users/eathanassiou/haarcascade_frontalface_alt.xml"); die vortrainierte Gesichtserkennung geladen wird.
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
public class Main {
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); };
...
if (faceDetected(File))
{ ...
}
...
public static boolean faceDetected(String File)
{
CascadeClassifier faceDetector = new CascadeClassifier();
faceDetector.load("/Users/eathanassiou/haarcascade_frontalface_alt.xml");
Mat image = Imgcodecs.imread(File); // Reading the input image
MatOfRect faceDetections = new MatOfRect(); // Detecting faces
faceDetector.detectMultiScale(image, faceDetections);
if (faceDetections.toArray().length != 0)
return true;
return false;
}
}
In MatOfRect faceDetections stehen die Koordinaten von Rechtecken, welche das Gesicht markieren.
Beim genauen Hinsehen erkennt man,dass das System Gesicher von vorne erkennt, aber keine Seitenansichten. Das kan man mit einem
anderen xml File bewerkstelligen, mit haarcascade_profileface.xml . Es gibt leider kein vortrainiertes set, dass beides
kann.
...
CascadeClassifier faceDetectorLeft = new CascadeClassifier();
faceDetectorLeft.load("/Users/eathanassiou/haarcascade_profileface.xml");
Mat imageLeft = Imgcodecs.imread(File); // Reading the input image
MatOfRect faceDetectionsLeft = new MatOfRect(); // Detecting faces
faceDetectorLeft.detectMultiScale(imageLeft, faceDetectionsLeft);
if (faceDetectionsLeft.toArray().length != 0)
return true;
...
Bald merkt man dann, dass man mit haarcascade_profileface.xml nur linksseitige Profile erkennt. Ist in voller
Absicht so, es ist nur mit linksseitgen Profilen trainiert worden.
Trainieren kostet Zeit, Rechnerkapazitäten und Geld. Die Entwickler von OpenCV haben gemerkt, das man das Bild nur einmal "Flippen"
sprich spiegelbildlich drehen muss, und dann wird die Erkennung mit dem haarcascade_profileface.xml die rechtsseitigen
Profile erkennen. Dazu gibt es opencv.core eine Methode.
...
CascadeClassifier faceDetectorRight = new CascadeClassifier();
faceDetectorRight.load("/Users/eathanassiou/haarcascade_profileface.xml");
Mat src = Imgcodecs.imread(File); //Reading the Image from the file and storing it in to a Matrix object
Mat flipped = new Mat(); //Creating an empty matrix to store the result
Core.flip(src, flipped, 1); // Flip the image
MatOfRect faceDetectionsRight = new MatOfRect(); // Detecting faces
faceDetectorRight.detectMultiScale(flipped, faceDetectionsRight);
if (faceDetectionsRight.toArray().length != 0)
return true;
...
haarcascade*.xml Dateien, aber das hat jetzt nicht die Top Priorität ...