Tabla de contenido:
- Paso 1: BoM - Lista de materiales
- Paso 2: Instalación del paquete OpenCV 3
- Paso 3: prueba tu cámara
- Paso 4: Detección de rostro
- Paso 5: recopilación de datos
- Paso 6: Entrenador
- Paso 7: reconocedor
- Paso 8: Conclusión
Video: Reconocimiento facial en tiempo real: un proyecto de principio a fin: 8 pasos (con imágenes)
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:43
En mi último tutorial explorando OpenCV, aprendimos SEGUIMIENTO AUTOMÁTICO DE OBJETOS DE VISIÓN. Ahora usaremos nuestra PiCam para reconocer rostros en tiempo real, como puedes ver a continuación:
Este proyecto se realizó con esta fantástica "Biblioteca de visión por computadora de código abierto", la OpenCV. En este tutorial, nos centraremos en Raspberry Pi (es decir, Raspbian como sistema operativo) y Python, pero también probé el código en Mi Mac y también funciona bien. OpenCV fue diseñado para la eficiencia computacional y con un fuerte enfoque en aplicaciones en tiempo real. Por lo tanto, es perfecto para el reconocimiento facial en tiempo real con una cámara.
Para crear un proyecto completo sobre Reconocimiento facial, debemos trabajar en 3 fases muy diferenciadas:
- Detección de rostros y recopilación de datos
- Entrena al reconocedor
- Reconocimiento facial
El siguiente diagrama de bloques reanuda esas fases:
Paso 1: BoM - Lista de materiales
Partes principales:
- Raspberry Pi V3 - US $ 32,00
- 5 megapíxeles 1080p Sensor OV5647 Mini módulo de video de cámara - US $ 13.00
Paso 2: Instalación del paquete OpenCV 3
Estoy usando una Raspberry Pi V3 actualizada a la última versión de Raspbian (Stretch), por lo que la mejor manera de tener OpenCV instalado, es seguir el excelente tutorial desarrollado por Adrian Rosebrock: Raspbian Stretch: Instale OpenCV 3 + Python en su Raspberry Pi.
Probé varias guías diferentes para instalar OpenCV en mi Pi. El tutorial de Adrian es el mejor. Te aconsejo que hagas lo mismo, siguiendo su pauta paso a paso.
Una vez que haya terminado el tutorial de Adrian, debe tener un entorno virtual OpenCV listo para ejecutar nuestros experimentos en su Pi.
Vayamos a nuestro entorno virtual y confirmemos que OpenCV 3 está instalado correctamente.
Adrian recomienda ejecutar el comando "fuente" cada vez que abra una nueva terminal para asegurarse de que las variables de su sistema se hayan configurado correctamente.
fuente ~ /.profile
A continuación, entremos en nuestro entorno virtual:
trabajar en cv
Si ve el texto (cv) que precede a su mensaje, entonces se encuentra en el entorno virtual cv:
(cv) pi @ frambuesa: ~ $Adrian llama la atención sobre el hecho de que el entorno virtual cv Python es completamente independiente y está aislado de la versión predeterminada de Python incluida en la descarga de Raspbian Stretch. Por lo tanto, cualquier paquete de Python en el directorio global site-packages no estará disponible para el entorno virtual cv. De manera similar, cualquier paquete de Python instalado en paquetes de sitio de cv no estará disponible para la instalación global de Python
Ahora, ingrese su intérprete de Python:
pitón
y confirme que está ejecutando la versión 3.5 (o superior)
Dentro del intérprete (aparecerá el ">>>"), importe la biblioteca OpenCV:
importar cv2
Si no aparecen mensajes de error, el OpenCV está instalado correctamente EN SU ENTORNO VIRTUAL PYTHON.
También puede comprobar la versión de OpenCV instalada:
cv2._ versión_
Debería aparecer la 3.3.0 (o una versión superior que se puede lanzar en el futuro). La pantalla de impresión del terminal anterior muestra los pasos anteriores.
Paso 3: prueba tu cámara
Una vez que tenga OpenCV instalado en su RPi, hagamos una prueba para confirmar que su cámara está funcionando correctamente.
Supongo que ya tiene una PiCam instalada en su Raspberry Pi.
Ingrese el siguiente código de Python en su IDE:
importar numpy como np
import cv2 cap = cv2. VideoCapture (0) cap.set (3, 640) # set Width cap.set (4, 480) # set Height while (True): ret, frame = cap.read () frame = cv2. flip (marco, -1) # Voltear la cámara verticalmente gris = cv2.cvtColor (marco, cv2. COLOR_BGR2GRAY) cv2.imshow ('marco', marco) cv2.imshow ('gris', gris) k = cv2.waitKey (30) & 0xff si k == 27: # presione 'ESC' para salir de romper cap.release () cv2.destroyAllWindows ()
El código anterior capturará la transmisión de video que generará su PiCam, mostrando ambos, en color BGR y en modo gris.
Tenga en cuenta que giré mi cámara verticalmente debido a la forma en que está ensamblada. Si no es su caso, comente o elimine la línea de comando "flip".
Alternativamente, puede descargar el código de mi GitHub: simpleCamTest.py
Para ejecutar, ingrese el comando:
python simpleCamTest.py
Para finalizar el programa, debe presionar la tecla [ESC] en su teclado.
Haga clic con el mouse en la ventana de video, antes de presionar [ESC]
La imagen de arriba muestra el resultado.
Algunos fabricantes encontraron problemas al intentar abrir la cámara (mensajes de error "Aserción fallida"). Eso podría suceder si la cámara no se habilitó durante la instalación de OpenCv y, por lo tanto, los controladores de la cámara no se instalaron correctamente. Para corregir, use el comando:
sudo modprobe bcm2835-v4l2
También puede agregar bcm2835-v4l2 a la última línea del archivo / etc / modules para que el controlador se cargue al arrancar.
Para saber más sobre OpenCV, puede seguir el tutorial: loading -video-python-opencv-tutorial
Paso 4: Detección de rostro
La tarea más básica del reconocimiento facial es, por supuesto, la "detección de rostros". Antes que nada, debes "capturar" un rostro (Fase 1) para poder reconocerlo, en comparación con un nuevo rostro capturado en el futuro (Fase 3).
La forma más común de detectar una cara (o cualquier objeto) es utilizando el "clasificador Haar Cascade"
La detección de objetos mediante clasificadores en cascada basados en características de Haar es un método eficaz de detección de objetos propuesto por Paul Viola y Michael Jones en su artículo, "Detección rápida de objetos mediante una cascada mejorada de características simples" en 2001. Es un enfoque basado en el aprendizaje automático en el que un La función de cascada se entrena a partir de una gran cantidad de imágenes positivas y negativas. Luego se usa para detectar objetos en otras imágenes.
Aquí trabajaremos con detección de rostros. Inicialmente, el algoritmo necesita muchas imágenes positivas (imágenes de rostros) e imágenes negativas (imágenes sin rostros) para entrenar al clasificador. Entonces necesitamos extraer características de él. La buena noticia es que OpenCV viene con un entrenador y un detector. Si desea entrenar su propio clasificador para cualquier objeto como automóvil, aviones, etc., puede usar OpenCV para crear uno. Sus detalles completos se dan aquí: Entrenamiento de clasificador en cascada.
Si no desea crear su propio clasificador, OpenCV ya contiene muchos clasificadores previamente entrenados para rostro, ojos, sonrisa, etc. Esos archivos XML se pueden descargar desde el directorio haarcascades.
Basta de teoría, ¡creemos un detector de rostros con OpenCV!
Descarga el archivo: faceDetection.py desde mi GitHub.
importar numpy como np
import cv2 faceCascade = cv2. CascadeClassifier ('Cascades / haarcascade_frontalface_default.xml') cap = cv2. VideoCapture (0) cap.set (3, 640) # set Width cap.set (4, 480) # set Height while True: ret, img = cap.read () img = cv2.flip (img, -1) gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) caras = faceCascade.detectMultiScale (gris, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20)) para (x, y, w, h) en caras: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gris [y: y + h, x: x + w] roi_color = img [y: y + h, x: x + w] cv2.imshow ('video', img) k = cv2.waitKey (30) & 0xff si k == 27: # presione 'ESC' para salir de romper cap.release () cv2.destroyAllWindows ()
Lo crea o no, las pocas líneas de código anteriores son todo lo que necesita para detectar una cara, usando Python y OpenCV.
Cuando lo compare con el último código utilizado para probar la cámara, se dará cuenta de que se le agregaron pocas partes. Tenga en cuenta la línea siguiente:
faceCascade = cv2. CascadeClassifier ('Cascades / haarcascade_frontalface_default.xml')
Esta es la línea que carga el "clasificador" (que debe estar en un directorio llamado "Cascades /", bajo el directorio de su proyecto).
Luego, configuraremos nuestra cámara y dentro del bucle, cargaremos nuestro video de entrada en modo escala de grises (lo mismo que vimos antes).
Ahora debemos llamar a nuestra función clasificadora, pasándole algunos parámetros muy importantes, como factor de escala, número de vecinos y tamaño mínimo del rostro detectado.
caras = faceCascade.detectMultiScale (gray, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20))
Dónde,
- el gris es la imagen de entrada en escala de grises.
- scaleFactor es el parámetro que especifica cuánto se reduce el tamaño de la imagen en cada escala de imagen. Se utiliza para crear la pirámide de escala.
- minNeighbors es un parámetro que especifica cuántos vecinos debe tener cada rectángulo candidato para retenerlo. Un número más alto da menos falsos positivos.
- minSize es el tamaño mínimo de rectángulo para ser considerado una cara.
La función detectará rostros en la imagen. A continuación, debemos "marcar" las caras en la imagen, utilizando, por ejemplo, un rectángulo azul. Esto se hace con esta parte del código:
para (x, y, w, h) en caras:
cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gris [y: y + h, x: x + w] roi_color = img [y: y + h, x: x + w]
Si se encuentran caras, devuelve las posiciones de las caras detectadas como un rectángulo con la esquina superior izquierda (x, y) y teniendo "w" como su Ancho y "h" como su Alto ==> (x, y, w, h). Por favor, vea la imagen de arriba.
Una vez que obtenemos estas ubicaciones, podemos crear un "ROI" (rectángulo dibujado) para la cara y presentar el resultado con la función imshow ().
Ejecute el script de Python anterior en su entorno de Python, usando la Terminal Rpi:
python faceDetection.py
El resultado:
También puede incluir clasificadores para "detección de ojos" o incluso "detección de sonrisas". En esos casos, incluirá la función de clasificador y el dibujo del rectángulo dentro del bucle de la cara, porque no tendría sentido detectar un ojo o una sonrisa fuera de una cara.
Tenga en cuenta que en una Pi, tener varios clasificadores en el mismo código ralentizará el procesamiento, una vez que este método de detección (HaarCascades) utiliza una gran cantidad de poder computacional. En un escritorio, es más fácil ejecutarlo.
En mi GitHub encontrarás otros ejemplos:
faceEyeDetection.py
faceSmileDetection.py
faceSmileEyeDetection.py
Y en la imagen de arriba puedes ver el resultado.
También puede seguir el siguiente tutorial para comprender mejor la detección de rostros:
Haar Cascade Object Detection Face & Eye OpenCV Python Tutorial
Paso 5: recopilación de datos
En primer lugar, debo agradecer a Ramiz Raja por su gran trabajo en el reconocimiento facial en fotos:
RECONOCIMIENTO FACIAL CON OPENCV Y PYTHON: UNA GUÍA PARA PRINCIPIANTES
y también Anirban Kar, que desarrolló un tutorial muy completo usando video:
RECONOCIMIENTO FACIAL - 3 partes
Realmente te recomiendo que eches un vistazo a ambos tutoriales.
Dicho esto, comencemos la primera fase de nuestro proyecto. Lo que haremos aquí, es comenzar desde el último paso (Detección de rostros), simplemente crearemos un conjunto de datos, donde almacenaremos para cada identificación, un grupo de fotos en gris con la parte que se utilizó para la detección de rostros.
Primero, cree un directorio donde desarrolle su proyecto, por ejemplo, FacialRecognitionProject:
mkdir FacialRecognitionProject
En este directorio, además de los 3 scripts en python que crearemos para nuestro proyecto, debemos tener guardado en él el Clasificador Facial. Puedes descargarlo de mi GitHub: haarcascade_frontalface_default.xml
A continuación, cree un subdirectorio donde almacenaremos nuestras muestras faciales y lo nombraremos "conjunto de datos":
conjunto de datos mkdir
Y descargue el código de mi GitHub: 01_face_dataset.py
importar cv2
import os cam = cv2. VideoCapture (0) cam.set (3, 640) # set video width cam.set (4, 480) # set video height face_detector = cv2. CascadeClassifier ('haarcascade_frontalface_default.xml') # Para cada persona, ingrese un ID de rostro numérico face_id = input ('\ n ingrese el ID de usuario y presione ==>') print ("\ n [INFO] Inicializando la captura de rostros. Mire la cámara y espere…") # Inicialice el recuento del conteo de rostros de muestreo individual = 0 while (True): ret, img = cam.read () img = cv2.flip (img, -1) # voltear imagen de video verticalmente gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) caras = face_detector.detectMultiScale (gris, 1.3, 5) para (x, y, w, h) en caras: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) count + = 1 # Guarde la imagen capturada en la carpeta de conjuntos de datos cv2.imwrite ("dataset / User." + str (face_id) + '.' + str (count) + ".jpg", gris [y: y + h, x: x + w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Presione 'ESC' para salir del video si k == 27: break elif count> = 30: # Tomar 30 muestras de caras y detener la pausa de video # Hacer ab it of cleanup print ("\ n [INFO] Saliendo del programa y cosas de limpieza") cam.release () cv2.destroyAllWindows ()
El código es muy similar al código que vimos para la detección de rostros. Lo que agregamos fue un "comando de entrada" para capturar una identificación de usuario, que debería ser un número entero (1, 2, 3, etc.)
face_id = input ('\ n ingrese la identificación del usuario y presione ==>')
Y para cada uno de los fotogramas capturados, debemos guardarlo como un archivo en un directorio de "conjunto de datos":
cv2.imwrite ("conjunto de datos / Usuario." + str (face_id) + '.' + str (cuenta) + ".jpg", gris [y: y + h, x: x + w])
Tenga en cuenta que para guardar el archivo anterior, debe haber importado la biblioteca "os". El nombre de cada archivo seguirá la estructura:
User.face_id.count.jpg
Por ejemplo, para un usuario con face_id = 1, el cuarto archivo de muestra en el directorio / conjunto de datos será algo como:
Usuario.1.4.jpg
como se muestra en la foto de arriba de mi Pi. En mi código, estoy capturando 30 muestras de cada id. Puede cambiarlo en el último "elif". El número de muestras se utiliza para romper el bucle donde se capturan las muestras faciales.
Ejecute la secuencia de comandos de Python y capture algunos ID. Debe ejecutar el script cada vez que desee agregar un nuevo usuario (o cambiar las fotos por uno que ya existe).
Paso 6: Entrenador
En esta segunda fase, debemos tomar todos los datos del usuario de nuestro conjunto de datos y "entrenar" el OpenCV Recognizer. Esto se realiza directamente mediante una función específica de OpenCV. El resultado será un archivo.yml que se guardará en un directorio "trainer /".
Entonces, comencemos a crear un subdirectorio donde almacenaremos los datos entrenados:
entrenador mkdir
Descargue de mi GitHub el segundo script de Python: 02_face_training.py
importar cv2
import numpy as np from PIL import Image import os # Path for face image database path = 'dataset' Recognizer = cv2.face. LBPHFaceRecognizer_create () detector = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # función para obtener las imágenes y los datos de la etiqueta def getImagesAndLabels (ruta): imagePaths = [os.path.join (ruta, f) para f en os.listdir (ruta)] faceSamples = ids = para imagePath en imagePaths: PIL_img = Image.open (imagePath).convert ('L') # convertirlo a escala de grises img_numpy = np.array (PIL_img, 'uint8') id = int (os.path.split (imagePath) [- 1]. split (".") [1]) faces = detector.detectMultiScale (img_numpy) para (x, y, w, h) en caras: faceSamples.append (img_numpy [y: y + h, x: x + w]) ids.append (id) return faceSamples, ids print ("\ n [INFO] Entrenar caras. Tardará unos segundos. Espera…") caras, ids = getImagesAndLabels (ruta) Recognizer.train (caras, np.array (ids)) # Guarde el modelo en trainer / trainer.yml Recognizer.write ('trainer / trainer.yml') # Recognizer.save () funcionó en Mac, pero no en Pi # Imprima el número de caras entrenadas y finalice la impresión del programa ("\ n [INFO] {0} rostros entrenados. Saliendo del programa".format (len (np.unique (ids))))
Confirme si tiene la biblioteca PIL instalada en su Rpi. De lo contrario, ejecute el siguiente comando en la Terminal:
pip instalar almohada
Usaremos como reconocedor, el Reconocimiento facial LBPH (LOCAL BINARY PATTERNS HISTOGRAMS), incluido en el paquete OpenCV. Hacemos esto en la siguiente línea:
reconocedor = cv2.face. LBPHFaceRecognizer_create ()
La función "getImagesAndLabels (ruta)", tomará todas las fotos en el directorio: "conjunto de datos /", devolviendo 2 matrices: "ID" y "caras". Con esas matrices como entrada, "entrenaremos nuestro reconocedor":
Recognizer.train (caras, identificadores)
Como resultado, se guardará un archivo llamado "trainer.yml" en el directorio del entrenador que fue creado previamente por nosotros.
¡Eso es todo! Incluí la última declaración impresa donde mostré para confirmación, el número de caras de usuario que hemos entrenado.
Cada vez que realiza la Fase 1, la Fase 2 también debe ejecutarse
Paso 7: reconocedor
Ahora, llegamos a la fase final de nuestro proyecto. Aquí, capturaremos una cara nueva en nuestra cámara y si esta persona tuvo su cara capturada y entrenada antes, nuestro reconocedor hará una "predicción" devolviendo su identificación y un índice, mostrando qué tan seguro está el reconocedor con esta coincidencia.
Descarguemos el script de Python de la tercera fase de mi GitHub: 03_face_recognition.py.
importar cv2
import numpy as np import os Recognizer = cv2.face. LBPHFaceRecognizer_create () Recognizer.read ('trainer / trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2. CascadeClassifier (cascadePath); font = cv2. FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # nombres relacionados con ids: ejemplo ==> Marcelo: id = 1, etc names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z ',' W '] # Inicializa e inicia la captura de video en tiempo real cam = cv2. VideoCapture (0) cam.set (3, 640) # set video widht cam.set (4, 480) # set video height # Define el tamaño mínimo de la ventana para ser reconocido como una cara minW = 0.1 * cam.get (3) minH = 0.1 * cam.get (4) while True: ret, img = cam.read () img = cv2.flip (img, -1) # Voltear verticalmente gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) caras = faceCascade.detectMultiScale (gray, scaleFactor = 1.2, minNeighbors = 5, minSize = (int (minW), int (minH)),) para (x, y, w, h) en caras: cv2.rectangle (img, (x, y), (x + w, y + h), (0, 255, 0), 2) id, confianza = reconocedor.predicto (gris [y: y + h, x: x + w]) # Compruebe si la confianza es menor que ellos 100 ==> "0" es una coincidencia perfecta si (confianza <100): id = nombres [id] confianza = "{0}% ".format (round (100 - confianza)) else: id =" desconocido "confianza =" {0}% ". formato (round (100 - conf idence)) cv2.putText (img, str (id), (x + 5, y-5), font, 1, (255, 255, 255), 2) cv2.putText (img, str (confianza), (x + 5, y + h-5), fuente, 1, (255, 255, 0), 1) cv2.imshow ('cámara', img) k = cv2.waitKey (10) & 0xff # Presione 'ESC' para salir del video si k == 27: break # Hacer un poco de limpieza print ("\ n [INFO] Saliendo del programa y cosas de limpieza") cam.release () cv2.destroyAllWindows ()
Incluimos aquí una nueva matriz, por lo que mostraremos "nombres", en lugar de identificadores numerados:
nombres = ['Ninguno', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W']
Entonces, por ejemplo: Marcelo será el usuario con id = 1; Paula: id = 2, etc.
A continuación, detectaremos una cara, igual que hicimos antes con el clasificador haasCascade. Teniendo una cara detectada podemos llamar a la función más importante en el código anterior:
id, confianza = reconocedor.predicto (parte gris de la cara)
El Recognizer.predict (), tomará como parámetro una porción capturada de la cara a analizar y devolverá su probable propietario, indicando su id y cuánta confianza tiene el reconocedor en relación con esta coincidencia.
Tenga en cuenta que el índice de confianza devolverá "cero" si se considera una coincidencia perfecta
Y por último, si el reconocedor puede predecir una cara, colocamos un texto sobre la imagen con la identificación probable y cuánto es la "probabilidad" en% de que la coincidencia sea correcta ("probabilidad" = 100 - índice de confianza). De lo contrario, se coloca una etiqueta de "desconocido" en la cara.
Debajo un-g.webp
En la imagen de arriba, muestro algunas pruebas realizadas con este proyecto, donde también he usado fotos para verificar si el reconocedor funciona.
Paso 8: Conclusión
Como siempre, espero que este proyecto pueda ayudar a otros a encontrar su camino hacia el apasionante mundo de la electrónica.
Para obtener detalles y el código final, visite mi depósito de GitHub: OpenCV-Face-Recognition
Para más proyectos, visite mi blog: MJRoBot.org
A continuación, un vistazo a un tutorial futuro, donde exploraremos el "seguimiento automático de rostros y otros métodos para la detección de rostros":
¡Saludos desde el sur del mundo!
¡Nos vemos en mi próximo instructable!
Gracias, Marcelo
Recomendado:
Marco de fotos OSD con reconocimiento facial: 11 pasos (con imágenes)
Marco de fotos OSD con reconocimiento de rostros: este instructivo muestra cómo hacer un marco de fotos con visualización en pantalla (OSD) con reconocimiento de rostros. El OSD puede mostrar la hora, el clima u otra información de Internet que desee
Espejo de reconocimiento facial con compartimento secreto: 15 pasos (con imágenes)
Espejo de reconocimiento facial con compartimento secreto: siempre me han intrigado los compartimentos secretos siempre creativos que se utilizan en historias, películas y cosas por el estilo. Entonces, cuando vi el Concurso de Compartimiento Secreto, decidí experimentar yo mismo con la idea y hacer un espejo de aspecto ordinario que abre una s
Reconocimiento de dispositivos en tiempo real mediante huellas EM: 6 pasos
Reconocimiento de dispositivos en tiempo real mediante huellas EM: este dispositivo está diseñado para clasificar diferentes dispositivos electrónicos según sus señales EM. Para diferentes dispositivos, tienen diferentes señales EM emitidas por él. Hemos desarrollado una solución de IoT para identificar los dispositivos electrónicos que utilizan Particle
Timbre con reconocimiento facial: 7 pasos (con imágenes)
Timbre con reconocimiento facial: motivación Recientemente, ha habido una ola de robos en mi país que están dirigidos a personas mayores en sus propios hogares. Por lo general, el acceso lo otorgan los propios ocupantes, ya que los visitantes los convencen de que son cuidadores / enfermeras. Eso
Sistema de seguridad de reconocimiento facial para un refrigerador con Raspberry Pi: 7 pasos (con imágenes)
Sistema de seguridad de reconocimiento facial para un refrigerador con Raspberry Pi: navegando por Internet descubrí que los precios de los sistemas de seguridad varían de 150 $ a 600 $ y más, pero no todas las soluciones (incluso las más caras) se pueden integrar con otras herramientas inteligentes en su hogar! Por ejemplo, no puede configurar