El reconocimiento facial es uno de los campos que emplea el aprendizaje automático y se utiliza ampliamente en muchos ámbitos, desde el etiquetado de fotos en las redes sociales y el emparejamiento de personas con los mismos rasgos faciales en los sitios de citas, hasta la localización de delincuentes y la seguridad de las fronteras, pasando por el mantenimiento a raya de los grandes jugadores en los casinos.
Me parece fascinante que podamos simular el proceso de reconocimiento facial con un grado significativo de precisión, mientras que al mismo tiempo hay personas que sufren de prosopagnosia, o «ceguera facial», que no tienen tanta suerte. Un autor de un artículo de Cracked con el que me topé hace un tiempo describe esta experiencia como la de ver una pila de LEGOs en la que, en cuanto apartas la vista, ya no puedes describir con ningún detalle sustancial de qué color y forma era cada pieza o cómo estaban colocadas. Me he preguntado si este trastorno cognitivo tiene algo que ver con la asignación de memoria. Por suerte, la memoria es algo de lo que los ordenadores disponen en abundancia y ni siquiera hemos empezado a arañar la superficie del conjunto completo de capacidades que presentará la computación cuántica.
Pero volvamos a las eigenfaces.
Los datos visuales de una imagen se pueden mapear en un vector en el que cada entrada representa el brillo del píxel correspondiente. Tomando un conjunto de imágenes, se puede construir una matriz en la que cada fila corresponde a un vector de imagen específico. Lo ideal es que las imágenes se normalicen primero de forma que se alineen los rasgos básicos, como los ojos, la nariz y la boca, para aumentar la precisión y reducir el ruido. Los rostros propios son entonces los vectores propios que se derivan de la matriz de covarianza de esta matriz de datos faciales analizados.
El conjunto de datos de rostros que utilizamos fue proporcionado amablemente por los Laboratorios AT&T de Cambridge y consistía en 40 rostros individuales, 10 imágenes de cada uno con diferentes expresiones faciales y posiciones de la cabeza.
En este ejercicio se utilizaron las siguientes bibliotecas y módulos de Python:
from sklearn.preprocessing import normalize
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from scipy.misc import imread
from itertools import chain
import numpy as np
import scipy as sp
import glob
-
normalize
la función escala cada vector individual de la muestra para que tenga norma unitaria. -
PCA
o Análisis de Componentes Principales, es un proceso de reducción de la dimensionalidad lineal que utiliza la Descomposición del Valor Singular de los datos para proyectarlos a un espacio de menor dimensión. En otras palabras, es el proceso de encontrar la estructura subyacente de los datos o las direcciones en las que hay más varianza. -
matplotlib.pyplot
es la conocida función de trazado. -
imread
se utiliza para leer en una imagen de un archivo como una matriz. -
chain
es un iterador que recorre la lista devolviendo elementos individuales de cada iterable. -
numpy
es el paquete fundamental de Python para la computación científica. -
scipy
es otro paquete para la computación científica y técnica, similar anumpy
pero que contiene versiones más completas de los módulos de álgebra lineal, así como muchos otros algoritmos numéricos. -
glob
módulo encuentra todos los nombres de ruta que coinciden con un patrón especificado.
El primer paso es extraer todos los nombres de archivo del archivo comprimido. A continuación, se crea una matriz deshaciendo las matrices de imágenes en vectores mediante el comando chain
y apilándolas. Esto crea una matriz de 400×10304 con cada fila que contiene toda la información sobre una imagen específica de 112×92.
filenames = m = for i in range(400)]for i in range(400):
m = list(chain.from_iterable(imread(filenames)))
m = np.matrix(m)
A continuación, se normaliza la matriz y se aplica el PCA. Aquí hemos reducido nuestro espacio vectorial a sólo 40 de 10304 dimensiones:
model = PCA(n_components=40)
pts = normalize(m)
model.fit(pts)
pts2 = model.transform(pts)
Por último, las caras propias, contenidas en model.components_
, pueden mostrarse:
fig, ax = plt.subplots(1,40)for i in range(40):
ord = model.components_
img = ord.reshape(112,92)
ax.imshow(img,cmap='gray')