Detección de rostros

Opencv nos facilita la terea de detectar rostros pues ya cuenta con clasificadores entrenados para esta tarea almacenados en archivos xml, pero en caso de que lo necesitemos podemos crear nuestros propios clasificadores, además de contar con todas las funciones necesarias para esta tarea.

Detección de rostros en opencv


Para detectar un rostro primero debemos procesar la imagen en la cual deseamos buscar un rostro, luego de cargar la imagen debemos aplicar los siguientes pasos:

Convertir la imagen a escala de grises, necesario para el correcto funcionamiento de los algoritmos de detección de rostros usados por opencv. Para convertir una imagen a escala de grises u otro formato contamos con la función cvtColor.

cvtColor(imagen, imagen, CV_BGR2GRAY);

Lo siguiente que debemos hacer es aplicar ecualización de histograma a la imagen en grises para estandarizar el contraste y brillo de la imagen, esto para que distintas condiciones de iluminación no afecten la detección del rosto en la imagen.

equalizeHist(imagen, imagen);

Con esto tendremos este resultado:


Para aumentar la velocidad de detección del algoritmo podemos escalar la imagen a un tamaño más pequeño no demasiado.

Con la imagen procesada ahora debemos cargar el detector que deseamos utilizar, pasaremos el nombre del clasificador al método load de la clase CascadeClassifier, los archivos .xml que debemos cargar se encuentran en C:\Opencv\data aquí encontraremos varias carpetas que contienes distintos clasificadores, en la carpeta C:\Opencv\data\haarcascades se encuentran varios clasificadores no solo para detectar rostros sino también para la detección de ojos, boca, nariz, entre otros.

Para detectar rostros de frente usaremos haarcascade_frontalface_alt.xml, para detectar cuerpo completo podemos usar haarcascade_fullbody.xml, para detectar ojos contamos con haarcascade_eye.xml, existen muchos otros.

CascadeClassifier detector;

if(!detector.load("haarcascade_frontalface_alt.xml"))
       cout << "No se puede abrir clasificador."<< endl;

Ahora podemos detectar los rostros presentes en la imagen

vector<Rect> rect;
detector.detectMultiScale(dest, rect);

Las caras detectadas serán almacenadas en el vector rect, solo debemos recorrerlo y marcar las caras encontradas

for(Rect rc : rect)
{
       rectangle(imagen,
                   Point(rc.x, rc.y),
                   Point(rc.x + rc.width, rc.y + rc.height),
                   CV_RGB(0,255,0), 2);
}


Código C++ Detección de Rostros:


Detección de rostros en tiempo real


Para detectar rostros en tiempo real solo debemos leer las imágenes de la webcam y aplicarle a cada una de ellas el procedimiento descrito anteriormente, para ver cómo usar la webcam.

Código de ejemplo para detectar rostros en tiempo real mediante el uso de la cámara web opencv.
Parámetros de la función de detección de rostros:

detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
  • image: imagen prosesada.
  • objectcs: vector donde se almacenara las coordenadas de las caras encontradas.
  • scaleFactor: factor de escala, 1.2 más rápido.
  • minNeighbors: factor para prevenir falsas detecciones.
  • flags: parámetro actualmente no es usado, indicar 0.
  • minSize, maxSize: tamaño máximo y mínimo de ventana usado para detectar rostros, limita la detección de rostros muy pequeño o demasiado grandes.

Espero les sirva de ayuda, más adelante veremos como reconocer o identificar un rostro, hasta la próxima.

Comentarios

  1. me arroja este error: error C2143: syntax error : missing ',' before ':'

    ResponderEliminar
    Respuestas
    1. Dame mas detalles del error, puede ser que uses un compilador que no admite C++ 11.

      Eliminar
    2. Es con el tema de: for(Rect rc:rect), no se que compilador ocupara visual studio 2010, podra ser por eso?

      Eliminar
    3. en que linea ? xddd puede ser que te conmiste un punto y coma justo en la linea de arriba ? xd o por el ciclo for si ...

      Eliminar
    4. tengo el mismo error ya lo pudiste solucionar?

      Eliminar
    5. //use la siguiente linea
      for(size_t i = 0; i < rect.size(); i++ )
      {

      rectangle(imagen,Point(rect[i].x, rect[i].y),Point(rect[i].x + rect[i].width, rect[i].y + rect[i].height),CV_RGB(0,255,0), 2);

      }

      Eliminar
  2. hola que librerías de open cv usas yo estoy con el 2.4.8 y me muestra las imágenes pero no con la detención de rostros, me arroja el siguiente error No se puede abrir clasificador.

    ResponderEliminar
    Respuestas
    1. Los clasificadores se encuentran en la carpeta de instalación de opencv.

      opencv\data\haarcascades

      Debes cambiar la ruta para que encuentre el clasificador o puedes copiar el clasificador en la carpeta raíz del proyecto.

      Eliminar
  3. ayuda xfavor al compilar este codoigo me sale el error range-based for loops are not allowed in c++98 mode y es debido a esta linea de comando(linea 29) " for(Rect rc : rect)" lo que leí es que este comando solo se ejecuta en c++11 ...no se que hacer si actualizar el compilador ya que estoy usando qt5.1.0 y opencv 2.4.9 ..o cambiar esa linea de comando para escribir con c++98 ...si alguien tiene una solucion xfavor ayuda

    ResponderEliminar
    Respuestas
    1. Puedes cambiar esta linea de código de este modo:
      for(int i = 0; i < rect.size(), i++) { Rect rc = rect[i];
      //......
      Reemplaza la linea #29 y la #30, si tienes dificultades me avisas.

      Eliminar
    2. si ya lo puede solucionar muchas gracias x el aporte

      Eliminar
    3. amigos me sale el mismo error me pueden ayudar a solucionarlo x favor?

      Eliminar
  4. una pregunta adicional estube revisando informacion y encontre que se puede ejecutar el codigo en forma paralela y optimizar el uso de los nucles d la pc con TBB de intel ...estoy tratando de contruir esta biblioteca con cmake ...pero dicen q debo construir primeramente con mingw32-make y la verdad ya voy algun tiempo y no e podido incluir esto a mi proyecto si saben algo de como solucionar esto x favor ayundemen ¡¡¡¡¡¡

    ResponderEliminar
  5. hola ,podrias ayudarme,porque me sale:
    OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file C:\b
    uildslave64\win64_amdocl\2_4_PackSlave-win32-vc11-shared\opencv\modules\imgproc\
    src\color.cpp, line 3737

    ResponderEliminar
  6. Hola amigos, buen aporte. Soy nuevo usando esta libreria y tratando de hacer un proyecto en QtCreator 5.3.1 el programa compila pero me arroja el siguiente error:

    QMetaType::registerType: Binary compatibility break -- Size mismatch for type 'QPaintBufferCacheEntry' [1024]. Previously registered size 0, now registering size 12.
    The program has unexpectedly finished.

    Agradeceria mucho su ayuda. Saludos

    ResponderEliminar
  7. Y pensar que yo me mate buscando el algoritmo de canny y programandolo tarde una semana :grin: y ya hay una libreria que lo hace, y bastante bien xd mañana pruebo esta libreria, la estoy bajando ...

    ResponderEliminar
  8. Buen día.

    Estuve compilando el código, pero me salen varios errores. el primero creo q tiene q ver con la inclusión de librerías. El mensaje es el siguiente:

    Description Resource Path Location Type
    referencia a `cv::CascadeClassifier::~CascadeClassifier()' sin definir TestPrj.cpp /TestPrj/src line 10 C/C++ Problem


    Me podría orientar por favor Agradezco su ayuda

    ResponderEliminar
  9. hHola , muchas GRAcias por las notas; tuve dos errores y necesito ayuda; el primero es que el comando CascadeClassifier sale como no identificado; Se que mi carpeta Data se encuentra dentro de la carpeta Sources y quiza esa sea la raxon, hice etc cosas como copiar la carpeta Data fuera, o el mismo XMl pero nada, por favor ayuda; y el sgt error es for(Rect rc : rect) ; aparece c++ 98 no permite esto , Ayuda y Bendiciones , gracias por tus aportes.

    ResponderEliminar
    Respuestas
    1. MAS ARRIBA PARECE QUE SE CORRIGE CAMBIANDO POR LAS LINEAS
      Puedes cambiar esta linea de código de este modo:
      for(int i = 0; i < rect.size(), i++) { Rect rc = rect[i];
      //......
      Reemplaza la linea #29 y la #30, si tienes dificultades me avisas.

      Eliminar
  10. hola me sale este error en code blocks.
    ||=== Build: Debug in opencv-test3 (compiler: GNU GCC Compiler) ===|
    obj\Debug\objectDetection.o||In function `main':|
    C:\Users\leo\Desktop\codeblockproyectos\opencv-test3\objectDetection.cpp|10|undefined reference to `cv::CascadeClassifier::CascadeClassifier()'|
    C:\Users\leo\Desktop\codeblockproyectos\opencv-test3\objectDetection.cpp|11|undefined reference to `cv::CascadeClassifier::load(std::string const&)'|
    C:\Users\leo\Desktop\codeblockproyectos\opencv-test3\objectDetection.cpp|27|undefined reference to `cv::CascadeClassifier::detectMultiScale(cv::Mat const&, std::vector, std::allocator > >&, double, int, int, cv::Size_, cv::Size_)'|
    C:\Users\leo\Desktop\codeblockproyectos\opencv-test3\objectDetection.cpp|43|undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'|
    C:\Users\leo\Desktop\codeblockproyectos\opencv-test3\objectDetection.cpp|43|undefined reference to `cv::CascadeClassifier::~CascadeClassifier()'|
    ||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

    como lo puedo solucionar? muchas gracias..

    ResponderEliminar
    Respuestas
    1. Tienes que añadir a tus librerías opencv_objdetect249.lib (en el caso de estar usando opencv 2.4.9

      Eliminar
  11. ¿Hay alguna manera de compilar el programa en Ubuntu sin usar un IDE?

    ResponderEliminar
  12. Hola, en mi caso, me dice que no puede cargar el archivo xml, si esta la ruta correcta

    ResponderEliminar
  13. Se produjo una excepción:infracción de acceso de lectura.
    std::vector,std::allocator > >::operator[](...) devolvió 0x1F00994F000.

    En esté caso que se puede hacer ? de antemano gracias por atender mi consulta

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Conectar SQL Server con Java

Instalar OpenCV para Python en Windows