Detectar los ojos es un segundo paso: primero se encuentra la cara y luego se buscan los ojos solo dentro de ella. Así se va más rápido y no aparecen «ojos» en la ropa o en el fondo.
También te puede interesar
CascadeClassifier ya no viene en el paquete normal. Con pip install opencv-python el código de siempre falla así:AttributeError: module 'cv2' has no attribute 'CascadeClassifier'Se ha trasladado al paquete
opencv-contrib-python, y los archivos XML de las cascadas ya no se instalan con él: hay que bajarlos aparte. Lo que el paquete normal trae ahora es un detector basado en redes neuronales, mejor en casi todo. Las dos opciones están en esta página.Con cascadas Haar
pip install opencv-contrib-python-headless
Hacen falta dos archivos de cascada, haarcascade_frontalface_default.xml y haarcascade_eye.xml, que se bajan del repositorio opencv_contrib. La versión anterior de esta página los cargaba desde C:/Users/decodigo/opencv-3.4.6/…, que solo existía en un ordenador.
import cv2
caras_det = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
ojos_det = cv2.CascadeClassifier("haarcascade_eye.xml")
imagen = cv2.imread("tripulacion.jpg")
gris = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)
for (x, y, w, h) in caras_det.detectMultiScale(gris, 1.1, 5, minSize=(60, 60)):
cv2.rectangle(imagen, (x, y), (x + w, y + h), (255, 100, 30), 3)
zona_gris = gris[y:y + h // 2, x:x + w]
zona_color = imagen[y:y + h // 2, x:x + w]
ojos = ojos_det.detectMultiScale(zona_gris, 1.1, 8, minSize=(15, 15))
print(f"cara en ({x}, {y}): {len(ojos)} ojos")
for (ox, oy, ow, oh) in ojos:
cv2.rectangle(zona_color, (ox, oy), (ox + ow, oy + oh), (60, 200, 60), 2)
cv2.imwrite("resultado_ojos.jpg", imagen)salidacara en (523, 164): 2 ojos cara en (806, 354): 1 ojos cara en (248, 332): 2 ojos cara en (683, 596): 0 ojos

Lo que hay que entender del código
La zona de búsqueda es la mitad de arriba de la cara: gris[y:y + h // 2, x:x + w]. Una imagen en OpenCV es una matriz de NumPy, y recortarla es indexarla, primero por filas —la y— y luego por columnas —la x—, al revés de como se escriben las coordenadas. En la mitad de abajo no hay ojos, y buscando ahí la cascada confundiría las comisuras de la boca con ojos.
zona_color no es una copia, es una vista de la imagen original. Por eso los recuadros que se dibujan en ella aparecen en la imagen completa, en su sitio, sin sumar las coordenadas de la cara.
Los resultados cuentan una historia. A Aldrin se le escapa un ojo porque sonríe y casi lo cierra. Y la cuarta «cara», en (683, 596), tiene cero ojos: es el bolsillo del traje que la cascada confundió con una cara, como se explica en la página de detección de rostros. Exigir dos ojos es, de hecho, un filtro sencillo para descartar falsos positivos.
Con YuNet, los ojos ya vienen
El detector moderno de OpenCV devuelve, además del recuadro, cinco puntos de cada cara, y los dos primeros son los ojos. No hay que buscarlos en un segundo paso:
nombres = ["ojo der.", "ojo izq.", "nariz", "boca der.", "boca izq."]
print({n: (int(caras[0][4 + 2*i]), int(caras[0][5 + 2*i])) for i, n in enumerate(nombres)})salida{'ojo der.': (282, 376), 'ojo izq.': (330, 374), 'nariz': (312, 402), 'boca der.': (284, 421), 'boca izq.': (328, 421)}«Derecho» e «izquierdo» desde el punto de vista de la persona fotografiada, no del que mira. El ejemplo completo, con la instalación y el modelo, está en la página de detección de rostros. Y si necesitas mucho más detalle que cinco puntos —el contorno de los ojos, de la boca, de la mandíbula—, eso es lo que hace dlib.
Todo el código se ejecutó con Python 3.14 en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.
Hola, disculpe la molestia pero no me dice que tengo un error en if cv2.waitkey(1) & 0xFF == ord(‘q’):
Si copiaste al código tal cual, hay un «amp;» después del ampersand, ya se corrigió, una disculpa.
A mi copiandolo tal cual me da error.
Hola, algo tarde pero te comento que lo solucioné a ese error quitando el & 0xFF .
if cv2.waitkey(1) == ord(‘q’): un dato es que si lo pones con 0 el waitkey te bota capturas que cambian cuando presionas otra tecla que no sea la ‘q’ para cortar el ciclo.
if cv2.waitkey(0) & == ord(‘q’):
donde estan los archivos haar
hola me arroja este error,saludos
File «C:/Users/xxx/Desktop/open CV test.py», line 23
if cv2.waitKey(1) & 0xFF == ord(‘q’):
^
SyntaxError: invalid syntax
Process finished with exit code 1
Hola, algo tarde pero te comento que lo solucioné a ese error quitando el & 0xFF .
if cv2.waitkey(1) == ord(‘q’):
Hola,
me da error de sintaxis » if cv2.waitKey(1) & 0xFF == ord(‘q’): » en el amp.
SyntaxError: invalid syntax
>>> break
File «», line 1
break
^
Te pasaste! muchas gracias funciono de inmediato!, solo me falta investigar com realizar un enrolamiento y detectarlo
También me causaba error en línea 23, para corregir quiten esto: amp;
y funciona muy bien. La ruta es de donde guaradron opencv, por ejemplo en mi caso es:
face_cascade = cv2.CascadeClassifier(
‘C:/Users/maria/Downloads/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml’)
disculpa y como hago un frame de cv.circle en lugar del rectangulo! cual es el codigo?
gracias
tinen que borrar el «amp;» esta por demas.
Hola, muy util tu ejemplo, me sirvio para terminar de comprender los haar***.xml, ya que el ejemplo de la documentacióon de opencv me daba un error de empty sobre faceCascade. Si quisiera consultarte por la constante 0xFF, que significa o a que hace referencia. Desde ya muchas gracias!
Que tal Nelson, es una línea algo confusa en realidad.
La respuesta es la siguiente:
cv2.waitKey(1) & 0xFF == ord(‘q’)
1.- cv2.waitKey(1) devuelve un entero de 32 bits correspondiente a la tecla presionada.
2.- & 0xFF aplica una máscara al valor devuelto anteriormente, establece los 24 bits a la izquierda en cero, porque ord() devuelve un valor entre 0 y 255, ya que los valores del teclado tienen un conjunto de caracteres limitado.
3.- Una vez que la máscara es aplicada, es posible comprobar si el valor capturado es igual a lo que devuelve la funcion ord(‘q’).
En resumen, la operación & 0xFF te permite ajustar los valores para poder compararlos.
muy bueno pero una pregunta cuando la camara reconozca a la persona como guardaría el nombre en una base de datos como seria la inserción.GRACIAS