Resolviendo algunas dudas del video anterior ( Reconocimiento facial con OpenCV y Python )

Por Administrador

Te doy la bienvenida a un nuevo post. Esta vez estaré resolviendo algunas dudas que me han hecho llegar sobre el tutorial anterior: ? Reconocimiento Facial ? | Python – OpenCV

CONTENIDO

  • ¿Entrené con CPU o GPU?
  • ¿Cuánto tiempo se tardó en entrenar cada reconocedor?
  • ¿Cómo se desempeña cada reconocedor?
    • ¿Y para qué me sirven estos datos?
  • ¿Con estos métodos (EigenFaces, FisherFaces y LBPH) se puede reconocer a más de una persona que aparezca en una imagen?

¿Entrené con CPU o GPU?

Para entrenar el reconocedor de rostros tanto con EigenFaces, FisherFaces y LBPH que vimos en el anterior tutorial lo entrené con CPU.

¿Cuánto tiempo se tardó en entrenar cada reconocedor?

Anteriormente habíamos entrenado reconocedores faciales para poder identificar a dos personas: Brenda y Gaby. Para el entrenamiento se contó con 300 imágenes de 150 x 150 pixeles con los rostros de cada una.

Para obtener el tiempo de duración por cada entrenamiento voy a incrementar unas cuantas líneas en el código anteriormente usado, veamos:

import cv2
import os
import numpy as np
import time

dataPath = 'C:/Users/Gaby/Desktop/Reconocimiento Facial/Data' #Cambia a la ruta donde hayas almacenado Data
peopleList = os.listdir(dataPath)
print('Lista de personas: ', peopleList)

labels = []
facesData = []
label = 0

for nameDir in peopleList:
    personPath = dataPath + '/' + nameDir
    #print('Leyendo las imágenes')

    for fileName in os.listdir(personPath):
        #print('Rostros: ', nameDir + '/' + fileName)
        labels.append(label)
        facesData.append(cv2.imread(personPath+'/'+fileName,0))
        #image = cv2.imread(personPath+'/'+fileName,0)
        #cv2.imshow('image',image)
        #cv2.waitKey(10)
    label = label + 1

#print('labels= ',labels)
print('Número de etiquetas 0: ',np.count_nonzero(np.array(labels)==0))
print('Número de etiquetas 1: ',np.count_nonzero(np.array(labels)==1))

# Métodos para entrenar el reconocedor
face_recognizer = cv2.face.EigenFaceRecognizer_create()
#face_recognizer = cv2.face.FisherFaceRecognizer_create()
#face_recognizer = cv2.face.LBPHFaceRecognizer_create()

# Entrenando el reconocedor de rostros
print("Entrenando...")
inicio = time.time()
face_recognizer.train(facesData, np.array(labels))
tiempoEntrenamiento = time.time()-inicio
print("Tiempo de entrenamiento: ", tiempoEntrenamiento)

# Almacenando el modelo obtenido
face_recognizer.write('modeloEigenFace.xml')
#face_recognizer.write('modeloFisherFace.xml')
#face_recognizer.write('modeloLBPHFace.xml')
print("Modelo almacenado...")

Línea 4: Importamos time.

Línea 38: Tomamos el tiempo actual que se almacenará en inicio.

Línea 40: Restamos el tiempo actual menos el tiempo en inicio que se almacenará en tiempoEntrenamiento. Recuerda que para poder monitorear el tiempo trascurrido debes tomar el tiempo anterior y posterior al de la línea 39 que corresponde al entrenamiento.

Línea 41: Visualizamos el tiempo transcurrido en segundos.

Ahora que ya tenemos como conocer el tiempo de entrenamiento vamos a experimentar en dos escenarios (computadores), con cada uno de los métodos: eigenFaces, fisherFaces, LBPH. Veamos:

¿Cómo se desempeña cada reconocedor?

Esta es una pregunta que me la he plateado yo, ya que quisiera mostrarte como está trabajando cada reconocedor con cada método entrenado. Esta vez voy a evaluar cuanto tiempo le toma la ejecución de un video aplicando el reconocimiento, además su fps (frame rate / fotogramas por segundo).

Para ello estaré usando la librería imutils, que nos ayudará a calcular el tiempo estimado de reproducción, además de los fps.

import cv2
import os
from imutils.video import FPS

dataPath = 'C:/Users/Gaby/Desktop/Reconocimiento Facial/Data' #Cambia a la ruta donde hayas almacenado Data
imagePaths = os.listdir(dataPath)
print('imagePaths=',imagePaths)

#face_recognizer = cv2.face.EigenFaceRecognizer_create()
#face_recognizer = cv2.face.FisherFaceRecognizer_create()
face_recognizer = cv2.face.LBPHFaceRecognizer_create()

# Leyendo el modelo
#face_recognizer.read('modeloEigenFace.xml')
#face_recognizer.read('modeloFisherFace.xml')
face_recognizer.read('modeloLBPHFace.xml')

#cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
cap = cv2.VideoCapture('Imagenes y Videos de Prueba/GabyTest1.mp4')

faceClassif = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
fps = FPS().start() while True: ret,frame = cap.read() if ret == False: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) auxFrame = gray.copy() faces = faceClassif.detectMultiScale(gray,1.3,5) for (x,y,w,h) in faces: rostro = auxFrame[y:y+h,x:x+w] rostro = cv2.resize(rostro,(150,150),interpolation= cv2.INTER_CUBIC) result = face_recognizer.predict(rostro) cv2.putText(frame,'{}'.format(result),(x,y-5),1,1.3,(255,255,0),1,cv2.LINE_AA) ''' # EigenFaces if result[1] < 5700: cv2.putText(frame,'{}'.format(imagePaths[result[0]]),(x,y-25),2,1.1,(0,255,0),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,255,0),2) else: cv2.putText(frame,'Desconocido',(x,y-20),2,0.8,(0,0,255),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,0,255),2) # FisherFace if result[1] < 500: cv2.putText(frame,'{}'.format(imagePaths[result[0]]),(x,y-25),2,1.1,(0,255,0),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,255,0),2) else: cv2.putText(frame,'Desconocido',(x,y-20),2,0.8,(0,0,255),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,0,255),2) ''' # LBPHFace if result[1] < 70: cv2.putText(frame,'{}'.format(imagePaths[result[0]]),(x,y-25),2,1.1,(0,255,0),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,255,0),2) else: cv2.putText(frame,'Desconocido',(x,y-20),2,0.8,(0,0,255),1,cv2.LINE_AA) cv2.rectangle(frame, (x,y),(x+w,y+h),(0,0,255),2) cv2.imshow('frame',frame) k = cv2.waitKey(1) if k == 27: break fps.update() fps.stop() print("Tiempo de reproducción: {:.2f}".format(fps.elapsed())) print("FPS aproximado: {:.2f}".format(fps.fps())) cap.release() cv2.destroyAllWindows()

Línea 3: Con from imutils.video import FPS, importamos lo necesario para obtener el tiempo de reproducción y su fps asociado.

Línea 22: Necesitamos iniciar con el proceso con FPS().start(), previo a la lectura del video.

Línea 67: Luego de la lectura de cada fotograma digitados fps.update(), para que cuente cada iteración y al final pueda calcular el fps.

Línea 69: Una vez que el video haya finalizado digitamos fps.stop().

Línea 70 y 71: Vamos a visualizar el tiempo de reproducción (fps.elapsed()), y el fps aproximado (fps.fps()).

Para probar este código usé un video de 8 segundos de duración, a 20 fotogramas por segundo (puedes verlo aquí).

Apliqué la programación a este video en un computador intel core i5, intel core i7 y además con una raspberry pi 3B. Estos fueron los resultados:

¿Y para qué me sirven estos datos?

El video de entrada tiene 8 segundos de duración y fps de 20. Sería «lógico» pensar que OpenCV va a respetar estos datos y mostrarnos una salida idéntica al video de entrada sin embargo, lo cierto es que OpenCV busca realizar los procesos u operaciones lo más rápido posible, es por ello que cuando simplemente visualizamos un video, este se muestra a gran velocidad.

Entonces, el resultado de aplicar reconocimiento facial con cada uno de estos métodos (EigenFaces, FisherFaces y LBPH) cambiará dependiendo de cada uno de ellos, dadas las operaciones que conlleva usarlos.

Si consideramos por ejemplo las mediciones realizadas para un computador con core i5 y 6GB de RAM, en EigenFaces tenemos un fps 9.54, con FisherFaces 24.08 y LBPH 8.92. Para el ejemplo que estamos tomando, el fps que más se acercaría al del video de entrada es el de LBPH, mientras que el más alto sería el correspondiente a FisherFaces. Comparando estos dos valores podemos darnos cuenta de que con FisherFaces tenemos más rapidez en las operaciones que realiza el reconocedor para identificar a una persona (dado que analiza rápidamente cada fotograma a comparación con el otro método), mientas que con LBPH es más tardado, por lo tanto se puede apreciar que este último es más costoso computacionalmente.

Cabe destacar que esta comparación la he realizado con el objetivo de analizar cual de estos métodos es más costoso computacionalmente, dado el ejemplo que he tomado, mas no para determinar que tan bien o mal está reconociendo a la persona.

¿Con estos métodos (EigenFaces, FisherFaces y LBPH) se puede reconocer a más de una persona que aparezca en una imagen?

El proceso de reconocimiento se da luego de la detección facial, por tanto todo rostro detectado pasará por el proceso de reconocimiento para ser etiquetado con el nombre de una persona o como desconocido. Por consiguiente el reconocimiento facial se aplicará a todos los rostros detectados en la imagen.

Veamos un ejemplo de como más de una persona es reconocida:

Figura 1: Reconocimiento facial.

Hemos llegado al final del post, espero sea útil y que me haya dado entender de mejor manera. Ten un excelente día y nos vemos en el siguiente video/post.