Vistas: 823
Tiempo de lectura:6 Minutos, 15 Segundos

Cada vez que subimos una foto a facebook, instagram o google photos, hay algoritmos corriendo, allá en los servidores, que constantemente están haciendo reconocimiento facial, constantemente clasificándolos, encontrando relaciones entre nuestros amigos y conocidos. Estamos viviendo en una época donde la potencia computacional en nuestros dispositivos ha aumentado tanto que es posible tener cosas que antes se podían creer impensables, ya nuestros propios teléfonos hacen reconocimiento facial y algunos se aventuran al reconocimiento de objetos.

Facebook hace reconocimiento facial para buscar relaciones entre tus amigos

Pero todos estos avances se realizan a través de una capa de abstracción que las mismas empresas han puesto para facilitarnos la vida. Ya hay tantas cosas que damos por hecho que ni siquiera al subir una foto nos tomamos la tarea de etiquetar a las personas, Facebook mismo nos sugiere esas etiquetas, ya no nos sorprende el acierto con el que llevan a cabo esta tarea.

Es por esto que las nuevas generaciones van a ser muy rápidas usando estos servicios, plataformas como facebook, snapchat, tic toc son tan fáciles de usar para estos niños que nacen hoy en día con un iPad debajo del brazo. Por esta razón hoy les traigo un pequeño tutorial, para arrojar un poco de luz sobre algunas herramientas que se utilizan hoy en día, vamos a implementar un modelo de reconocimiento facial con una API llamada Face Recognition. Esta nos permitirá solucionar varios problemas.     

  • Detectar caras de personas  
  • Aprender la cara de una persona  
  • Reconocer la cara de personas aprendidas en otras fotos o vídeos

1. Preparación del entorno

Como todo proyecto en python vamos a necesitar un ambiente aislado para montar nuestro codigo, asi como las librerías que utilizaremos. La opcion mas facil es instalar anaconda (https://www.anaconda.com/) con python 3.

Vamos a necesitar instalar tres librerías, Face Recognition, Numpy y OpenCV. Para esto abrimos la terminal de linux y ponemos el siguiente comando:

pip install face_recognition opencv-python numpy

2. Entrenamiento

Para este primer paso vamos a necesitar la foto de una persona y su nombre, para este ejemplo usaremos la cara alguien más o menos conocido, Will Smith. Es importante que esta foto sea únicamente de la cara de la persona que queremos aprender, por que puede detectar caras adicionales y generar errores.

Foto de Will Smith como ejemplo

Para aprender la cara usamos la siguiente API de face_recognition:

# Carga la imagen de entrenamiento
will_smith_image = face_recognition.load_image_file("will_smith.jpg")
# Codifica la cara de entrenamiento
will_smith_face_encoding = face_recognition.face_encodings(will_smith_image)[0]
 
# Crea un arreglo con las distintas caras codificadas
known_face_encodings = [
   will_smith_face_encoding
]
# Crea un arreglo de los nombres en orden de las caras codificadas
known_face_names = [
   "Will Smith",
]

Face recognition carga la imagen y la codifica, dando como resultado una vector de flotantes de 128 dimensiones. Este vector es único para cada cara y nos permitirá en un futuro reconocer esa cara en otras fotos.

Por ahora guardamos la cara y los nombres en un arreglo ordenado, hay que repetir esta operación si queremos aprendernos varias caras.

3. Seleccionar la fuente de imágenes

Una vez tengamos la cara codificada, tenemos que pasar una foto o video con quien compararla, sea de la misma persona o de personas diferentes.

#extraer imagenes de un video
video_capture = cv2.VideoCapture('Will.mp4')
 
#extraer imagenes de la webcam
video_capture = cv2.VideoCapture(0)
 
if (video_capture.isOpened()== False):
 print("Error opening video stream or file")

El código del tutorial está preparado para usar la cámara web del equipo como fuente de imágenes o un archivo de video dentro del directorio, solo tendrías que comentar lo que no quieres usar.

4. Detectar caras

Una vez tenemos la fuente configurada, pasamos a detectar caras, fotograma por fotograma, para eso usamos la función read(). Para un mejor rendimiento, redimensionamos la resolución de la imagen a ¼ de su tamaño. 

# Toma los fotogramas del capturador
   ret, frame = video_capture.read()
 
   # Redimensiona el fotograma a 1/4 de resolucion para mejor rendimiento
   small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
 
   # Convierte la imagen de BGR color a RGB
   rgb_small_frame = small_frame[:, :, ::-1]

La siguiente línea usa la función “face_locations” de Face Recognition para detectar las caras en el fotograma:

# encuentra y codifica todas las caras existentes en el fotograma
face_locations = face_recognition.face_locations(rgb_small_frame)

La siguiente línea codifica todas las caras con “face_encoding”, generando otra vez un vector de 128 dimensiones, con el que al fin podremos comparar la cara entrenada anteriormente

face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

5. Comparar caras

Ya con el vector de la cara entrenada y el de las caras nuevas, usamos la función “compare_faces”. Esta parte del código, toma cada cara nueva y la compara con las caras entrenadas, el resultado es una matriz de booleanos, que en orden devuelve un “True”  por cada vez que haga match con una cara entrenada. Esta matriz la pasamos por otra función que devuelve la distancia en un espacio euclídeo entre los vectores, de esta manera, las caras mas parecidas estarán más cercanas.

for face_encoding in face_encodings:
           # compara las caras codificadas con las caras entrenadas
           matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
           name = "Unknown"
 
           # usa la distancia entre las caras para encontrar la mayor probabilidad de match
           face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
           best_match_index = np.argmin(face_distances)
           if matches[best_match_index]:
               name = known_face_names[best_match_index]
 
           face_names.append(name)

Así, el final dará como resultado que esa cara corresponderá a un nombre previamente entrenado o “unknow” que será desconocido.

6. Presentar los resultados

Para presentar los resultados, nos apoyamos de la librería opencv, que nos servirá para pintar cuadros y texto sobre el fotograma y mostrarlo en una ventana de visualización.

for (top, right, bottom, left), name in zip(face_locations, face_names):
       # Escala nuevamente el fotograma a la resolucion original
       top *= 4
       right *= 4
       bottom *= 4
       left *= 4
 
       # Dibuja un rectangulo al rededor del rostro
       cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
 
       # Dibuja el nombre del rostro encontrado
       cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
       font = cv2.FONT_HERSHEY_DUPLEX
       cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
 
   # Muestra el resultado de la imagen
   cv2.imshow('Video', frame)

Para correr el script simplemente es poner en la consola:
python face_recognition_tutorial.py

Foto de Will Smith como ejemplo

7. Conclusiones

Este es un script muy sencillo de implementar donde nos muestra cómo se han facilitado las barreras de entrada para las personas interesadas en machine learning o específicamente reconocimiento facial.

Este ejemplo así como otros están en el repositorio original como “examples” https://github.com/ageitgey/face_recognition 

Si quieres profundizar mas, el autor de la librería saco un articulo explicando más a fondo cómo funciona la librería: 

https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78

Lectura casi que obligatoria.Además de tener en cuenta la documentación de la librería para saber todas sus funciones:

https://face-recognition.readthedocs.io/en/latest/ 

Si llegaste hasta aquí, felicidades espero que te haya servido este pequeño introductorio.