knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(eigenfaces)
In diesem Paket wird die Hauptkomponentenanalyse auf Bilder von Gesichtern aus dem Olivetti Faces Datensatz angewendet. Das Paket stellt folgende Funktionen bereit:
Darüber hinaus existieren einige nebensächliche Userfunktionen, die hier nicht aufgelistet wurden. Die wichtigsten Funktionen sind fett markiert und werden im folgenden exemplarisch vorgestellt.
Die Idee der maschinelle Gesichtserkennung mit der Technik der Hauptkomponentenanalyse stammt von Turk und Pentland, 1991. Sie haben ausgenutzt, dass menschliche Gesichter gewisse Ähnlichkeiten aufweisen. Dies ermöglicht eine Darstellung von Gesichtern auf einem niedrigdimensonalen Raum, mithilfe der Eigenvektoren eines Datensatzes von zahlreichen Gesichtern. Die Eigenvektoren werden in diesem Zusammenhang Eigenfaces genannt.
Mithilfe der Hauptkomponentenanalyse will man ganz allgemein die Dimensionalität eines Datensatzes, der aus vielen Variablen, besteht reduzieren. Dabei soll jedoch die im Datensatz vorhandene Variation bis zu einem maximalen Ausmaß erhalten bleibt. Eine statistische Verteilung in einem Datensatz ist deswegen notwendig für eine erfolgreiche Anwendung. Da Gesichter charakteristische Merkmale aufweisen, lässt sich das Verfahren sehr gut darauf anwenden.
Um die Hauptkomponentenanalyse durchführen zu können, müssen die Gesichter normalisiert werden. Danach wird das Durchschnittsgesicht $\bar{X}$ aus dem kompletten Datenset von $x_i$ Gesichtern berechnet.
$\begin{equation} \tag{1} \bar{X} = \frac{1}{n}\sum_{i=1}^{n} x_i \end{equation}$
Im nächsten Schritt wird das erhaltene Durchschnittsgesicht von jedem Gesicht abgezogen.
$\begin{equation} \tag{2} B = \sum_{i=1}^{n} x_i - \bar{X} \end{equation}$
Dadurch erhält man eine Matrix B, die alle Abweichungen zum Durchschnittsgesichts wiedergibt. Aus der Kovarianzmatrix C
$\begin{equation} \tag{3} C= B^t B \end{equation}$
lassen sich die Eigenvektoren bzw. Eigengesichter berechnen. Nach der Ausführung wird auffallen, dass die ersten Eigengesichter die Lichtverhältnisse wiedergeben, die nächsten die Frisur oder Mimik. Eigengesichter bilden somit die Grundstruktur, um ein Gesicht zu rekonstruieren. Diese ist für jeden Datensatz gleich. Dabei spielt es keine Rolle, ob es sich dabei um einen Datensatz von Gesichtern oder beispielsweise um einen Datensatz von handgeschriebenen Zahlen, wie in dem MNIST Datensatz handet.
In unserem Paket verwenden wir den Olivetti Faces Datensatz. Das Paket lässt sich aber auch problemlos auf den berühmten MNIST Datensatz anwenden. Im Paket werden beide Datensätze inklusive Class-Labels mitgeliefert.
Der Olivetti Faces Datensatz wurde zwischen April 1992 und April 1994 erstellt und umfasst 400 Bilder von Gesichtern. Insgesamt wurden 40 verschiedene Personen zu 10 verschiedenen Zeiten mit varrierendem Lichteinfall, Gesichtsausdrücken, und Gesichtsdetails fotografiert. Alle Aufnahmen haben einen schwarzen Hintergrund und sind in schwarz-weiß fotografiert. Die Größe der jeweiligen Aufnahmen beträgt 64 * 64 pixel.
Die Personen sind durchnummeriert von 1 bis 40.
Weitere Informationen erhält man mit ?Olivetti.
Der Datensatz lässt sich mit load_imageset_ef(path, imgDim) importieren. Mittels print Befehl z.B. td[[1]] erhält man, wie unten zu sehen ist, das erste Bild der ersten Person des Datensets.
``` {r eval=FALSE} library(eigenfaces) olivetti <- system.file("extdata","olivetti_X.csv",package="eigenfaces") td <- load_imageset_ef(olivetti, c(64,64)) td[[1]]
``` {r echo=FALSE, out.width = '20%', fig.align="center"}
library(knitr)
olivetti <- system.file("extdata","td1.png",package="eigenfaces")
include_graphics(olivetti)
Um ein Gefühl für den Olivetti Faces Datensatz zu vermitteln sind im folgenden die ersten 40 Bilder des Datensatzes zu sehen. Die Spalten sind nach Personen und die Reihen sind nach den 10 unterschiedlichen Fotos der Personen sortiert.
``` {r eval=FALSE} par(mfrow=c(4,10),pin=c(1,1),mar=c(0.4,0.4,0.4,0.4)) for (i in 1:4) { for(j in 1:10){ idx <- (i-1)*10 + j print(td[[idx]]) } }
``` {r echo=FALSE, out.width = '90%', fig.align="center"}
library(knitr)
olivetti <- system.file("extdata","Olivettidata2.png",package="eigenfaces")
include_graphics(olivetti)
Um die ersten n Eigengesichter zu erhalten, wendet man nun die Hauptkomponentenanalyse auf den Datensatz an.
Zunächst sei einmal das Durchschnittsgesicht dargestllt. Dieses erhält man mit der Funktion avg_face(td) (siehe ?avg_face).
avg_face(td)
``` {r echo=FALSE,out.width = '20%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","avgface.png",package="eigenfaces")
include_graphics(olivetti)
Die Funktion `get_eigenfaces(td, nfaces = 15, quick = FALSE)` berechnet die ersten `nfaces` Eigengesichter des Datensatzes. Eine einfache Ausgabe in der Plot Pane ist wieder mittels `ef[[1]]` möglich. Alternativ lassen sich wie folgt die ersten 9 Eigengesichter darstellen. ```r ef <- get_eigenfaces(td, 9) par(mfrow=c(3,3),pin=c(1,1),mar=c(0.4,0.4,0.4,0.4)) for (i in 1:9) { print(ef[[i]]) }
``` {r echo=FALSE,out.width = '50%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","eigenfaces.png",package="eigenfaces")
include_graphics(olivetti)
## Darstellung von Bildern im Datensatz mit reduzierter Anzahl an Hauptkomponenten Eine weitere hilfreiche Anwendung im Zusammenhang mit großen Datensätzen ist die Rekonstruktion einzelner Bilder mit einer reduzierten Anzahl an Eigenvektoren. Mit den Eigengesichtern lassen sich dementsprechend die ursprünglichen Gesichter, aber auch komplett neue Gesichter rekonstruieren. Wählt man ein (neues) Gesicht aus und projiziert es auf die Hauptkomponenten, so lässt sich das Gesicht mittels des Durchschnittsgesicht und der Linearkombination von Eigenvektoren rekonstruieren. Die dazugehörige Funktion heißt `FSP(img, eigenfaces, avgFace, showCoefficients = FALSE)` (siehe `?FSP`). ```r par(mfrow=c(1,5),pin=c(1,1),mar=c(0.4,0.4,0.4,0.4)) ef <- get_eigenfaces(td, 1) FSP(td[[5]], ef, avg_face(normalize(td))) ef <- get_eigenfaces(td, 5) FSP(td[[5]], ef, avg_face(normalize(td))) ef <- get_eigenfaces(td, 25) FSP(td[[5]], ef, avg_face(normalize(td))) ef <- get_eigenfaces(td, 100) FSP(td[[5]], ef, avg_face(normalize(td))) ef <- get_eigenfaces(td, 400) FSP(td[[5]], ef, avg_face(normalize(td)))
``` {r echo=FALSE, out.width = '85%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","FSP_td5.png",package="eigenfaces")
include_graphics(olivetti)
In der obigen Grafik ist die Rekonstruktion mit 1, 5, 25, 100 und 400 Eigengesichtern (v.l.n.r.) zu sehen. Hier wurde das fünfte Bild der ersten Person aus dem Datensatz verwendet. Um ein weiteres Beispiel zu liefern: Das dritte Bild der vierten Person lässt sich mit `FSP(td[[33]], ef, avg_face(normalize(td)))` analog rekonstruieren: ``` {r echo=FALSE, out.width = '85%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","FSP_td33.png",package="eigenfaces") include_graphics(olivetti)
Das Prinzip der Gesichtserkennung bzw. Klassifizierung mittels Hauptkomponentenanalyse lässt sich am einfachsten anhand eines kleines Beispieles erklären. Im folgenden Code-Abschnitt wurden sämtliche Bilder auf die ersten beiden Eigengesichter ef1 und ef2 projiziert. Im Plot ist hierbei zu erkennen, dass sich einzelne farbige Gruppen bilden.
# Loading of classes classes <- load_classes_ef(system.file("extdata","olivetti_y.csv", package="eigenfaces")) # Initialization data <- data.frame(matrix(ncol=3,nrow=5, dimnames=list(NULL, c("ef1_x", "ef2_y", "class")))) # Fill with projections and corresponding classes ef1 <- as.vector(ef[[1]]) ef2 <- as.vector(ef[[2]]) for (i in 1:length(td)) { data[i,] <- c(as.vector(td[[i]])%*%ef1,as.vector(td[[i]])%*%ef2,classes[[1]][i]) } # Scatterplot ggplot(data, aes(x=ef1_x, y=ef2_y, color=class)) + geom_point(shape=19, size=1.2) + scale_color_gradientn(colours = rainbow(100))
``` {r echo=FALSE, out.width = '90%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","projection_rainbow.png",package="eigenfaces")
include_graphics(olivetti)
Wie bereits erwähnt, sieht man, dass sie sich kleinere Gruppierungen bilden. Für einige Klassen bilden sich dementsprechend regelrechte Cluster in denen nur Bilder der selben Klasse anzufinden sind. Ein sehr gutes Beispiel sind die rosanen Projektionen (um `ef1_x = -250` und `ef2_y = 0`). Jedoch geht es bei dem Plot weniger, um die einzelnen Punkte und mehr um das große Ganze. Es ist zu erkennen, dass allein schon eine Projektion auf die ersten beiden Eigenvektoren zu einem Clustering der Bilder führt. Würde man nun ein unbekanntes Gesicht auf diese zwei Eigenvektoren projezieren, und würde sich der Punkt im Bereich des rosanen Clusters befinden, so wäre es ein einfach diesem mit k-Nearest Neighbor Algortihmen o.ä. eine Klasse zuzuordnen. Darauf basiert die Idee der Gesichtserkennung mittels Hauptkomponentenanalyse in diesem Kontext. Abschließend sei noch gesagt, dass ein noch besseres Clustering mit dem MNIST Datensatz zu erreichen ist. Das Austesten wird empfohlen. Das Einlesen des Datensatzes erfolgt analog mittels `mnist <- system.file("extdata","mnist_X.csv",package="eigenfaces"); td <- load_imageset_ef(mnist, c(28,28))`. Um nach diesem kleinen Exkurs wieder zu unserer konkreten Anwendung zu kommen: In unserem Paket ist es mittels der Funktion `classification_ef(img, td, nclosest = 3, neigenfaces = 15, quick = FALSE)` (siehe `?classification_ef`) möglich die `nclosest` Bilder, die dieser Person ähnlich sehen, auszugeben. `FSP`(kurz für: Feature Space Projection) basiert dabei auf dem euklidischen Abstand. Im folgenden wurde eine Klassifikation für das bereits bekannte dritte Bild der vierten Person durchgeführt. Es sind die drei nächsten Nachbarn zu sehen. ```r olivetti <- system.file("extdata","olivetti_X.csv",package="eigenfaces") td <- load_imageset_ef(olivetti, c(64,64)) img <- td[[33]] closest <- classification_ef(img, td) closest
``` {r echo=FALSE, out.width = '50%', fig.align="center"} library(knitr) olivetti <- system.file("extdata","closesttd33.png",package="eigenfaces")
include_graphics(olivetti) ```
Matthew Turk and Alex Pentland. 1991. Eigenfaces for recognition. J. Cognitive Neuroscience 3, 1 (Winter 1991), 71–86.
https://www.bytefish.de/pdf/eigenfaces.pdf
https://de.wikipedia.org/wiki/Hauptkomponentenanalyse
https://en.wikipedia.org/wiki/Eigenface
https://www.kaggle.com/serkanpeldek/face-recognition-on-olivetti-dataset
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.