Para hacer esto debemos entender que es una convolucion y que es el algoritmo Haar Cascade.
En este blog hay informacion al respecto:
https://datasmarts.net/es/deteccion-de-rostros-a-la-vieja-usanza-con-haar-cascades/
Ahi tambien pueden encontrar el codigo para implementarlo en una imagen pero en este caso lo haremos para detectar nuestros rostros en tiempo real, ademas proporciono el codigo para descargar los clasificadores
Importaremos dos archivos desde github, uno con el clasificador de ojos y otro con el clasificador de rostros, ademas usaremos la libreria OpenCV para realizar la convolucion en nuestro modelo y para la manipulacion de imagenes, en este caso de la captura(ejm: el dibujo de los cuadrantes).
Lamentablemente a pesar de que google colab tiene integrada la libreria OpenCV no me permite ejecutar en tiempo real el algoritmo, por eso les dejare el codigo aca:
0-Antes que nada instalamos OpenCV:
pip install opencv-python
1-Ahora en nuestro IDE importamos las librerias numpy para manejo de matrices, cv2 de opencv, requests para obtener los archivos de github y os para manejo de archivos, luego cargamos nuestros clasificadores, le decimos que si no encuentra esos archivos que los descargue de github.
import numpy as np
import cv2
import requests
import os
#Descargar la data
face = "haarcascade.xml"
if not os.path.isfile(face):
url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
content = requests.get(url).content
f = open(face, "wb")
f.write(content)
eye = "eyecascade.xml"
if not os.path.isfile(eye):
url_ = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye.xml"
content_ = requests.get(url_).content
f = open(eye, "wb")
f.write(content_)
2- Creamos nuestros clasificadores a partir de la data importada, luego creamos nuestra captura de video y con cv2.namedWindow haremos que sea posible cambiar el tamaño de nuestra ventana.
#Clasificadores
face_cascade = cv2.CascadeClassifier(face)
eye_cascade = cv2.CascadeClassifier(eye)
#Captura de video
cap = cv2.VideoCapture(0)
cv2.namedWindow("frame", cv2.WINDOW_NORMAL)
3-Ahora creamos un infinite loop para mantener nuestra captura, gray es la captura en escala de grises, faces son las regiones o bounding boxes donde clasificó el/los rostros los cuales tienen como variables:
-x,y: coordenadas de los centros de cada bounding box
-w,h: ancho y altura de la imagen
Dibujaremos el bounding box de cada rostro segun esos datos y agregamos la palabra:“Person”.
Una vez que tenemos las regiones de nuestros rostros(x,y,w,h), para detectar los ojos pasaremos a usar el clasificador de ojos para cada region de cada rostro y asi optimizar la busqueda de manera que no recorra toda la imagen.
Dejare anotaciones en el codigo para un mejor entendimiento.
while 1:
ret, frame = cap.read()
#Imagen en escala de grises
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Deteccion de rostros con nuestro clasificador
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
#(coordenadas en xy, ancho y alto)
for (x,y,w,h) in faces:
#Dibujar rectangulo(imagen, coordenadas, ancho y alto, color en RGB, grosor)
img = cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2)
cv2.putText(img = img,
text = "Person",
org = (x-10, y-10),
fontFace = cv2.FONT_HERSHEY_SIMPLEX,
fontScale = 0.6,
color = (0,0,255),
thickness= 1
)
#Region del rostro en la imagen en escala de grises
roi_gray = gray[y:y+h, x:x+w]
#Region del rostro en la imagen a colores
roi_color = img[y:y+h, x:x+w]
#Deteccion de ojos por cada rostro
#Recuerda que el kernel o filtro solo funciona con imagenes en escala de grises
eyes = eye_cascade.detectMultiScale(roi_gray)
#(coordenadas en xy, ancho y alto)
for (ex,ey,ew,eh) in eyes:
#Dibuja el rectangulo en la region del rostro
img = cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 2)
Ahora todo el codigo se veria asi:
import numpy as np
import cv2
import requests
import os
#Descargamos los clasificadores
face = "haarcascade.xml"
if not os.path.isfile(face):
url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
content = requests.get(url).content
f = open(face, "wb")
f.write(content)
eye = "eyecascade.xml"
if not os.path.isfile(eye):
url_ = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye.xml"
content_ = requests.get(url_).content
f = open(eye, "wb")
f.write(content_)
#Clasificadores
face_cascade = cv2.CascadeClassifier(face)
eye_cascade = cv2.CascadeClassifier(eye)
#Captura de video
cap = cv2.VideoCapture(0)
cv2.namedWindow("frame", cv2.WINDOW_NORMAL)
while 1:
ret, frame = cap.read()
#Imagen en escala de grises
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#Deteccion de rostros con nuestro clasificador
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
#(coordenadas en xy, ancho y alto)
for (x,y,w,h) in faces:
#Dibujar rectangulo(imagen, coordenadas, ancho y alto, color en RGB, grosor)
img = cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2)
cv2.putText(img = img,
text = "Person",
org = (x-10, y-10),
fontFace = cv2.FONT_HERSHEY_SIMPLEX,
fontScale = 0.6,
color = (0,0,255),
thickness= 1
)
#Region del rostro en la imagen en escala de grises
roi_gray = gray[y:y+h, x:x+w]
#Region del rostro en la imagen a colores
roi_color = img[y:y+h, x:x+w]
#Deteccion de ojos por cada rostro
#Recuerda que el kernel o filtro solo funciona con imagenes en escala de grises
eyes = eye_cascade.detectMultiScale(roi_gray)
#(coordenadas en xy, ancho y alto)
for (ex,ey,ew,eh) in eyes:
#Dibuja el rectangulo en la region del rostro
img = cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 2)
cv2.imshow("frame", frame)
cv2.waitKey(1)
cap.release()
cv2.destroyAllWindows()
Y listo, mantente cerca de la camara de tu computadora para que veas como funciona.
Podremos probar este algoritmo para algo mas simple, en este caso para detectar los rostros de Messi y CR7:
import numpy as np
import cv2
import requests
import os
import matplotlib.pyplot as plt
#Download data
face = "haarcascade.xml"
if not os.path.isfile(face):
url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
content = requests.get(url).content
f = open(face, "wb")
f.write(content)
eye = "eyecascade.xml"
if not os.path.isfile(eye):
url_ = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye.xml"
content_ = requests.get(url_).content
f = open(eye, "wb")
f.write(content_)
image = "messi_cr7.jpg"
if not os.path.isfile(image):
url_ = "https://publimetro.pe/resizer/n7FU8sz4fE1ml7RPdvi_6XEFp1w=/980x528/smart/arc-anglerfish-arc2-prod-elcomercio.s3.amazonaws.com/public/HBSLR2R2ZVGOFBJXSFIJZ3HOTQ.jpg"
content_ = requests.get(url_).content
f = open(image, "wb")
f.write(content_)
#Classifiers
face_cascade = cv2.CascadeClassifier(face)
eye_cascade = cv2.CascadeClassifier(eye)
#Image we will predict
img = cv2.imread(image)
plt.imshow(img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Detect face
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
#params = (image, position, width and height, color in RGB scale, and thickness)
img = cv2.rectangle(img, (x,y), (x+w, y+h), (255,0,0), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
#Detect eyes per face
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 2)
#Show image
cv2.namedWindow("image", cv2.WINDOW_NORMAL)
while 1:
cv2.imshow("image", img)
cv2.waitKey(1)
cv2.destroyAllWindows()
Output:

Curso de Redes Neuronales en Keras y Scikit-Learn 2019