Entrenar OpenCV en Detección de Objetos

OpenCV cuenta con varios clasificadores en cascada entrenados que podemos encontrar en el directorio opencv\build\etc\haarcascades ó en opencv\build\etc\lbpcascades estos clasificadores nos sirven para la detección de caras o rostros, nariz, boca, placas de autos, rostros de gatos, entre otras cosas, en caso de que deseemos detectar otro tipo de objeto podemos entrenas nuestros propios clasificadores para que detecte por ejemplo, un animal determinado, un automóvil, un teléfono celular o lo que deseemos según lo requiera el proyecto que realicemos.

opencv object detect
En la carpeta opencv\build\x86\vc11\bin podemos encontrar los ejecutables opencv_createsamples.exe y opencv_traincascade.exe que nos ayudaran ha realizar el trabajo de entrenamiento de manera sencilla, el primero prepara el conjunto de imágenes positivas y el otro genera el clasificador en cascada.

La primera tarea que debemos realizar es recolectar el conjunto de imágenes, necesitaremos un conjunto positivo y uno negativo, el conjunto de imágenes positivas en aquel que contiene varias imágenes con el objeto que deseamos detectar con OpenCV y el negativo son todas aquellas imágenes que no contengan el objeto.

Detección de Autos con OpenCV


Para construir este ejemplo usaremos el conjunto de imágenes obtenidos de Datasets for Computer Vision Research donde encontraremos varios bases de datos de imágenes que podemos utilizar para entrenar OpenCV, seleccionaremos las imágenes para detectar autos UIUC Image Database for Car Detection

car dataset opencv


Lo primero que haremos será abrir CMD y ejecutar con el comando:
cd C:\opencv\build\x86\vc11\bin
Nos movemos a la carpeta que contiene las aplicaciones opencv_createsamples.exe y opencv_traincascade.exe.

Usaremos el siguiente comando para crear el archivo binario cars.vec correspondiente a las imágenes positivas, usaremos la aplicación opencv_createsamples.exe también requerimos la carpeta con las imágenes positivas, la llamaremos pos, además del archivo de texto cars.info que nos indica donde localizarlas.

Por facilidad copiamos el archivo cars.info y la carpeta pos en la misma carpeta donde se encuentra el ejecutable opencv_createsamples.exe

opencv_createsamples -info cars.info -num 550 -w 48 -h 24 -vec cars.vec

opencv_createsample.exe

Una vez tenemos el binario cars.vec procedemos a crear el cascade.xml esta vez usaremos la aplicación opencv_traincascade.exe, esta vez necesitaremos el archivo neg.info y la carpeta neg con las imágenes negativas.

Copiamos neg.info y carpeta neg en el directorio donde anterior, además creamos una carpeta llamada data, donde se almacenara nuestro cascade.xml.

opencv_traincascade -data data -vec cars.vec -bg neg.info -numPos 500 -numNeg 500 -numStages 10 -w 48 -h 24 -featureType LBP

Para conocer detalles sobre las aplicaciones opencv_createsamples, opencv_traincascade y sus parámetros visitar la documentación: Cascade Classifier Training

Cargar Clasificador en Cascada


El siguiente código nos muestra como cargar el clasificador que acabamos de crear, funciona igual que cualquier otro clasificador, incluso podemos usar el código del proyecto Detección de Rostros en Tiempo Real solo cambiamos el clasificador .xml y podremos detectar autos con la webcam.

Para este ejemplo usaremos las imágenes de prueba que vienen con la base de datos que descargamos, haremos que la aplicación pruebe con un grupo de las primera 20 imágenes, las mismas irán cambiando al presionar una tecla.

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{

	String TEST_DIR = "data\\data_file\\test";
	String CAR_CXML = "data\\data_file\\cascade.xml";
	String NAME_WIN = "Entrenar OpenCV";

	CascadeClassifier car_detector;

	if (!car_detector.load(CAR_CXML)) { cout << "Error en el archivo: " + CAR_CXML << endl; return -1; };

	for (int i = 0; i < 20; i++)
	{
		std::stringstream number;
		number << i;

		String image_test = TEST_DIR + "\\test-" + number.str() + ".pgm";
		Mat image = imread(image_test, 1);

		if (!image.data) { cout << "No image data." << endl; return -1; }

		std::vector<Rect> rc;

		car_detector.detectMultiScale(image, rc, 1.1, 8);

		for (size_t i = 0; i < rc.size(); i++)
		{
			rectangle(image, Point(rc[i].x, rc[i].y), Point(rc[i].x + rc[i].width, rc[i].y + rc[i].height), CV_RGB(0, 255, 0), 1);
		}

		namedWindow(NAME_WIN, WINDOW_AUTOSIZE);
		imshow(NAME_WIN, image);
		waitKey(0);
	}

	return 0;
}


Debemos tener en cuenta que nuestro clasificador no es perfecto, está construido de la manera más simple posible, un clasificador bueno requiere de una colección de imágenes positivas y negativas bastante amplia.

Especificando los parámetros adecuados a la hora de crear el clasificador podemos mejoras su eficacia, pero debemos tener en cuenta que un buen entrenamiento puede tardar muchas horas o hasta días.

Puedes encontrar el proyecto completo en: GitHub Tutor de Programación

Comentarios

  1. hola! no encuentro el archivo cars.info... sólo he encontrado un readme.txt...

    ResponderEliminar
    Respuestas
    1. Puedes encontrar los archivos necesarios en la carpeta image_dataset que se encuentra en el repositorio GitHub.
      https://github.com/TutorProgramacion/opencv-traincascade
      Olvide subirla, gracias por el comentario.

      Eliminar
  2. gracias, es que encontré el archivo de otro repositorio, pero creo que no es el mismo... y las carpetas neg y pos, las he hecho partiendo en dos el archivo donde están todas las fotos. Bueno, voy a intentarlo de nuevo con los nuevos archivos...-porque me está dando error en el .exe de createsamples y en el array.cpp Gracias.Un saludo

    ResponderEliminar
  3. Ya he cambiado los archivos, gracias. Una última pregunta: Para el test de "entrenamiento", el .cpp lo ejecuto desde dónde? Gracias de antemano

    ResponderEliminar
  4. Hola de nuevo, lo he compilado y ejecutado con Dev_Cpp, pero no encuentra opencv.hpp-

    ResponderEliminar
  5. He puesto todo el camino para que encuentre el archivo y parece que funciona, pero todavía no lo he conseguido del todo...

    ResponderEliminar
  6. Ya lo he solucionado. Gracias, era la plataforma al hacer el build.

    ResponderEliminar
    Respuestas
    1. Que bueno que lo solucionaras por tu cuenta, pequeños detalles hacen una gran diferencia.

      Eliminar
  7. Hola, no tienen este ejemplo en Python? :c

    ResponderEliminar
  8. Puedes hacer tutoriales de Reconocimiento Facial, Pero usando el Lenguaje Java, pues he visto varios tutoriales suyos, escritos en c++, pero se me dificulta traducirlo a java. Tambien seria bueno que hicieras un tutorial en donde se explique como detectar si la persona está dormida, y hacer sonar una alarma. Yo he realizado parte de los dos proyectos que he mencionado, pero no he podido terminarmlos.. No encuentro la solucion. Gracias.

    ResponderEliminar
  9. Buenas, estoy trabajando en la version 3.1 y con ubuntu. Al ejecutarlo el codigo se me queda colgado. Tengo unos printf para ver hasta donde ejecuta y se para en : "Mat image = imread(image_test, 1);"

    Sabes por que puede ser?
    Muchas gracias.

    ResponderEliminar
  10. Todos estos tutoriales se los puede trabajar con python tambien ?

    ResponderEliminar
  11. hola muy buenos dias profe, estoy tratando de crear un clasificador que reconozca las manos , he seguido algunos tutoriales pero en el momentos de crear el vector me arroja un error de analisis sobre al archivo indice, en este caso se utiliza es un archivo positive.txt, he compilado su ejemplo del tutorial sin ningun problema el cual trae un archivo cars.info y la carpeta pos y muestra la creacion del vector , las imagenes tienen que tener un tratamiento en especial o un peso en especial? yo utilizo las fotos en formato bmp de 320x240 y creo el archivo indice con objectmarker , no he podido encontrar el error

    ResponderEliminar
    Respuestas
    1. Es difícil saber donde está el problema, pero se me ocurre que podría estar al momento de usar opencv_createsample.exe asegúrate de que los parámetros -w y -h correspondan al ancho y alto de tus imágenes.

      Otra cosa podría ser que el archivo positive.txt no apunta correctamente a la ruta en donde se encuentran las imágenes.

      Eliminar
  12. y otra inquietud como se hace para crear el archivo .info o no varia al trabajar con .txt

    ResponderEliminar
    Respuestas
    1. Lo importante es el contenido, la extensión puede ser cualquiera: .info, .txt, etc.

      Eliminar
  13. buenos dias lo he intentado ya varias veces pero me crea el vector vacio se presenta un error parse errorDone , yo utilizo objectmarkert y despues creo el directorio para el archivo positivo.txt pero me presenta ese error al intentar crear el vector

    ResponderEliminar
  14. ya lo he intentado con otras fotos y tampoco, pero en cambio el que esta en el tutorial si crea el vector sin ningun tipo de error

    ResponderEliminar
  15. si el formato de las fotos es de 240x320 como calculo el w y h para el comando shell o serian las mismas medidas?

    ResponderEliminar
  16. ahi un medio de tener contacto donde pueda enviarte pantallazos del procedimiento y el error que se presenta al tratar de crear el vector , para hallar una solucion al problema

    ResponderEliminar
  17. o si tu me puedes enviar los pasos a seguir , de pronto los tutoriales que he seguido hace falta algo ,

    ResponderEliminar
    Respuestas
    1. Envíame un link con lo que tienes y lo revisaré, veremos que podemos hacer, no incluyas todas las imágenes solo un par de ellas para que el archivo no sea de gran tamaño.

      Eliminar
  18. listo hare el link con la imagenes mas detalladas, encontre un documento en el cual viene un poco mas explicado los parametros de objectmarket y de createsamples, donde habla de unas dll que debe tener el create samples para funcionar , lo extraño es que los datos que tu proporcionas en el tutorial de clasificador de carros, con ellos logro crear los samples sin ningun error, sin esas dll.
    cxcore097.dll, highgui097.dll, libguide40.dll

    ResponderEliminar
  19. No he podido dar con el error , al parecer es el ingreso de los imágenes , pero son imágenes del mismo tamaño, en escala de gris y tampoco me deja crear los samples, tan pronto pueda te envio el link

    ResponderEliminar
  20. Bueno profe ya he solucionado el problema , revise los direcciones y los tamaños pero el error estaba era que la version del createsamples que venia en el tool zip de haartraining son de versiones diferentes a la que estoy utilizando .

    ResponderEliminar
  21. bueno profe hasta el momento he llegado hasta ahi porque estoy intentando crear el archivo xml pero me esta presentando un error , y me pide revisar los parametros de training, voy a tratar de enviarle un link, bueno tambien estoy trabajando en encontrar el error .
    Profe tenia una pregunta acerca del codigo de entrenamiento de rostros , y el de clasificacion de genero , si bien estos codigos estas adecuados para entrenar rostros y tambien detectar e identificar rostros, en el caso de querer reconocer gestos manuales como lenguaje de señas, podria hacerlo cambiando el archivo xml , y modificando parte del codigo para que entrene señas

    ,

    ResponderEliminar
  22. hola profe queria saber si una pagina en la que usted ofrece asesorias que se llama workana , que tal confiable es ya que un desarrollador esta interesado en colaborarme con el proyecto. pero no tengo la informacion suficiente de esta pagina para decidirme a depositar

    ResponderEliminar
    Respuestas
    1. Workana es una plataforma de trabajo freelancer, es de las mas conocidas en latino américa, la plataforma funciona correctamente pero debes prestarle atención al profesional que te ayudará, mira su perfil, pídele que te muestre algunos de sus trabajos, etc., si el profesional no cumple con lo estipulado puedes solicitar a la plataforma la devolución de tu deposito.

      Eliminar
  23. ok . si pues la pregunta es si la pagina era de confianza, ya sabes por tanto fraude electronico en la actualidad

    ResponderEliminar
  24. revisare con calma el perfil del profesional, muchas gracias..

    ResponderEliminar
  25. Tienen que ser imagenes pgm o pueden ir en otro formato?
    Que significan los numeros 1 0 0 100 40 al final de cada linea en el archvo cars.info?

    ResponderEliminar
    Respuestas
    1. Puede ser otro formato de imagen siempre que el mismo esté soportado por OpenCV.

      En el archivo cars.info los números indican lo siguiente:

      1 - cantidad de imágenes presentes, en un archivo de imagen pueden aparecer por ejemplo 2 autos.

      0 0 100 40 - Es el rectángulo en donde se encuentra el auto, de haber 2 deberás indicar igual número de rectangulos.

      Eliminar
  26. Hola he realizado estos paso pero no me crea el archivo .vec? que estoy haciendo mal?

    ResponderEliminar
    Respuestas
    1. me aparece esto al final del cmd
      Done. Created 0 samples

      Eliminar
    2. Asegúrate de tener las imágenes en las carpetas correctas.

      Eliminar
  27. como puedo crear los archivos con terminación .info

    ResponderEliminar
  28. Enlace roto >> http://www-cvr.ai.uiuc.edu/ponce_grp/data/

    ResponderEliminar
  29. He instalado opencv a través de Anaconda y no soy capaz de encontrar los directorios que comentas, no tengo ningún directorio con el nombre de opencv

    ResponderEliminar
    Respuestas
    1. Esta publicación es un poco antigua, si deseas hacer detección de objetos en la actulizadad es mejor usar redes neuronales usando el módulo DNN de OpenCV aquí puedes ver un tutorial: https://acodigo.blogspot.com/2019/03/cargar-modelos-tensorflow-en-opencv-dnn.html

      Eliminar
  30. el archivo cars.info , imagino que funciona solamente para el fin de detectar carros, ¿Como creo con la informacion correcta mi propio .info?

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

Histogramas OpenCV Python

Modelo de Iluminación Phong - Tutorial OpenGL

tkinter Canvas