Skip to content
Pablo Aguado edited this page Mar 30, 2016 · 93 revisions

Lo que vamos haciendo, problemas que vamos encontrando, issues que abrimos o cerramos.



YYYY/MM/DD - Autor

Texto texto texto texto texto.


2016/01/13 - Pablo Creo el repositorio para que empecemos de vuelta. Voy a intentar ordenar la wiki. Cree un nuevo repositorio para las imagenes y bases de datos en general.


2016/01/15 - Pablo Idea: Dado que la camara está siempre a la misma altura y posición, podemos post-filtrar lo detectado a partir de la base de la persona detecta, que daría su cercanía, y su altura. Problema: y si está parada sobre otro objeto?; además, es muy especifico... EDIT: Podría ser más grande para esa posición de la base, en caso de estar sobre una caja o haber saltado...pero no podría ser más chico.


2015/01/16 - Pablo Leído HOG_01_Dalal_2005 ...complicado. ¿Será necesario que leamos?

LSVM está muy jodido de leer.... Me parece mejor que no leamos nada y que apliquemos nomás.

  1. Diseñar un método de evaluación
  2. Preparar los sets.

Buscar modelos Haar upper body y lower body

Podemos hacer un programa auxiliar para marcar las personas a mano. Bounding box, 4 puntos. De ahí extraer el centro. Podría establecerse un rango de desviación del centro y uno del ancho y la altura. El umbral de desviación del centro puede determinarse a partir del ancho marcado a mano, por ej, y un factor multiplicador. El rango de desviación del ancho y de la altura, proporciones del ancho y altura marcados a mano.

TODO:

  • Buscar forma de seleccionar en OpenCV un rectángulo. O hacerlo en Matlab.
  • GUI?
  • Meter los datos en una tabla. Se podrían leer y meter en un struct por objeto. Luego comparar y concluir.
  • Se pueden discriminar las imagenes en donde está el sujeto entero y donde está partido.

set - número - completo - arriba_izq - arriba_der - abajo_izq - abajo_der

Problemas vistos:

  • HOG es lento como para video..tal vez. El del ejemplo hace 200 ms, ver código.
  • Cuando el tipito está lejos, en las imagenes de profundidad no aparece..

2015/01/17 - Pablo Probé el programa de prueba /home/ppp/opencv/samples/c/facedetect.cpp, que usa Haar cascades, en el set 1, y los resultados no son buenos. Usé el modelo de persona entera y el de lowerbody (/home/ppp/opencv/data/haarcascades/haarcascade_lowerbody.xml). Se puede llamar con un archivo de texto como argumento, que tenga una lista de todas las imagenes a leer. La lista con full paths se puede obtener con ls -1 $PWD/*color.png por ej, para las de color, parado en la carpeta en donde están las imagenes. Para que anduviera comenté

// else if( inputName.size() ) // { // image = imread( inputName, 1 ); // if( image.empty() ) // { // capture = cvCaptureFromAVI( inputName.c_str() ); // if(!capture) cout << "Capture from AVI didn't work" << endl; // } // }

Ejecuté ./testperson2 --cascade="/home/ppp/opencv/data/haarcascades/haarcascade_lowerbody.xml" --scale=1 /home/ppp/vision/dp_databases/set1/dirs_color.txt

-.-.-.-.-.-.-.-.-.-.-.-.--.-.-.-.-.-.-.-.-.-.-

De haarcascade_lowerbody.xml:

KNOWN LIMITATIONS ==================

  1. the detectors only support frontal and back views but not sideviews. Sideviews are trickier and it makes a lot of sense to include additional modalities for their detection, e.g. motion information. I recommend Viola and Jones' ICCV 2003 paper if this further interests you.
  1. dont expect these detectors to be as accurate as a frontal face detector. A frontal face as a pattern is pretty distinct with respect to other patterns occuring in the world (i.e. image "background"). This is not so for upper, lower and especially full bodies, because they have to rely on fragile silhouette information rather than internal (facial) features. Still, we found especially the upper body detector to perform amazingly well. In contrast to a face detector these detectors will also work at very low image resolutions

Igual revisar para ver si se está usando bien el detector - tamaños de imagen de entrada y otros parámetros..


2015/01/18 - Pablo Tras mucho rabiar con opencv/samples/c/latentsvmdetect.cpp (segmentation faults), descubrí que los modelos están de alguna manera malos, ya que sí funciona con el modelo de cat.xml que está en la misma carpeta. Yo probé los modelos person.xml y chairs.xml que están acá: https://github.com/Itseez/opencv_extra/tree/master/testdata/cv/dpm/ pero resulta que esos son para cascadas...porque eso es para la 3.1, en donde al parecer todavía no está (o no va a estar) el detector basado en dpm latentsvm. Los modelos que sirven están en https://github.com/Itseez/opencv_extra/tree/2.4.12.x-prep/testdata/cv/latentsvmdetector , que corresponde a la 2.4. Yo probé con los modelos VOC2010 del trabajo original v5, encontrados acá: https://github.com/rbgirshick/voc-dpm y los convertí con el programa que encontré acá https://github.com/amc-nu/Latent-SVM-MAT2XML-Converter. De cualquier manera, andan muy lento, tardando varios segundos para encontrar la persona, con muchos falsos positivos.

Offtopic1: ¿Cómo se hace para debuggear adentro de la biblioteca? Por que el eclipse no podía entrar..

Offtopic2: Interesante al instalar las bibliotecas a mano: checkinstall


2015/01/21 - Pablo Comienzo milestone Sistema de pruebas


2015/01/22 - Pablo Estuve leyendo de clases en C++. Podríamos hacer una clase detectora que configuremos para cada test.


2015/01/24 - Pablo Comencé rama general, con el programa general. Lee archivos de una carpeta, crea un csv y guarda info.


2015/01/25 - Pablo El formato y su función de guardar (operador<<) están ahora aparte.


2015/01/26 - Pablo Empecé boceto de detectores...no sé como podríamos hacer para automatizar un poco las pruebas y no andar compilando y recompilando. Podríamos usar http://www.boost.org/doc/libs/1_36_0/doc/html/program_options.html ..o ifs de parámetros, pero es complicado de mantener.. Luego podemos llamar con batch de consola.


2015/01/27 - Pablo Empecé y termine la clase abstracta Detector, clase abstracta desde donde podemos derivar los otros detectores. A modo de ejemplo, la clase DetectorDummy, a la cual le falta una función detectar. PD: falta una verificación de argumentos en casi todos lados. Ver también de como usar los errores.


2015/01/28 - Pablo Implementada una función detectar que no hace nada. Con esto considero que está terminado el programa general https://github.com/GERUNSJ/dp_opencv/issues/6 .


2015/02/01 - Pablo Terminado el extractor manual. Cierro #4.

Problemas:

  • Crashea al seleccionar pixeles afuera de la imagen.
  • Qué hacemos con las imágenes que no tienen personas? No marcamos nada?

2015/02/02 - Pablo Comienzo detector_hog.


2015/02/03 - Pablo Termino detector HOG, cierro #11. Ahora el programa también muestra el progreso del proceso. Añadido el argumento bool mostrar_detecciones. Comienzo otro


2015/02/08 - Pablo Leído un poco de las formas de evaluar los resultados. No logro entender el funcionamiento de las curvas ROC o DET. Ahora un poco...pero...qué parámetros podemos variar en nuestros detectores???? Muy poco..


2015/02/09 - Pablo Comienzo con resultados. detecciones multiples...quien las elimina? resultados o detector? ..Creo que es responsabilidad del detector. Hay que agregarselo a HOG entonces.

Avancé con los resultados. Estamos en el mismo repositorio, así que hay que configurar el IDE para que no compile dp_opencv y sí dp_resultados. También se puede cambiar el nombre del ejecutable que genera, en las opciones de Build. En Eclipse, es cuestión de crear una nueva Build configuration, en mi caso, R_DEBUG, y crea una nueva carpeta. http://stackoverflow.com/a/19171230. Acá dicen de ver Git submodules.

Tuve un problema al usar el range-based for con auto, ya que la variable se estaba pasando por valor y no por referencia, y por ende no modificaba los elementos del vector:

for( auto& f : frames )	// Range-based for. Atento al & para pasar por referencia.
	{
		//...
		//
		f.falsos_positivos = f.estimados.size();
		f.falsos_negativos = f.reales.size();
	}

Decidí leer los archivos con fscanf, a lo c. No veo porque recomiendan no hacerlo. REVISAR.


2015/02/11 - Pablo Añadí comentarios a dp_opencv. Usé la función sort, muy interesante.

dp_resultados ya escribe resultados. Cambié la comparación. Ahora para considerar dos cuadros como iguales:

  1. La distancia euclídea entre centros debe ser menor a una proporción P_RADIO del ancho del cuadro.
  2. La diferencia de anchos relativa al ancho real debe ser menor a P_ANCHO.
  3. La diferencia de alturas relativa a la altura real debe ser menor a P_ALTO.
// Importante el orden de los operadores..
bool operator==(const struct_resultados& real, const struct_resultados& est)
{
	float distancia = sqrt( powf((real.centro_x-est.centro_x),2) + powf((real.centro_y-est.centro_y),2) );
	if( distancia < P_RADIO*real.ancho )
		if( abs(est.ancho - real.ancho)/real.ancho  <  P_ANCHO )	// est.ancho < P_ANCHO*real.ancho
			if( abs(est.alto - real.alto)/real.alto  <  P_ALTO )
				return true;
	return false;
}

Arreglé la contabilidad de los falsos negativos. FALTA agregar alguna medida de la bondad de la detección.


2015/02/13 - Pablo Más de resultados. Agrego FPPW (falsos positivos por ventana) - promedio. 100*Miss rate / FPPW nos puede servir como medida general.

Tasa de equivocación(miss rate) = falsos_negativos / (falsos_negativos + verdaderos_positivos) Falsos positivos por ventana(FPPW) = falsos_positivos / n_imagenes_evaluadas

Podemos usar como medida 100 tasa de equivocación / FPPW*

Cerré #7.


2015/02/14 - Pablo Estuve viendo cómo registrar/alinear las imagenes depth y rgb. Al parecer deberíamos calibrar las 2 cámaras como arreglo estéreo, usando el visible de la cámara infrarroja. http://wiki.ros.org/camera_calibration/Tutorials/StereoCalibration Instalé el Matlab para hacer pruebas rápidas. Necesité para que ande el paquete matlab-support.


2015/02/15 - Pablo Empecé rama Matlab para pruebas. Probé la idea de los gradientes, con imagenes de 16 con niveles ajustados (histograma expandido/normalizado a mano en Krita, que soporta 16 bits). De esas imagenes saqué a la persona y a la caja, como muestras.

  • El gradiente horizontal basta, ya que es en el plano horizontal adonde ocurren las mayores variaciones en la "textura" que queremos ver en la persona. Usé filtro [-1,0,1]. Debe almacenarse en int16 y no uint16 para el signo. Luego en opencv hay que ver qué hay y cómo normaliza o satura.
  • Para cuantificar los valores de gradiente sirve un histograma de la imagen de gradientes. Lo terminé haciendo a mano, histogram me devolvía bins unitarios pero desde y hasta el último valor. Se puede seguir probando.
  • Luego analizar la varianza o desviación (diferencia???) del histograma positivo o negativo. Una desviación chica implica que el gradiente tiende a constante, y por ende es una cara plana. Una desviación grande implica variaciones más interesantes. Si no discriminamos entre positivo y negativo podemos llegar a confundir, ya que dos caras planas en esquina, por ej, darían dos lóbulos grandes pero espaciados (uno negativo y uno positivo), con varianza grande.

Probar script2 en carpeta matlab. Ojo, tarda rato por los 16 bits.

>> script2 % Imagen10 depth 16 bits
Elapsed time is 60.069163 seconds.
Caja:
POS	media = 27.993225 	 std = 2278.691140
NEG	media = -27.993225 	 std = 2527.065831	 std_mean = 2402.878485
Elapsed time is 58.997367 seconds.
Tipo:
POS	media = 109.603607 	 std = 11119.902621
NEG	media = -109.603607 	 std = 11280.516330	 std_mean = 11200.209475

Como prueba de concepto. Habría que verificar con más imagenes y objetos. TO DO: ver como queda en 8 bits luego de ajustado el histograma. Luego ver como implementar en opencv 8 bits.


2015/02/16 - Pablo En 8 bits (las mismas imagnes ajustadas) la relación sigue siendo más o menos la misma.

>> script3 % 8 bits
Elapsed time is 0.237928 seconds.
Caja:
POS	media = 26.984375 	 std = 222.333788
NEG	media = -26.984375 	 std = 294.254218	 std_mean = 258.294003
Elapsed time is 0.259820 seconds.
Tipo:
POS	media = 99.242188 	 std = 1094.869954
NEG	media = -99.242188 	 std = 986.160888	 std_mean = 1040.515421

EDIT: Script2 fue probado con imagenes normalizadas de 16 bits, mientras que script3 fue probado con imagenes de 8 pero sin normalización previa. Entonces, no necesitamos normalizar.

Estuve probando con findContours y drawContours, ver ejemplo contours2.cpp, con las imagenes de profundidad. Nos podría ayudar a borrar el fondo, por ejemplo, que tiene muchos agujeros. Basicamente, borrar todo lo que tenga agujeros, suponiendo que no son personas. Sin embargo así nomás con eso no es suficiente, y tampoco hacerlo luego de buscar bordes con sobel (magnitud). Pero podemos hacerlo luego de segmentar con el histograma, para filtrar segmentos.

        for(int i = 0 ; i < hierarchy.size() ; i++)
        {
        	if( hierarchy[i][3] >= 0)
        	{
        		drawContours(antes, contours, i, Scalar(0,0,255), 2,8);
        		imshow("antes", antes);
        	}
        	else
        	{
        		hierarchyfiltrados.push_back(hierarchy.at(i));
        		contoursfiltrados.push_back(contours.at(i));
        		drawContours(antes, contours, i, Scalar(0,255,0), 2,8);
        		imshow("antes", antes);
        	}

        }

bordes Nótese que eliminar a todos los que tienen agujeros implicaría también eliminar al tipo.

Error del día: popear cosas de un vector al recorrerlo en un for clásico. Al popear, me salto un elemento! Hay que hacer a mano un incremento condicional del índice, y no usar el del for. O copiar a un arreglo nuevo.


2015/02/17 - Pablo Comienzo un detector basado en lo que habíamos trabajado en la versión anterior. Descubro nuevamente que calcHist sólo funciona con imagens de 8 bits, por lo que segmentar con la de 16 sólo se podría hacer si construimos el histograma a mano. Así que reuso lo que habíamos programado la otra vez, quedará así en 8 bits por lo pronto.

Comienzo rama detector1. Pasé todo lo que habíamos progamado antes a aux.hpp y aux.cpp. Idea:

  • Apertura para eliminar ruidos.
  • Cierre para cerrar posibles agujeritos chicos en la persona.
  • Filtrado por contornos, eliminar si tiene agujeros
  • Filtrado por relación de aspecto de un rectangulo contenedor
  • Filtrado por dispersión del gradiente, en cada predetección

Necesitamos una clase contenedora (Predeteccion) donde vamos guardando cada posible objeto, y luego filtrando.

Por lo pronto segmenta. Es importante que determinemos una cantidad fija de suavizar_histograma..mucho junta todo y poco separa mucho. Además podemos descartar los primeros segmentos (los más cercanos a la cámara), pero la cantidad a descartar depende de cuan segmentado esté.


2016/02/18 - Pablo La apertura borra ruido pero igual siguen habiendo muchos puntos sueltos, sobre todo en las imagenes lejanas. Extraeremos los contornos como Rect desde boundingRect nomás, porque la extracción correcta (o sea sólo lo que encierra el contorno) significaría un fillpoly y máscaras, y creo que es demasiado procesamiento. Hubiese estado bueno jugar con blobs http://www.learnopencv.com/blob-detection-using-opencv-python-c/ , pero se va a hacer eterno...


2016/02/22, 21 - Pablo Trabajando en el detector1, me pasó que el método copyTo(destino,máscara) no eliminaba lo que había en el destino. Supongo que es a lo que se refiere con

While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.

Así que tuve que limpiar el destino antes. No encontré como limpiar. El método release() a las matrices las destruía y luego tenía errores al usarlas. Terminé asignándoles una matriz nula de 1x1.

class Predeteccion
{
public:
	// auxiliar
	cv::Mat img;

	// Rect que contiene las coordenadas de interes, referidas a la imagen completa.
	cv::Rect rect;

	// Máscara para aplicar a la imagen completa.
	cv::Mat mascara;

	// Mat que contiene la predetección, como porción de la imagen original.
	cv::Mat img_original;

	// Mat que contiene la predetección, como porción de la imagen normalizada.
	cv::Mat img_normalizada;

	// Mat que contiene la predetección, como porción de la imagen procesada.
	cv::Mat img_procesada;

	// Mat que contiene la predetección, como rectángulo dentro de la imagen original.
	cv::Mat rect_original;

	// Mat que contiene la predetección, como rectángulo dentro de la imagen normalizada.
	cv::Mat rect_normalizada;

	// Mat que contiene la predetección, como rectángulo dentro de la imagen procesada.
	cv::Mat rect_procesada;

	void limpiar(void)
	{
//		img.release();
//		mascara.release();
//		img_original.release();
//		img_normalizada.release();
//		img_procesada.release();

//		img = cv::Mat();
//		mascara = cv::Mat();
//		img_normalizada = cv::Mat();
//		img_original = cv::Mat();
//		img_procesada = cv::Mat();

		//img = cv::Mat::zeros( 1, 1, CV_8UC1);
		mascara = cv::Mat::zeros( 1, 1, CV_8UC1);
		img_original = cv::Mat::zeros( 1, 1, CV_8UC1);
		img_procesada = cv::Mat::zeros( 1, 1, CV_8UC1);
		img_normalizada = cv::Mat::zeros( 1, 1, CV_8UC1);
	}

Hasta ahora está guardado todo eso como información de predetección, hay que ver qué nos sirve y cómo. La apertura y el cierre están deformando bastante las máscaras.


2016/02/23 - Pablo Sigo con detector1. Estuve buscando cómo transformar medidas en la imagen a medidas reales. No saqué casi nada en claro, pero encontré algo que al parecer funciona. De aquí saqué que:

Tamaño en imagen = Tamaño real [m] * distancia focal / distancia al objeto [m]

Sorprendentemente el resultado da en pixeles, bastante similar al medido en las imagenes. La distancia focal es extraída directamente de la imagen de profundiad de 16 bits, que está guardada en formato de OpenNI, donde cada pixel tiene el valor de la profundidad real en mm. La distancia focal usada es aproximadamente 580 para la cámara infrarroja) , aunque tendríamos que ver si está guardada en el topic camera_info de ROS.

Según nuestro código de guardar imágenes, las de profundidad que tenemos son de /camera/depth_registered/image_raw, por lo cuál las imágenes de profundidad y color deberían estar alineadas. No lo están - tal vez tengamos que hacer una calibración con las dos cámaras...tal vez.


2016/02/24 - Pablo Funciona el chequeo de altura real basado en la profundidad, es_altura_creible. Para acceder al valor de la imagen de 16 bits tuve que hacer

ushort valor = i_img_profundidad16.at<ushort>(centro_y,centro_x);

Limpia todos las predetecciones chiquitas, pero siguen vivos grandes trozos de pared / fondo. Sigo ahora con lo del gradiente uniforme/no uniforme...

Implementado pero las desviaciones de las personas son chicas comparados con las de las paredes. Además en general son chicas. Verificar todo y matlab. TODO: Ver qué están dando las desviaciones entregadas por meanStdDev.


2016/02/28 - Pablo Más pruebas con la desviación. No me acuerdo qué hice. !


2016/02/29 , 03/01, 03/02 - Pablo

El profesor nos sugirió usar cosas ya hechas y no dejar de aprovechar la información de profundidad, e intentar con seguidores de esqueleto.

EDIT1: Hay indicios de que ha cambiado...

EDIT2 : En Windows con el SDK de Microsoft, no hace falta la psi pose.

EDIT3: Más info respecto a la no necesidad de la psi pose en versiones relativamente nuevas..Cuál?

https://getsatisfaction.com/openni/topics/a_newie_question_what_exactly_is_considered_a_psi_pose_calibration?topic-reply-list[settings][filter_by]=all&topic-reply-list[settings][reply_id]=14128972#reply_14128972 https://forum.openframeworks.cc/t/ofxopenni-pose-calibration-needed/15172/8 https://forum.openframeworks.cc/t/skeleton-tracking-without-calibration-psi-pose/20488/29

*EDIT4: interesante https://github.com/gameoverhack/ofxOpenNI , http://openframeworks.cc/ https://forum.openframeworks.cc/t/skeleton-tracking-without-calibration-psi-pose/20488/30

Conclusión: Lo de guardar un archivo de calibración también ya es viejo. Podríamos intentar hacer andar una versión de OpenNI que no necesite el tracking, pero por fuera de ROS y metiéndonos en OpenNI. No va a andar con el código de openni_tracker de ROS, porque ha sido programado para buscar la pose y con versión vieja. Me parece que meternos en OpenNI no es opción. Además implica dejar OpenCV de lado. Y es pesado en recursos, instalación...y produce mucha información que no es útil para el caso.

¿Tiene sentido no usar OpenCV o similar para el trabajo de visión?

Qué es OpenNI, qué es NITE? - otro

OpenNI is the entire framework for developing applications using "natural interaction" (gestures and so on). It provides an open source API that can be used for supporting different cameras (such as Kinect and Xtion) and algorithms (for body detection, etc.). Without adequate modules OpenNI doesn't do anything.

NITE is just a plugin (also called a module) that works in this framework, developed by PrimeSense. It's proprietary and its sole function is to perform skeleton tracking.

Someone could write another plugin for skeleton tracking (as Microsoft did for its SDK) and make it run inside OpenNI (making the code implement the right interfaces). But since skeleton tracking isn't trivial an open-source alternative doesn't exist yet (please correct me if I'm wrong). Theoretically if there weren't license restrictions I believe someone could even adapt MS algorithm for use as a module in OpenNI, to replace NITE...


  • Skeltrack de Joaquim Rocha utiliza otro enfoque, pero aún así está limitado a una persona y a escenas sin otros objetos.

  • Encontramos un paquete de Human Tracking de ROS Industrial, pero es para Fuerte. Está desarrollado por Matteo Munaro y equipo. No logré hacerlo andar, a pesar de, al parecer, haber compilado correctamente todo - seguí los tutoriales introductiorios de ROS, para rosbuild (esto es antes de catkin)..tal vez estaba andando, pero yo no me dí cuenta. La documentación de uso es poca.

The software first detects and then tracks people in the field of view of the sensors using machine learning techniques. The detection system is a cascade of successively more complex classifiers in the following order:

    Simple geometric consistency test
    Ada Boost Classifier using 174 Haar-like features on the intensity image
    Ada Boost Classifier using 174 Haar-like features on the disparity image
    Support Vector Machine using 174 Haar-like features on the intensity image
    Support Vector Machine using Histogram of Oriented Gradient features

The tracking software implements a particle filter in the x-y plane, and learns on-line using color histograms computed over vertical columns as features.
  • Matteo Munaro también está en el equipo de http://openptrack.org/ . Este anduvo bien, pero crasheaba sin mayor aviso. Tal vez con una instalación limpia funcione. Complejo, corre también sobre ROS Indigo.

  • También probamos la cascada LBP con el modelo de VisionAry, y funcionó mucho mejor que las cascadas de opencv.


Mergeo detector1 así como está, con el master. De allí sigo trabajando para #22


2016/03/03 - Pablo Hice que el programa principal cargue tanto la carpeta a color como la de profundidad. El detector elegido usará lo que tenga que usar. Incluso se puede poner un 0 o una carpeta vacía para explicitar que no se usa.

Comienzo el DetectorFinal, que usará Haar con opción a filtrado con altura estimada por la profundidad. Le falta la profundidad, pero ya anda bien como cascada.

Encontré un posible significado de los flags de detectMultiScale de las cascadas:

DO_CANNY_PRUNING If it is set, the function uses Canny edge detector to reject some image regions that contain too few or too much edges and thus can not contain the searched object. The particular threshold values are tuned for face detection and in this case the pruning speeds up the processing

SCALE_IMAGE For each scale factor used the function will downscale the image rather than "zoom" the feature coordinates in the classifier cascade. Currently, the option can only be used alone, i.e. the flag can not be set together with the others

FIND_BIGGEST_OBJECT If it is set, the function finds the largest object (if any) in the image. That is, the output sequence will contain one (or zero) element(s)

DO_ROUGH_SEARCH It should be used only when CV_HAAR_FIND_BIGGEST_OBJECT is set and min_neighbors > 0. If the flag is set, the function does not look for candidates of a smaller size as soon as it has found the object (with enough neighbor candidates) at the current scale. Typically, when min_neighbors is fixed, the mode yields less accurate (a bit larger) object rectangle than the regular single-object mode (flags=CV_HAAR_FIND_BIGGEST_OBJECT), but it is much faster, up to an order of magnitude. A greater value of min_neighbors may be specified to improve the accuracy.

Creo #24 y #25 relativos a la necesidad teórica de preprocesamiento antes de las cascadas Haar, LBP y el detector HOG, y referidas a lo que efectivamente están haciendo los programas de opencv.


2016/03/04 - Pablo Terminé el final, le agregué la información de profundidad. La cascada sigue detectando aun cuando la información de profundidad se perdió. Creo que conviene usar la cascada sola bien estricta, con muchos minNeighbors (5 o mas) y sacrificar verdaderos positivos a cambio de menos falsos positivos.

Me olvidé de escribir respecto a Matlab y es_gradiente_disperso... por qué el histograma? Es lo mismo hacer la media y desviación de los positivos o negativos. A esto lo probé en el script5.m , pero me daba distinto. Creo que por que, eureka, en el de los histogramas estabamos eliminando el cero, cuando tranquilamente pueden haber muchos ceros dentro del área de interés. Habría que rehacerlo, aunque la idea sigue siendo válida y correcta.

Mergeo resultados y matlab con el master.

Empiezo scritps de automatización, en bash.

Añadí otras medidas de bondad,

	cout << "\nMiss rate * tiempo promedio = " << bondad3;
	cout << "\n100*Miss rate * FPPW * tiempo promedio = " << bondad2;

Bondad 3 sirve en el caso de que FFPW sea 0, pero el miss_rate podría ser alto. Bondad 2 añade el tiempo a la ecuación.


2016/03/05 - Pablo Hice un script base.sh y otro para detector final. Sin embargo las pruebas están todas juntas y desordenadas. Para ser más científicos deberíamos variar sólo un parámetro a la vez, y luego hacer mezclas con lo mejor de lo anterior. Se puede hacer un archivo para cada variación.

Ya lo arreglé, hice muchos archivos para ir variando de a un parámetro. Me dí cuenta de que lo he hecho a todo para el set1, así que voy a tener que modificarlo para hacerlo variable.


2016/03/06 , 07 - Pablo Terminé los scripts. Ahora se puede elegir set, y además los resultados de cada prueba son escritos en un formato tal que puedan ser fácilmente importados a una tabla. Los bash scripts son muy poderosos!

Hay que llamar a llamartodos.sh. Desde ahi se importan los otros.


2016/03/08 - Pablo Añadí la eliminación de duplicados al detectorHOG. Estuve viendo información para capturar los nuevos sets y calibrar las cámaras.

INTERESANTE: http://learn.turtlebot.com/


2016/03/09 - Pablo Estuve viendo más sobre la calibración. Ver el detallado en #27.

  • El turtlebot se niega a transmitir simultaneamente la imagen de la cámara IR y la RGB, por lo cuál la calibración estéreo es inviable.EDIT: Sí se puede, pero es bastante trabajo. Implica simular uno de los streams. Ver acá: http://wiki.ros.org/openni_launch/Tutorials/ExtrinsicCalibration
  • Las imágenes están temporal y espacialmente desfasadas.
  • Las imágenes de profundidad del set1 son tanto registered como rectified, sea lo que sea que signifiquen.

Por lo tanto, lo único que podemos hacer es calibrar cada cámara independientemente. Ya imprimimos los tableros, así que mañana calibro. Luego quedará hacer un set nuevo. Podemos intentar usar la sincronización de suscriptores..


2016/03/10 - Pablo

Calibradas las cámaras del turtlebot 1 con rgb e ir con rosrun camera_calibration cameracalibrator.py image:=/camera/rgb/image_rect_mono camera:=/camera/rgb --size 10x7 --square 0.034

rosrun camera_calibration cameracalibrator.py image:=/camera/ir/image_raw camera:=/camera/ir --size 10x7 --square 0.034


MUCHO DE LO HECHO EN LOS DÍAS NO DOCUMENTADOS ESTÁ EN LOS ISSUES RESPECTIVOS


2016/03/22 - Pablo

  • Calibramos las cámaras de los 2 turtlebots. Se observa menor variación espacial, pero hay. La variación temporal es menor ahora, con suscriptores sincronizados.
  • Tomamos nuevos sets de imágenes. Con 1 persona, 2 personas, y en altura. poner altura en posibles mejoras en las conclusiones
  • Creamos paquetes que usan headers y múltiples cpps. La clave es añadir los cpps y nada más:
# Declare the executable, along with its source files.
add_executable(guardar_imagenes guardar_imagenes.cpp pepito.cpp)

Queda añadir algunas cosas a los detectores, como Blur y normalización de la imagen de profundidad, separar las imagenes de los sets en carpetas, añadir las nuevas variaciones a los batchs y correr todo. Mientras tanto seguimos con el nodo final.


2016/03/23 - Pablo Añadidos blur a HOG y final. Nuevos parámetros en HOG: blurear, tamanio_blur y hit_threshold. Hay variaciones en hit_threshold, pero no encontré mucha información. Podemos probar con 0, 0.1, 0.5, 1, 2


2016/03/29 - Pablo groupRectangles anda, y muy bien. Agrupa los rectangulos cuya relación entre lados sea menor a eps y crea un rectángulo promedio de los agrupados.

C++: void groupRectangles(vector<Rect>& rectList, int groupThreshold, double eps=0.2)

Para agrupar sin eliminar, es cuestión de groupThreshold = 1, y eps según se desee. El detector de cascada y el de HOG lo usan como minNeighbors, pero no permiten variar eps. Ambos lo tienen hardcodeado a 0.2

RUN3 TIENE ALGUNAS CORRECCIONES EN HOG, PERO LO PRINCIPAL ES QUE PARA AMBOS SACAMOS EL AGRUPAMIENTO QUE HACÍAMOS POSTDETECCIÓN, CON NUESTRO CRITERIO. SÓLO SERVÍA SI MINNEIGHBORS ERA MUY BAJO O NULO - Y DE CUALQUIER MANERA HUBIESE SIDO MEJOR USAR GROUPRECTANGLES CON EPS VARIABLE. LO DEJAMOS ASÍ COMO ESTÁ Y QUE AGRUPE CON MINNEIGHBORS (EPS 02). NÓTESE QUE ES TOTALMENTE INVÁLIDO USAR MINNEIGHBORS 0, PORQUE DEJA TODO Y LOS RESULTADOS PARECEN BUENOS PERO SON HORRIBLES.

Clone this wiki locally