Beruflich Dokumente
Kultur Dokumente
1 2 Introduccin........................................................................................................... 4 Algoritmo mastitis ................................................................................................. 5 2.1 Documentacin de clases................................................................................. 5 2.1.1 Referencia de la clase CV ................................................................ 5 2.1.1.1 cvThreshold................................................................................... 5 2.1.1.2 cvFindContours ............................................................................ 7 2.1.1.3 cvContourArea.............................................................................. 8 2.1.1.4 cvBox2D........................................................................................ 9 2.1.1.5 cvFitEllipse ................................................................................... 9 2.1.2 Referencia a la clase HighGUI ........................................................ 11 2.1.2.1 cvNamedWindow ......................................................................... 11 2.1.2.2 cvDestroyWindow ......................................................................... 11 2.1.2.3 cvShowImage ................................................................................ 12 2.1.2.4 cvWaitKey ..................................................................................... 12 2.1.2.5 cvLoadImage................................................................................. 12 2.1.2.6 cvSaveImage ................................................................................. 13 2.1.3 Referencia a la clase CxCore ........................................................... 14 2.1.3.1 IplImage........................................................................................ 14 2.1.3.2 CvPoint ......................................................................................... 16 2.1.3.3 CvPoint2D32f ............................................................................... 17 2.1.3.4 CvSize ........................................................................................... 17 2.1.3.5 cvCreateImage .............................................................................. 18 2.1.3.6 cvCloneImage ............................................................................... 18 2.1.3.7 CvMemStorage.............................................................................. 19 2.1.3.8 cvCreateMemStorage.................................................................... 20 2.1.3.9 CvSeq ............................................................................................ 20 2.1.3.10 cvCvtSeqToArray ........................................................................ 22 2.1.3.11 CV_RGB ..................................................................................... 22 2.1.3.12 cvDrawContours......................................................................... 23 2.1.3.13 cvZero ......................................................................................... 23 2.1.3.14 CvScalar ..................................................................................... 24 2.1.3.15 CvSize ......................................................................................... 24 2.1.3.16 CvArr .......................................................................................... 25 2.1.3.17 cvCmp ......................................................................................... 25 2.1.3.18 cvGetSize..................................................................................... 26 2.1.3.19 cvRound ...................................................................................... 26 2.1.3.20 cvEllipse...................................................................................... 27 2.2 Algoritmo......................................................................................................... 28 2.2.1 Explicacin del cdigo..................................................................... 29 2.2.1.1 Includes......................................................................................... 29 2.2.1.2 Declaracin e inicializacin de variables .................................... 29 2.2.1.3 Mostrar Imagen ............................................................................ 32 2.2.1.4 Inicio del main .............................................................................. 33 2.2.1.5 Obtencin de los contornos exteriores ......................................... 37 2.2.1.6 Clculo del rea de los contornos ................................................ 38 2.2.1.7 Eliminacin de los contornos exteriores....................................... 42 2.2.1.8 Clculo del nmero de clulas...................................................... 44 2.2.1.9 Tratamiento imagen final.............................................................. 53 Haartraining ........................................................................................................... 56 3.1 Proceso............................................................................................................. 56 3.2 Imgenes de entrenamiento ............................................................................. 56 3.2.1 Createsamples .................................................................................. 57 3.2.2 Muestras positivas............................................................................ 59
3.2.2.1 Imgenes simples .......................................................................... 59 3.2.2.2 imgenes clulas ........................................................................... 62 3.2.3 Muestras negativas........................................................................... 64 3.2.3.1 Imgenes simples .......................................................................... 64 3.2.3.2 Imgenes clulas........................................................................... 67 3.3 Comando Haartraining..................................................................................... 70 3.4 Performance..................................................................................................... 80 3.5 Creacin de ejemplos (Application) ................................................................ 87 3.6 Ubicacin de los archivos................................................................................ 90
Lista de Figuras
Figura 1: cvThreshold ........................................................................................................................................6 Figura 2: Ejmplo de estructura IplImage..........................................................................................................16 Figura 3: Imagen pasada como parmetro........................................................................................................28 Figura 4: Primera imagen mostrada .................................................................................................................34 Figura 5: Imagen inicial binarizada..................................................................................................................36 Figura 6: Bordes exteriores ..............................................................................................................................40 Figura 7: Imagen en blanco y negro sin bordes exteriores...............................................................................42 Figura 8: Clculo de elipses (2)........................................................................................................................49 Figura 9: Clulas eliminadas ............................................................................................................................51 Figura 10: Imagen final ....................................................................................................................................54 Figura 11: Parmetros fichero de ndices .........................................................................................................57 Figura 12: Fondo y primer plano de la imagen simple.....................................................................................59 Figura 13: Muestras positivas aleatorias ..........................................................................................................60 Figura 14: Fondo blanco y puntos negros ........................................................................................................64 Figura 15: Imagen con puntos negros ..............................................................................................................65 Figura 16: Imgenes de fondo ..........................................................................................................................67 Figura 17: Imgenes de fondo (2) ....................................................................................................................69 Figura 18: Directorio eyes_classifier_take_1 con diez etapas .........................................................78 Figura 19: Contenido del fichero AdaBoostCARTHaarClassifier.txt..............................................................79 Figura 20: Objeto encontrado (Hit)................................................................................................................81 Figura 21: falso positivo (False) ...................................................................................................................81 Figura 22: Falso negativo (Missed) ...............................................................................................................82 Figura 23: Imagen de partida para el Createsamples........................................................................................87 Figura 24: Imgenes creadas con Createsamples .............................................................................................88 Figura 25: rbol de directorios (1)...................................................................................................................90 Figura 26: rbol de directorios (2)...................................................................................................................90 Figura 27: rbol de directorios (3)...................................................................................................................91 Figura 28: rbol de directorios (4)...................................................................................................................91 Figura 29: rbol de directorios (5)...................................................................................................................92
En este apartado se pretende ofrecer a futuros usuarios tanto del algoritmo de deteccin de la mastitis como de la herramienta Haartraining una informacin detallada de cada una de las clases y elementos que los componen. En primer lugar, analizaremos todo lo referente al algoritmo de la mastitis centrndonos en cada una de sus clases y funciones y detallando la estructura y uso de cada uno de los mtodos utilizados de la misma. El resto de mtodos no usados podrn consultarse en la documentacin incluida en la biblioteca OpenCV. Puede accederse a estos ficheros a travs del archivo index.htm situado en la carpeta /share/doc. Posteriormente analizaremos la herramienta Haartraining, describiendo todos sus comandos individualmente, sus caractersticas y los resultados que aqullos producen.
Algoritmo mastitis
2.1.1.1 cvThreshold
void cvThreshold (IplImage* src, IplImage* dst, float threshold, float maxvalue, CvThreshType type) NECESITA: src: Imagen origen. dst: Imagen destino. Puede coincidir con la imagen origen. threshold: Parmetro umbral (lmite inferior). maxvalue: Valor mximo (lmite superior) usado en los tipos de umbral: CV_THRESH_BINARY, CV_THRESH_BINARY_INV y CV_THRESH_TRUNC. type: Tipos de umbral. Existen los siguientes tipos: CV_THRESH_BINARY: Si val > threshold CV_THRESH_TRUNC: Si val > threshold CV_THRESH_TOZERO: Si val > threshold val = maxvalue; si no val = 0. val = 0; si no val = maxvalue. val = threshold; si no val = maxvalue. val = val; si no val = 0. val = 0; si no val = val. CV_THRESH_BINARY_INV: Si val > threshold
CV_THRESH_TOZERO_INV: Si val > threshold Grficamente los tipos de umbral son los siguientes:
Figura 1: cvThreshold
MODIFICA: La imagen destino guardando en ella la umbralizacin de la imagen origen, segn el mtodo dado en type y el umbral threshold. La umbralizacin se hace con un valor constante. Un mtodo ms avanzado es cvAdaptativeThreshold (consultar documento opencvref_cv.htm incluido en la documentacin de OpenCV) que calcula un umbral para cada pxel (adaptativo). Esta funcin se utiliza tpicamente para conseguir imgenes en escala de grises o de dos niveles.
2.1.1.2 cvFindContours
int cvFindContours (CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size = sizeof(CvContour), int mode = CV_RETR_LIST, int method = CV_CHAIN_APPROX_SIMPLE, CvPoint offset = cvPoint(0,0) ) NECESITA: image: Imagen fuente de 8 bits o canales. storage: Donde se almacenan los contornos encontrados (contenedor de contornos). first_contour: Parmetro de salida que contendr el puntero al primer contorno exterior. Ser nulo si no se detectan contornos. header_size: Tamao de la cabecera de la secuencia. Ser mayor o igual que sizeof (cvChain) si method = CV_CHAIN_CODE y mayor o igual que sizeof (CvContour) en otro caso. mode: Modo de obtencin de los contornos. Existen varios tipos: CV_RETR_EXTERNAL: Recupera slo el contorno exterior de la imagen. CV_RETR_LIST: Recupera todos los contornos y los pone en la lista. CV_RETR_CCOMP: Recupera todos los contornos y los organiza en una jerarqua de dos niveles. El nivel superior estar formado por los lmites externos y el inferior por los internos. CV_RETR_TREE: Recupera todos los contornos y reconstruye la jerarqua completa. method: Mtodo de aproximacin para todos los modos excepto para el CV_RETR_RUNS, que usa un sistema propio (incorporado) de aproximacin: CV_CHAIN_CODE: Contornos exteriores mediante el cdigo de cadena de Freeman. CV_CHAIN_APPROX_NONE: Traduce todas las partes del cdigo de cadena a puntos. CV_CHAIN_APPROX_SIMPLE: Comprime los segmentos horizontales, verticales y diagonales dejando slo sus puntos finales. CV_CHAIN_APPROX_TC89_L1: Primera versin del algoritmo de aproximacin TehChin. CV_CHAIN_APPROX_TC89_KCOS: Segunda versin del algoritmo Teh-Chin. CV_LINK_RUNS: Slo puede ser usado con mode = CV_RETR_LIST. Utiliza un mtodo de enlaces de segmentos horizontales de 1s. offset: Desplazamiento a partir del cual se quitan todos los puntos del contorno.
MODIFICA: Si se detectan contornos, first_contour contendr un puntero al primer contorno exterior encontrado. Los siguientes contornos se alcanzan utilizando h_next y v_next. PRODUCE: Encuentra los contornos de una imagen binaria y devuelve el nmero de contornos encontrados. En la imagen inicial, se trata a los pxeles de valor distinto de cero como unos y a los de valor cero como ceros. Esto produce el tratamiento de la imagen pasada como parmetro como binaria. Para obtener una imagen binaria a partir de una escala de grises, puede usarse cvThreshold, cvAdaptativeThreshold o cvCanny.
2.1.1.3 cvContourArea
double cvContourArea (const CvArr* contour, CvSlice slice = CV_WHOLE_SEQ) NECESITA: contour: Contorno del cual queremos calcular el rea. slice: Puntos iniciales y finales de la seccin del contorno de inters. Por defecto se calcula el rea de todo el contorno.
PRODUCE: El rea de todo el contorno o de una seccin del mismo. La orientacin del contorno puede hacer que la funcin devuelva un resultado negativo, por lo que ser conveniente utilizar la funcin fabs() para obtener su valor absoluto.
2.1.1.4 cvBox2D
typedef struct CvBox2D32f { CvPoint2D32f center CvSize2D32f float angle } size
Estructura con tres campos que genera, usando flotantes, un rectngulo girado en 2 dimensiones y 32 bits. center: Centro del rectngulo. size: Ancho y largo del rectngulo. angle: ngulo formado entre el eje horizontal y el largo del rectngulo en radianes.
2.1.1.5 cvFitEllipse
void cvFitEllipse (CvPoint* points, int n, CvBox2D32f* box) NECESITA: points: Puntero al conjunto de puntos 2D. n: Nmero de puntos. Debe ser mayor o igual que 6. box: Puntero a la estructura donde se almacena la elipse.
MODIFICA: La estructura box de la siguiente manera: box box box center: Punto central de la elipse. size: Dimensiones de los 2 ejes de la elipse. angle: ngulo formado entre el eje horizontal y el eje longitudinal de la elipse.
PRODUCE: Forma una elipse ajustada al conjunto de puntos pasados como parmetro. En versiones anteriores de OpenCV esta funcin exista pero no funcionaba, producindose un error en tiempo de ejecucin. En versiones recientes tambin podemos encontrar la funcin:
CvBox2D cvFitEllipse2 (const CvArr* points) NECESITA: points: Secuencia o array de puntos
MODIFICA: La estructura box de salida de la siguiente manera: box box box center: Punto central de la elipse. size: Dimensiones de los 2 ejes de la elipse. angle: ngulo formado entre el eje horizontal y el eje longitudinal de la elipse.
PRODUCE: Calcula la elipse que mejor se adapta (atendiendo al sistema de los mnimos cuadrados) al conjunto de puntos pasados.
10
2.1.2.1 cvNamedWindow
int cvNamedWindow (const char* name, int flags) NECESITA: name: Nombre de la ventana a crear. flags: Flags de la ventana. Actualmente el nico soportado es CV_WINDOWS_AUTOSIZE, que puede estar a uno (el tamao de la ventana se ajusta automticamente a la imagen) o a cero (la imagen se escalar con la ventana).
MODIFICA: Crea una ventana en la que se pueden insertar imgenes y trackbars. Estas ventanas son referidas por su nombre. Si a la ventana se le da un nombre ya existente, la funcin no hace nada. PRODUCE: Produce un uno si la ventana se cre correctamente y cero en caso contrario.
2.1.2.2 cvDestroyWindow
void cvDestroyWindow (const char* name) NECESITA: name: Nombre de la ventana a eliminar.
11
2.1.2.3 cvShowImage
void cvShowImage (const char* name, CvArr* image) NECESITA: name: Nombre de la ventana a mostrar. image: Imagen a mostrar.
MODIFICA: Muestra la imagen en la ventana especificada con name. Si la ventana fue creada con el flag de CV_WINDOWS_AUTOSIZE a uno, la imagen ser mostrada en su tamao original; si no, ser escalada con la ventana.
2.1.2.4 cvWaitKey
int cvWaitKey (int delay = 0) NECESITA: delay: espera en milisegundos.
MODIFICA: Espera a que se pulse una tecla indefinidamente si delay es menor o igual que cero. En caso contrario, espera delay milisegundos. PRODUCE: Devuelve el cdigo de la tecla pulsada 1 si no se ha pulsado ninguna tecla antes de cumplirse los delay milisegundos.
2.1.2.5 cvLoadImage
IplImage* cvLoadImage (const char* filename, int iscolor = 1) NECESITA: filename: Nombre del archivo que contiene la imagen. Los archivos soportados por OpenCV son: Windows bipmap: BMP, DIB Archivos JPEG: JPEG, JPG, JPE Portable Network Graphics: PNG Sun rasters: SR, RAS TIFF files: TIFF, TIF
12
iscolor: Especifica en nmero de canales con los que se carga la imagen. Si iscolor > 0, la imagen se carga con tres canales (rojo, verde y azul). Igual a cero si queremos que se cargue con un canal, en escala de grises. Menor que cero si queremos que se cargue con la cabecera del archivo.
MODIFICA: Carga una imagen del archivo especificado en la llamada. PRODUCE: Devuelve un puntero a la estructura de la imagen cargada (IplImage).
2.1.2.6 cvSaveImage
int cvSaveImage (const char* filename, const CvArr* image) NECESITA: filename: Nombre del archivo. image: Nombre de la imagen a guardar.
MODIFICA: Guarda la imagen en el archivo especificado. El formato de la imagen depende de la extensin del filename. Los formatos permitidos son los mismos que los especificados en cvLoadImage. PRODUCE: Produce un uno si la imagen se guarda correctamente y un cero en caso contrario.
13
2.1.3.1 IplImage
Como ya hemos visto, la estructura de representacin de las imgenes es IplImage, que ya es utilizada por IPL (Intel Image Processing Library). Esta estructura dispone de muchos campos, muchos de los cuales son heredados de IPL y no se usan en OpenCV. A continuacin, mostramos y explicamos los campos ms importantes de la estructura: typedef struct _IplImage { int nSize; int nChannels; int width; int height; int depth; int dataOrder; int origin; char *imageData; int widthStep; struct _IplROI *roi; char *imageDataOrigin; int void } align; *imageId; struct _IplImage *maskROI; struct _IplTileInfo *tileInfo;
14
CAMPOS: nSize: sizeof (IplImage). nChannels: nmero de canales. las ltimas versiones de OpenCV soportan 1, 2, 3 4 canales. width: ancho de la imagen (en pxeles). height: altura de la imagen (en pxeles). depth: profundidad del pxel en bits: IPL_DEPTH_8U Entero de 8 bits sin signo. IPL_DEPTH_8S Entero de 8 bits con signo. IPL_DEPTH_16S Entero de 16 bits con signo. IPL_DEPTH_32S Entero de 32 bits con signo. IPL_DEPTH_32F Reales de precisin simple (32 bits). IPL_DEPTH_64F Reales de precisin doble (64 bits). dataOrder: orden de los canales. Puede tener dos valores: 0 1 Entrelazado de pxeles. Por canales (pxeles separados).
cvCreateImage slo puede crear entrelazado de pxeles, mediante el flag IPL_DATA_ORDER_PIXEL. Sin embargo, si COI est activado, los canales seleccionados pueden ser procesados. origin: origen. Indica donde empieza la imagen, puede ser: origin = 0 habitual. Top-left: El pxel i(0,0) es la esquina superior izquierda. Es la ms
origin = 1 Bottom-left: El pxel i(0,0) es la esquina inferior izquierda. Usada en algunos formatos como BMP. imageData: puntero a los pxeles de la imagen. widthStep: tamao de la fila de datos de la imagen en bytes (entre una fila y la siguiente hay widthStep bytes). Al final de la fila pueden sobrar algunos bytes con le propsito de alinear las filas. roi: imagen ROI (zona de inters). Cuando no es nula (NULL), especifica la regin de la imagen que va a ser procesada. imageDataOrigin: puntero al origen de los datos de la imagen. align: alineamiento de los datos de la imagen. Pueden ser de 4 u 8 bytes. maskROI: debe ser nulo en OpenCV. imageId: tambin debe ser nulo. tileInfo: tambin debe ser nulo.
Los pxeles de la imagen estn referenciados en *imageData. Se almacenan por filas, de izquierda a derecha, empezando por la fila superior o la inferior (dependiendo del valor de origin) y entre una fila y otra encontramos widthStep bytes. Un ejemplo de esto puede ser:
15
IplImage *img
int width = 2 int height = 2 int nChannels = 3 int depth = 8U char *imageData Figura 2: Ejmplo de estructura IplImage
widthStep = 8
2.1.3.2 CvPoint
Coordenadas de un punto (un pxel) en una imagen. La numeracin de filas y columnas empieza en cero. typedef struct CvPoint { int x; int y; } CAMPOS: x: coordenada x. y: coordenada y.
Existen funciones inline para crear e inicializar variables de estos tipos de datos: Constructor: inline CvPoint cvPoint (int x, int y) Conversin desde CvPoint2D32f: (CvPoint2D32f point) inline CvPoint cvPointFrom32f
16
2.1.3.3 CvPoint2D32f
Coordenadas de un punto (un pxel) expresado como real (flotante). typedef struct CvPoint2D32f { float x; float y; } CAMPOS: x: coordenada x. y: coordenada y.
Funciones inline de creacin e inicializacin de variables: Constructor: inline CvPoint2D32f cvPoint2D32f( double x, double y ) Conversin desde CvPoint: point) inline CvPoint2D32f cvPointTo32f (CvPoint
2.1.3.4 CvSize
Expresa el tamao de una regin rectangular, en pxeles typedef struct CvSize { int width; int height; } CAMPOS: width: anchura del rectngulo. height: altura del rectngulo.
Funciones inline de creacin e inicializacin de variables: Constructor: inline CvSize cvSize (int width, int height).
17
2.1.3.5 cvCreateImage
IplImage* cvCreateImage (CvSize size, int depth, int channels) NECESITA: size: tamao de la imagen depth: profundidad del pxel en bits. Como vimos en la estructura IplImage, esta profundidad puede ser: IPL_DEPTH_8U Entero de 8 bits sin signo. IPL_DEPTH_8S Entero de 8 bits con signo. IPL_DEPTH_16S Entero de 16 bits con signo. IPL_DEPTH_32S Entero de 32 bits con signo. IPL_DEPTH_32F Reales de precisin simple (32 bits). IPL_DEPTH_64F Reales de precisin doble (64 bits). channels: nmero de canales. Puede ser 1, 2, 3 4.
MODIFICA: Crea una imagen, formando su cabecera y la localizacin de sus datos. PRODUCE: Puntero a la estructura IplImage de la imagen creada.
2.1.3.6 cvCloneImage
IplImage* cvCloneImage (const IplImage* image) NECESITA: image: imagen a clonar.
MODIFICA: Almacena la nueva imagen en la estructura IplImage de salida. PRODUCE: Una copia exacta y completa de la imagen inicial.
18
2.1.3.7 CvMemStorage
CvMemStorage crea una estructura esttica global necesaria para almacenar estructuras de datos que crecen dinmicamente como secuencias, contornos, etc. Esta estructura est organizada en forma de bloques de igual tamao, donde la cima (top) es actualmente usado (pero no necesariamente el ltimo bloque de la lista) y el campo bottom principio de la lista de bloques. Todos los bloques entre bottom y top (excluyendo a considerados ocupados, mientras que los bloques entre top y el ltimo bloque (excluyendo al considerados totalmente vacos. El bloque top puede estar parcialmente ocupado, por lo que free_space marca la cantidad de bytes libres en dicho bloque. el bloque apunta al ste) son top) son el campo
La nueva estructura de memoria puede ser asignada explcitamente por la funcin cvMemStorageAlloc o implcitamente por funciones de ms alto nivel como cvSeqPush, cvGraphAddEdge, etc., comenzando siempre por el final del bloque actual (top) - si tiene suficiente capacidad -. Despus de la asignacin, free_space es decrementado con el valor del espacio asignado incrementado en algunos bytes ms para mantener la alineacin adecuada. Si el bloque top no tiene espacio suficiente, es tomado como top el siguiente bloque de almacenaje y free_space guarda el tamao del bloque completo. Si no hay ms bloques libres, se asigna un nuevo bloque, pudiendo tomarlo del padre, y aadindolo al final de la lista. As, la estructura de almacenamiento se comporta como una pila, donde bottom, top y free_space son los elementos clave. typedef struct CvMemStorage { struct CvMemBlock* bottom; struct CvMemBlock* top; struct CvMemStorage* parent; int block_size; int free_space; } CAMPOS: bottom: puntero al primer bloque de memoria. top: cima actual de la pila. parent: situacin de los nuevos bloques, puede ser un puntero a los bloques del padre. block_size: tamao del bloque. free_space: espacio libre en bytes en el bloque apuntado por top.
19
2.1.3.8 cvCreateMemStorage
CvMemStorage* cvCreateMemStorage (int block_size = 0) NECESITA: bloq_size: tamao de los bloques que forman la estructura de almacenamiento en bytes. Si es cero, los bloques toman el tamao por defecto (64K).
MODIFICA: Crea una zona de almacenamiento en memoria, inicialmente vaca. Todos los campos de la estructura creada, excepto block_size, son puestos a cero. PRODUCE: Devuelve un puntero a la estructura de almacenamiento creada.
2.1.3.9 CvSeq
La estructura CvSeq es la base para todas las estructuras dinmicas de OpenCV. Dispone de una macro que facilita la extensin de la estructura con parmetros (secuencias) adicionales definidos por el programador. Para ampliar CvSeq, el programador define estas nuevas secuencias a continuacin de las ya existentes en la macro CV_SEQUENCE_FIELDS(). Hay dos tipos de secuencias, llamadas dense y sparse. Las secuencias dense tienen como tipo base CvSeq y se usan para representar estructuras dinmicas como vectores, pilas o colas. No disponen de elementos vacos en posiciones intermedias, de tal manera que si se inserta o se elimina un elemento en una de estas posiciones, el resto de elementos se reagrupan. Las secuencias sparse tienen como tipo base CvSet y estn formadas por nodos que disponen de un flag que indica si estn vacos o no. Estas secuencias se usan para estructuras de datos desordenadas como conjuntos de elementos, tablas hash, etc.
20
#define CV_SEQUENCE_FIELDS() int flags; int header_size; struct CvSeq* h_prev; struct CvSeq* h_next; struct CvSeq* v_prev; struct CvSeq* v_next; int total; int elem_size; char* block_max; char* ptr; int delta_elems; CvMemStorage* storage; CvSeqBlock* free_blocks; CvSeqBlock* first; CAMPOS DE CV_SEQUENCE_FIELDS(): flags: contiene distintos flags. Si la secuencia es de tipo dense, en sus 16 bits ms altos contiene el campo CV_SEQ_MAGIC_VAL mientras que si es sparse, este campo ser el CV_SET_MAGIC_VAL, adems de otras informaciones referentes a la secuencia. Los bits ms bajos, referenciados por CV_SEQ_ELTYPE_BITS contienen la ID del tipo de elemento. header_size: tamao de la cabecera. Debe ser mayor o igual que sizeof (CvSeq). h_prev: secuencia previa. h_next: siguiente secuencia. v_prev: segunda secuencia previa. v_next: segunda secuencia posterior. total: contiene el nmero total de elementos en una secuencia de tipo dense, y el nmero de nodos asignados en una secuencia de tipo sparse. elem_size: tamao de los elementos de la secuencia en bytes. block_max: cota superior del ltimo bloque. ptr: puntero al elemento actual. delta_elems: nmero de elementos reservados cuando la secuencia crece. storage: estructura de almacenamiento de la secuencia. free_blocks: lista de bloques vacos. first: puntero al primer bloque de la secuencia.
Los campos h_prev, h_next, v_prev y v_next pueden ser usados para crear una estructura jerrquica de secuencias separadas, donde h_prev y h_next apuntarn a la secuencia previa y siguiente respectivamente en el mismo nivel jerrquico, mientras que v_prev y v_next apuntarn a la previa y posterior en direccin vertical, es decir, al padre y a su primer hijo.
21
2.1.3.10 cvCvtSeqToArray
void * cvCvtSeqToArray (const CvSeq* seq, void* elements, CvSlice slice = CV_WHOLE_SEQ) NECESITA: seq: puntero a la estructura de la secuencia. elements: puntero al array de destino, que debe ser suficientemente grande. slice: parte de la secuencia a copiar al array. Por defecto copia la secuencia completa.
MODIFICA: Copia la secuencia completa o la subsecuencia en la estructura de almacenamiento especificada. PRODUCE: Puntero a la estructura de almacenamiento.
2.1.3.11 CV_RGB
Construye una variable de color. # define CV_RGB (r, g, b) Ejemplo: CV_RGB (255, 0, 0) CV_RGB (0, 255, 0) CV_RGB (0, 0, 255) color rojo color verde color azul cvScalar ((b), (g), (r))
22
2.1.3.12 cvDrawContours
void cvDrawContours (CvArr* img, CvSeq* contour, CvScalar external_color, CvScalar hole_color, int max_level, int thickness = 1, int line_type = 8) NECESITA: img: imagen de la que se dibujarn los contornos. contour: puntero al primer contorno. external_color: color de los contornos exteriores. hole_color: color de los contornos interiores (agujeros). max_level: nivel mximo para dibujar contornos. Si es 0, slo contour ser dibujado (nivel 0). Si es 1, contour y todos los contornos del nivel 1 sern dibujados, etc. Si tiene un valor negativo, la funcin dibujar el contorno de nivel 0 y los de nivel abs(max_level)-1. thickness: Grosor de las lneas que dibujarn los contornos. Si es negativo (por ejemplo CV_FILLED), se dibujarn los contornos interiores (rea delimitada por los contornos exteriores). line_type: tipo de lnea: line_type = 8 line_type = 0 line_type = 4 lnea unida de 8 puntos. lnea unida de 8 puntos. lnea unida de 4 puntos. lnea de tipo antialiased.
2.1.3.13 cvZero
void cvSetZero (CvArr* arr) #define cvZero cvSetZero NECESITA: arr: array a vaciar o inicializar a cero. Se utiliza tambin para inicializar una imagen toda a cero (color negro).
MODIFICA: Pone el array a cero. En caso de arrays de tipo dense, cvZero (array) es equivalente a cvSet (array, cvScalarAll (0), 0) mientras que si el array es de tipo sparse, todos los elementos son eliminados.
23
2.1.3.14 CvScalar
Proporciona un contenedor para nmeros con forma de tupla de 1, 2, 3 4 elementos. typedef struct CvScalar { double val[4]; } Funciones inline de creacin e inicializacin de variables: Constructor 1: inicializa val[0] = val0; val[1] = val1, etc. inline CvScalar cvScalar (double val0, double val1 = 0, double val2 = 0, double val3 = 0) Constructor 2 : Inicializa val[0]... val[3] con val0123 inline CvScalar cvScalarAll (double val0123) Constructor 3: Inicializa val[0] = val0; val[1] = val[2] = val[3] = 0 inline CvScalar cvRealScalar (double val0)
2.1.3.15 CvSize
Indica el tamao exacto de un pxel de un rectngulo. typedef struct CvSize { int width; int height; } CAMPOS: width: ancho del rectngulo. height: altura del rectngulo.
Funciones inline de creacin e inicializacin de variables: Constructor: inline CvSize cvSize (int width, int height)
24
2.1.3.16 CvArr
Especifica un array arbitrario. typedef void CvArr; El tipo CvArr* se usa slo como parmetro de funciones, y puede representar distintos tipos de arrays como IplImage *, CvMat * CvSeq *.
2.1.3.17 cvCmp
void cvCmp cmp_op) NECESITA: src1: primer array origen. Debe ser de un canal. src2: segundo array origen. Debe ser de un canal. dst: array destino. Debe ser de enteros de 8 bits con o sin signo. cmp_op: flag que especifica la relacin entre los elementos de los arrays. Puede ser: CV_CMP_EQ: src1 igual a src2. CV_CMP_GT: src1 mayor que src2. CV_CMP_GE: src1 mayor o igual a src2. CV_CMP_LT: src1 menor que src2. CV_CMP_LE: src1 menor o igual que src2. CV_CMP_NE: src1 distinto a src2. MODIFICA: Compara, elemento a elemento, los arrays origen, guardando el resultado de la operacin en el array destino. Los arrays deben ser del mismo tipo (excepto el de destino) y tener la misma dimensin. El resultado ser un array binario. Cada posicin de este array ser un 1 si la relacin entre src1 y src2 es cierta y un 0 en caso contrario. (const CvArr* src1, const CvArr* src2, CvArr* dst, int
25
2.1.3.18 cvGetSize
CvSize cvGetSize (const CvArr* arr) NECESITA: arr: matriz o imagen de la cual se devolver su tamao.
MODIFICA: Calcula las dimensiones de la estructura pasada como parmetro. PRODUCE: Devuelve el nmero de filas (CvSize::height) y el nmero de columnas (CvSize::width) de la matriz o imagen pasada por parmetro.
2.1.3.19 cvRound
int cvRound (double value) NECESITA: value: punto expresado como flotante.
MODIFICA: Convierte el punto con coordenadas flotantes de entrada en un nmero entero. PRODUCE: Devuelve el valor del nmero entero ms cercano al argumento.
26
2.1.3.20 cvEllipse
void cvEllipse (CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness = 1, int line_type = 8, int shift = 0); NECESITA: img: imagen inicial. center: centro de la elipse. axes: longitud de los ejes de la elipse. angle: ngulo de rotacin. start_angle: ngulo inicial del arco de la elipse. end_angle: ngulo final del arco de la elipse. color: color de la elipse. thickness: grosor del arco de la elipse. line_type: tipo de lnea (ver 9.2.1.3.12) shift: nmero de bits fraccionados en el centro de coordenadas. MODIFICA: Dibuja un arco elptico o rellena el interior de una elipse.
27
2.2 Algoritmo
En este punto explicaremos paso a paso el funcionamiento del algoritmo de deteccin de la mastitis, analizando el cdigo as como los resultados intermedios y finales producidos en una imagen pasada como parmetro. La imagen inicial utilizada para este anlisis es la siguiente:
28
#include <highgui.h> // incluye definiciones HighGUI #include <cxcore.h> // estructuras y operaciones de CxCore #include <string.h> #include <stdio.h> #include <math.h> #include <iostream.h> #include <fstream.h> #include <vector.h>
/* Declaramos una serie de estructuras IplImagen de un slo canal (blanco y negro), que contendrn imgenes parciales obtenidas despus de transformaciones. ByN contendr la imagen inicial transformada a blanco y negro; ByNSinBordes esa misma imagen sin los bordes exteriores; BordesExt contendr slo los bordes de la imagen y FINAL tendr la imagen final despus de todos los clculos realizados. Como se puede observar, estas imgenes son creadas con el tamao de la imagen inicial, una profundidad de 8 bits y 1 canal. */
IplImage* ByN = cvCreateImage (cvGetSize(origen), 8, 1); IplImage* ByNSinBordes = cvCreateImage (cvGetSize(origen), 8,1); IplImage* BordesExt = cvCreateImage (cvGetSize(origen), 8, 1); IplImage* FINAL = cvCreateImage (cvGetSize(origen), 8, 1);
/* Creamos una zona de almacenamiento en memoria, inicialmente vaca, para almacenar las imgenes y las secuencias que contendrn dichas imgenes. Como parmetro de la funcin pasamos un cero, lo que har que el tamao del bloque de memoria ser el de por defecto (64K). */
CvMemStorage* mem = cvCreateMemStorage(0);
29
/* Declaramos secuencias de memoria, de tipo dense, para representar estructuras dinmicas que contendrn los contornos de las imgenes: */
CvSeq * contorno0 = 0; CvSeq * contorno1 = 0; CvSeq * contorno2 = 0;
/* Declaramos coordenadas de puntos (pxeles) de una imagen en formato de entero o flotante. La numeracin de filas y columnas empieza en cero. */
CvPoint* PointArray; CvPoint2D32f* PointArray2D32f;
/* Declaramos una estructura que genera, usando flotantes, un rectngulo girado en 2 dimensiones y 32 bits y servir para almacenar elipses. */
CvBox2D32f* MemElipse;
/* Inicializamos con cvZero las imgenes en blanco y negro. Est inicializacin pone a cero dichas imgenes (color negro). */
cvZero(ByN); cvZero(BordesExt); cvZero(ByNSinBordes); cvZero(FINAL);
/* Declaramos tres contadores que registrarn el nmero de clulas. El primero de ellos, contar las clulas de los bordes exteriores de la imagen; el segundo, el de las clulas interiores (sin bordes) y el ltimo de ellos registrar el nmero de clulas totales. */
int NumeroCelulasContorno int NumeroCelulasTotal = 0; = 0;
int NumeroCelulasSinBordes = 0;
/* A continuacin declaramos lmites numricos que usaremos a lo largo del programa. Estos valores fueron proporcionados por el equipo de microscopa del proyecto. */
30
/* Limites para el parmetro maxvalue de la instruccin cvThreshold, usada principalmente en este algoritmo para conseguir imgenes binarias: */
int LimiteInfByN int LimiteSupByN = 127; = 255; // Lmite inferior de la imagen en blanco y negro. // Lmite superior de la imagen en blanco y negro. // Lmite inferior de los contornos exteriores. // Lmite superior de los contornos exteriores. // Lmite inferior de la imagen final. // Lmite superior de la imagen final.
int LimiteInfContExt = 180; int LimiteSupContExt = 255; int LimiteInfFINAL int LimiteSupFINAL = 127; = 255;
long int LimSupCelEliminadas = 4999; long int LimInfCelEliminadas = 2000; int TamMedioCelulas = 12000;
double area_total_contorno = 0;
// Otras variables:
CvSize size; // Variable de tamao. CvPoint center; // Puntero de coordenada float media = 0; double suma = 0; int nele = 0, cont = 0, eliminadas = -1; double PI = 3.141592;
31
NECESITA: nombre: nombre de la ventana a crear. im: imagen a mostrar. val: flag CV_WINDOWS_AUTOSIZE de la ventana. Si est a uno, el tamao de la ventana se ajusta automticamente a la imagen; si est a cero la imagen se escala con la ventana (se puede cambiar su tamao).
MODIFICA: Crea una ventana denominada nombre y muestra en ella la imagen im pasada por parmetro. La ventana permanecer visible hasta que se pulse cualquier tecla, momento en el cual ser eliminada.
32
CvSeq * contorno0 = 0; CvSeq * contorno1 = 0; CvSeq * contorno2 = 0; CvPoint* PointArray; CvPoint2D32f* PointArray2D32f; CvBox2D32f* MemElipse; cvZero(ByN); cvZero(BordesExt); cvZero(ByNSinBordes); cvZero(FINAL); int NumeroCelulasContorno int NumeroCelulasTotal = 0; = 0;
int NumeroCelulasSinBordes = 0;
33
= 127; = 255;
int LimiteInfContExt = 180; int LimiteSupContExt = 255; int LimiteInfFINAL int LimiteSupFINAL = 127; = 255; = 1700000; = 160000; = 1700000; = 160000; = 340000; = 5000;
long int LimSupCelsContorno long int LimInfCelsContorno long int LimSupSinBordes1 long int LimInfSinBordes1 long int LimSupSinBordes2 long int LimInfSinBordes2
long int LimSupCelEliminadas = 4999; long int LimInfCelEliminadas = 2000; int TamMedioCelulas = 12000;
34
// Guardamos la imagen anterior en un archivo de extensin png. cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/01_imagen.png, /* 01_imagen.png: nombre del archivo origen: nombre de la imagen a guardar */ // Clonamos la imagen inicial para no modificarla (quedar almacenada en origen), almacenando la copia en al estructura ByN. ByN = cvCloneImage (origen); /* origen: imagen a clonar */ // Binarizamos la imagen anterior, aplicando la funcin cvThreshold. cvThreshold(ByN, ByN, LimiteInfByN, LimiteSupByN, CV_THRESH_BINARY ); /* ByN: imagen origen ByN: imagen destino LimiteInfByN: parmetro umbral (lmite inferior) LimiteSupByN: valor mximo (lmite superior) CV_THRESH_BINARY: Si val > LimiteInfByN */ val = LimiteSupByN; sino val = 0 origen);
35
// Volvemos a guardar la imagen en el mismo directorio: cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/02_ByN.png", ByN); /* 02_ByN.png: nombre del archivo ByN: nombre de la imagen a guardar */
36
2.2.1.5 Obtencin de los contornos exteriores // Clonamos la imagen ByN, almacenando la copia en BordesExt. BordesExt = cvCloneImage (ByN); // ByN: imagen a clonar // Buscamos los contornos exteriores de la imagen BordesExt, almacenndolos en el contenedor mem. contorno0 tendr un puntero al primer contorno encontrado. Con CV_RETR_EXTERNAL recuperamos slo los contornos exteriores de la imagen. cvFindContours (BordesExt, mem, &contorno0, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); /* BordesExt: imagen fuente mem: lugar de almacenamiento de los contornos encontrados contorno0: puntero al primer contorno exterior sizeof(CvContour): tamao de la cabecera de la secuencia CV_RETR_EXTERNAL: recupera slo el contorno exterior de la imagen CV_CHAIN_APPROX_SIMPLE: Comprime los segmentos horizontales, verticales y diagonales dejando slo sus puntos finales */ sizeof(CvContour),
37
2.2.1.6 Clculo del rea de los contornos /* En este punto calculamos el rea de los contornos obtenidos anteriormente. Una vez hecho esto, comprobamos si en dicha rea puede haber clulas a detectar, para lo que hacemos una media del rea total obtenida con el tamao medio de las clulas. */ /* Declaramos dos variables de color, una para los bordes exteriores y otra para los huecos, dndole valores aleatorios, ya que no modificarn el resultado final. Esto es debido a que las imgenes a tratar son binarias (en blanco y negro). */ CvScalar colorExterior = CV_RGB (rand(), rand(), rand()); CvScalar colorHuecos = CV_RGB ( rand(), rand(), rand() ); // El siguiente for recorre los contornos encontrados anteriormente (recordemos que contorno0 contiene un puntero al primer contorno encontrado. A travs de h_next, h_prev, v_next y v_prev podemos acceder al resto de contornos. for (; contorno0 { area1_contorno = fabs (cvContourArea (contorno0, CV_WHOLE_SEQ)); /* contorno0: contorno del cual queremos calcular el rea CV_WHOLE_SEQ: calculamos el rea de todo el contorno */ cvDrawContours CV_FILLED, 8); /* BordesExt: imagen de la que se dibujarn los contornos contorno0: puntero al primer contorno colorExterior: color de los contornos exteriores colorHuecos: color de los contornos interiores (huecos) -1: nivel mximos para dibujar los contornos CV_FILLED: grosor de las lneas. CV_FILLED indica que se dibujarn los contornos interiores 8: tipo de lnea */ } //fin_for (BordesExt, contorno0, colorExterior, colorHuecos, -1, 0; contorno0 = contorno0 -> h_next)
38
/* Clculo de reas parciales y totales, recorriendo los contornos horizontal y verticalmente. El resultado de dichos clculos se almacenar en la variable total. */ for (; contorno0 { area2_contorno = fabs (cvContourArea (contorno0, CV_WHOLE_SEQ)); /* contorno0: contorno del cual queremos calcular el rea CV_WHOLE_SEQ: calculamos el rea de todo el contorno */ contorno1 = contorno0 -> v_next; // Contornos verticales if (contorno1) { for (; contorno1 /* contorno1: contorno del cual queremos calcular el rea CV_WHOLE_SEQ: calculamos el rea de todo el contorno */ 0; contorno1 = contorno1 -> h_next) 0; contorno0 = contorno0 -> h_next)
total_contorno += area1_contorno + area2_contorno; }//fin_if /* En el siguiente bucle, comprobamos la existencia de aglomeraciones de clulas. Para ello, comparamos el resultado del rea anterior con los lmites dados por el equipo de microscopa. */ if ((total_contorno LimInfCelsContorno)) { /* Hacemos una aproximacin del nmero de clulas del contorno, dividiendo el rea total por el tamao medio de las clulas. */ NumeroCelulasContorno += (int) (total_contorno / TamMedioCelulas); }//fin_If }//fin_for LimSupCelsContorno) && (total_contorno
39
// Volvemos a binarizar la imagen: cvThreshold (BordesExt, CV_THRESH_BINARY); /* BordesExt: imagen origen BordesExt: imagen destino LimiteInfContExt: parmetro umbral (lmite inferior) LimiteSupContExt: valor mximo (lmite superior) CV_THRESH_BINARY: Si val > LimiteInfContExt val = 0 */ val = LimiteSupContExt sino BordesExt, LimiteInfContExt, LimiteSupContExt,
40
cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/03_BordesExt.png", BordesExt); /* 02_BordesExt.png: nombre del archivo BordesExt: nombre de la imagen a guardar */
41
2.2.1.7 Eliminacin de los contornos exteriores // Una vez obtenidos los contornos exteriores, los eliminamos de la imagen. // Clonamos la imagen ByN, que contiene la imagen inicial en blanco y negro. ByNSinBordes contendr esa misma imagen pero sin los contornos exteriores. ByNSinBordes = cvCloneImage (ByN); //ByN: imagen a clonar // Realizamos la operacin [ByNSinBordes = ByN op BordesExt], siendo op la operacin lgica ' ' = cvCmp (ByN, BordesExt, ByNSinBordes, CV_CMP_EQ); /* ByN: primer array origen BordesExt: segundo array origen ByNSinBordes: array destino CV_CMP_EQ: ByN igual a BordesExt */ MostrarImagen ("Imagen ByNSinBordes, 0); inicial binarizada sin contornos exteriores", 1 si ByN = BordesExt; 0 si no.
42
cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/04_SinBordes.png", ByNSinBordes); /* 04_SinBordes.png: nombre del archivo ByNSinBordes: nombre de la imagen a guardar */
43
2.2.1.8 Clculo del nmero de clulas // En este punto y una vez conseguida la imagen en blanco y negro sin los bordes exteriores, calcularemos el nmero de clulas de la mastitis. Para ello ajustaremos las clulas detectadas con elipses y compararemos las dimensiones de dichas elipses con las medidas dadas por el equipo de microscopa para comprobar si dichas clulas son somticas o no. // Inicializamos de nuevo los contornos. contorno0 = 0; contorno1 = 0; // Volvemos a comprobar los contornos, pero esta vez los interiores (los exteriores ya han sido eliminados), realizando una jerarqua completa de los mismos. Para ello ponemos el flag CV_RETR_TREE. cvFindContours (ByNSinBordes, mem, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); /* ByNSinBordes: imagen fuente mem: lugar de almacenamiento de los contornos encontrados contorno0: puntero al primer contorno exterior sizeof(CvContour): tamao de la cabecera de la secuencia CV_RETR_TREE: Recupera todos los contornos y reconstruye la jerarqua completa. CV_CHAIN_APPROX_SIMPLE: Comprime los segmentos horizontales, verticales y diagonales dejando slo sus puntos finales */ // Nos desplazamos por los contornos horizontalmente for ( ;contorno0; contorno0 = contorno0 -> h_next ) { // Bajamos un nivel en la jerarqua de contornos (hijo) contorno1 = contorno0 -> v_next; if (contorno1) { // Nos desplazamos horizontalmente en ese nivel inferior for (; contorno1; contorno1 = contorno1 -> h_next ) { // total: contiene el nmero total de elementos en una secuencia nele = contorno1 -> total; &contorno0, sizeof(CvContour),
44
if ( nele >= 6 ) { PointArray = new CvPoint [nele * sizeof(CvPoint)]; PointArray2D32f=new CvPoint2D32f [nele * sizeof(CvPoint2D32f)]; // Reservo memoria para los datos de la elipse MemElipse = new CvBox2D32f [sizeof(CvBox2D32f)];
/* Hacemos una copia de la secuencia, almacenndola en la estructura PointArray. */ cvCvtSeqToArray (contorno1, PointArray, CV_WHOLE_SEQ); /* contorno1: puntero a los contornos PointArray: puntero al array de destino CV_WHOLE_SEQ: se copia la secuencia completa */ /* Guardamos la secuencia anterior pasndola a flotante */ for (int i=0; i < nele; i++) { PointArray2D32f[i].x =(float)PointArray[i].x; PointArray2D32f[i].y =(float)PointArray[i].y; }fin_for /* Formamos una elipse con la secuencia anterior almacenndola en MemElipse */ cvFitEllipse (PointArray2D32f, nele, MemElipse); /* PointArray2D32f: puntero al conjunto de puntos nele: nmero de puntos (tiene que ser mayor que 6) MemElipse: puntero a la estructura de almacenamiento de la elipse */ /* Guardamos en center el valor entero correspondientes a la coordenada del centro de la elipse. */ center.x = cvRound (MemElipse -> center.x); center.y = cvRound (MemElipse -> center.y); /* MemElipse -> center.x: punto expresado como flotante */
45
/* Guardamos en size los enteros correspondiente al tamao de los radios de la elipse */ size.width = cvRound (MemElipse -> size.width * 0.5); size.height = cvRound (MemElipse -> size.height * 0.5); /* MemElipse -> size.width * 0.5: punto expresado como flotante */ // Evitamos la posible existencia de ngulos negativos MemElipse -> angle = fabs (MemElipse -> angle); // Guardamos en variables de flotantes el tamao de los radios de los ejes float eje_uno = MemElipse -> size.width; float eje_dos = MemElipse -> size.height; /* Calculamos el valor de los ejes mayor y menor, haciendo el mximo y el mnimo de los ejes calculados en el paso anterior */ float eje_mayor eje_dos)/2; float eje_menor eje_dos)/2; = = (eje_uno (eje_uno + + eje_dos)/2 eje_dos)/2 + fabs fabs (eje_uno (eje_uno -
area_positiva = cvContourArea (contorno1, CV_WHOLE_SEQ); /* contorno1: contorno del que queremos calcular el rea CV_WHOLE_SEQ: se calcular el rea de todo el contorno */ area_elipse = PI * eje_mayor * eje_mayor; cociente = area_positiva / area_elipse; /* Recorremos las elipses interiores a otras elipses calculando su rea (rea negativa) */ area_negativa = 0; contorno2 = contorno1 -> v_next; for(; contorno2; contorno2 = contorno2 -> h_next) { if ( contorno2 -> total >= 6 ) area_negativa += (cvContourArea (contorno2, CV_WHOLE_SEQ)); /* contorno2: contorno del que queremos calcular el rea CV_WHOLE_SEQ: se calcular el rea de todo el contorno */
46
}//fin_for // El rea total ser la suma del rea positiva y la negativa area_total = area_negativa + area_positiva; if ((area_total LimInfSinBordes1)) { cvDrawContours (ByNSinBordes, colorHuecos, -1, 1, 8); /* ByNSinBordes: imagen de la que se dibujarn los contornos contorno1: puntero al primer contorno colorExterior: color de los contornos exteriores colorHuecos: color de los contornos interiores (huecos) -1: nivel mximo para dibujar los contornos 1: grosor de las lneas 8: tipo de lnea */ NumeroCelulasSinBordes += (int)( area_total / TamMedioCelulas ); MostrarImagen ("Calculo de elipses (1)", ByNSinBordes, 0); // En nuestro ejemplo no entr en este bucle cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/05_elipses1.png", ByNSinBordes); /* 05_elipses1.png: nombre del archivo ByNSinBordes: nombre de la imagen a guardar */ }fin_if contorno1, colorExterior, <= LimSupSinBordes1) && (area_total >=
47
else if ((area_total <= LimSupSinBordes2) LimInfSinBordes2) && (cociente >= 0.15) ) { //Dibujamos la elipse
&&
(area_total
>=
cvEllipse (ByNSinBordes, center, size, MemElipse -> angle, 0, 360, CV_RGB(255, 0, 0), 3); /* ByNSinBordes: imagen inicial center: centro de la elipse size: longitud de los ejes de la elipse MemElipse -> angle: ngulo de rotacin 0: ngulo inicial del arco de la elipse 360: ngulo final del arco de la elipse CV_RGB(255, 0, 0): color de la elipse 3: grosor del arco de la elipse 8 (por defecto): tipo de lnea 0 (por defecto): nmero de bits fraccionados en el centro de coordenadas */
contorno1,
CV_RGB(0,0,255),
ByNSinBordes: imagen de la que se dibujarn los contornos contorno1: puntero al primer contorno CV_RGB(0,0,255): color de los contornos exteriores CV_RGB(0,0,255): color de los contornos interiores (huecos) -1: nivel mximo para dibujar los contornos 1: grosor de las lneas 8: tipo de lnea */ cont ++; suma += area_total; MostrarImagen ("Calculo de elipses (2)", ByNSinBordes, 0);
48
cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/05_elipses2.png", ByNSinBordes); /* 05_elipses2.png: nombre del archivo ByNSinBordes: nombre de la imagen a guardar */ }fin_else /* Comprobamos, segn los lmites dados por el equipo de microscopa para las reas, la necesidad de eliminar algunas clulas que se salen de dichos lmites */ if ((area_total <= LimInfCelEliminadas)) { eliminadas++; cvEllipse (ByNSinBordes, center, size, MemElipse -> angle, 0, 360, CV_RGB(0,0,255), 3); /* ByNSinBordes: imagen inicial LimSupCelEliminadas) && (area_total >=
49
center: centro de la elipse size: longitud de los ejes de la elipse MemElipse -> angle: ngulo de rotacin 0: ngulo inicial del arco de la elipse 360: ngulo final del arco de la elipse CV_RGB(0, 0, 255): color de la elipse 3: grosor del arco de la elipse 8 (por defecto): tipo de lnea 0 (por defecto): nmero de bits fraccionados en el centro de coordenadas */ cvDrawContours (ByNSinBordes, CV_RGB(0,0,0), -1, 1, 8); /* ByNSinBordes: imagen de la que se dibujarn los contornos contorno1: puntero al primer contorno CV_RGB(0,0,0): color de los contornos exteriores CV_RGB(0,0,0): color de los contornos interiores (huecos) -1: nivel mximo para dibujar los contornos 1: grosor de las lneas 8: tipo de lnea */ MostrarImagen ("Clulas eliminadas", ByNSinBordes, 0); contorno1, CV_RGB(0,0,0),
50
cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/06_Eliminadas. png", ByNSinBordes); /* 06_eliminadas.png: nombre del archivo ByNSinBordes: nombre de la imagen a guardar */ }fin_if
// Liberamos la memoria usada delete PointArray; delete PointArray2D32f; delete MemElipse; cvDrawContours (ByNSinBordes, colorHuecos, -1, -1, 8); /* ByNSinBordes: imagen de la que se dibujarn los contornos contorno1: puntero al primer contorno contorno1, colorExterior,
51
colorExterior: color de los contornos exteriores colorHuecos: color de los contornos interiores (huecos) -1: nivel mximo para dibujar los contornos -1: grosor de las lneas 8: tipo de lnea */
52
if (cont != 0) media = suma / cont; if (eliminadas > 0) NumeroCelulasTotal = cont + NumeroCelulasSinBordes - eliminadas; else NumeroCelulasTotal NumeroCelulasSinBordes; = cont + NumeroCelulasContorno +
NumeroCelulasContorno
if (NumeroCelulasTotal < 0) NumeroCelulasTotal = 0; cout << "\nNumero de celulas totales fabs(NumeroCelulasTotal) << endl << endl << endl; // Binarizamos la imagen final cvThreshold ( FINAL, CV_THRESH_BINARY); /* FINAL: imagen origen FINAL: imagen destino LimiteInfFINAL: parmetro umbral (lmite inferior) LimiteSupFINAL: valor mximo (lmite superior) CV_THRESH_BINARY: Si val > LimiteInfContExt val = 0 */ val = LimiteSupContExt si no FINAL, LimiteInfFINAL, LimiteSupFINAL, detectadas: " <<
&contorno1,
sizeof(CvContour),
mem: lugar de almacenamiento de los contornos encontrados contorno1: puntero al primer contorno exterior sizeof(CvContour): tamao de la cabecera de la secuencia CV_RETR_CCOMP: Recupera todos los contornos y los organiza en una jerarqua de dos niveles. El nivel superior estar formado por los lmites externos y el inferior por los internos CV_CHAIN_APPROX_SIMPLE: Comprime los segmentos horizontales, verticales y diagonales dejando slo sus puntos finales
53
*/ // Dibujamos los contornos de la imagen final for (; contorno1 != 0; contorno1 = contorno1 -> h_next ) { cvDrawContours (FINAL, contorno1, colorExterior, colorHuecos, -1, CV_FILLED, 8); /* FINAL: imagen de la que se dibujarn los contornos contorno1: puntero al primer contorno colorExterior: color de los contornos exteriores colorHuecos: color de los contornos interiores (huecos) -1: nivel mximo para dibujar los contornos CV_FILLED: grosor de las lneas. Se dibujan los contornos interiores 8: tipo de lnea */ } MostrarImagen ("Imagen final", ByNSinBordes, 0);
54
cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/08_FINAL.pgn", FINAL); /* 08_FINAL.png: nombre del archivo FINAL: nombre de la imagen a guarda */
}//fin_if }//fin_main
55
3 Haartraining
La obtencin de un clasificador (detector de objetos) en rbol construido mediante el mtodo de boosting para un objeto en concreto requiere el seguimiento estricto de unos pasos que se van a describir con detalle en este captulo. En primer lugar, se requerir una preparacin exhaustiva de las imgenes que servirn como muestras, tanto positivas como negativas, para el aprendizaje del clasificador. En un caso ideal, el algoritmo partira del total del espacio muestral, distribuido en muestras positivas y negativas. Seguidamente, se pasar a la parte de entrenamiento del clasificador mediante el mtodo del boosting. Al finalizar el entrenamiento, se obtendrn como resultado las diferentes etapas del clasificador. Por ltimo, se proceder a la comprobacin del clasificador obtenido con imgenes reales.
3.1 Proceso
Para comprobar el funcionamiento del proceso Haartraining, primeramente decidimos crear una imgenes simples para aplicar la deteccin. Estas imgenes consistieron en un rectngulo negro sobre un fondo blanco. El rectngulo variara de posicin en cada imagen de manera aleatoria. Una vez familiarizados con el funcionamiento mediante estas imgenes, pasamos a probar Haartraining con fotos reales de clulas microscpicas de leche bovina.
56
3.2.1 Createsamples
Las muestras positivas necesarias para construir el clasificador se crean con la utilidad Createsamples. Tras su ejecucin, se crea un fichero de extensin vec que servir al clasificador para su entrenamiento. El Createsamples puede tomar como base para la creacin del fichero de entrenamiento una nica imagen del objeto o una coleccin de imgenes con las coordenadas exactas donde se encuentre el objeto en cada una (fichero ndice). El primer caso encuentra su aplicacin en objetos que se presenten siempre de igual modo, como por ejemplo el logotipo de una compaa. El programa es capaz de, a partir de rotaciones aleatorias, cambios en el color, as como colocacin sobre diversos fondos, generar un gran conjunto de muestras positivas que sirvan para el entrenamiento. El segundo caso es el que se ajusta a nuestro modelo. Las clulas a localizar no son nicas, por lo que no se conseguira la informacin necesaria para entrenar al clasificador con slo una imagen, aunque se le aplicasen las transformaciones anteriores (rotaciones...). Por ello es necesario crear un fichero de ndices con informacin sobre el conjunto de muestras. Este archivo de ndices (de extensin txt o idx) tendr la siguiente estructura: nombre_archivo1 nombre_archivo2 ... siendo nombre_archivo el nombre de la imagen donde se encuentran los objetos a buscar. Debemos destacar que el nombre del archivo debe ir acompaado de su direccin absoluta dentro del sistema de ficheros. nmero_muestras el nmero de objetos positivos que se encuentran en la imagen, en nuestro caso el nmero de clulas que contiene; el resto de parmetros se muestras en el siguiente grfico: nmero_muestras x11 y11 w11 h11 x12 y12... nmero_muestras x21 y21 w21 h21 x22 y22...
w11
57
La llamada al programa para crear el fichero de extensin vec tiene los siguientes argumentos: -vec: tras este flag escribiremos el nombre del fichero vec que crear el Createsamples a partir de las muestras proporcionadas. -info: preceder al nombre del fichero lista que contendr todas las imgenes de los objetos que constituyen las muestras positivas y cuya construccin se ha descrito anteriormente. -bg: nombre del fichero con la lista de las imgenes que servirn de fondos (muestras negativas). -num: indica al Createsamples el nmero de muestras que contiene el fichero lista y que por tanto aadir en el formato adecuado en el fichero vec. -w: indica el ancho deseado para las muestras creadas en la ejecucin del Createsamples. Su valor por defecto es de 24 pxeles. -h: indica el valor para el alto de las muestras. su valor por defecto es 24 pxeles.
Adems de stas, el programa tambin dispone de otras opciones cuyo objetivo es indicar los ngulos mximos en cada direccin para realizar las rotaciones o para hacer la inversin de los colores de la muestra que se pueden consultar en la misma ayuda del programa y que no se describen aqu por no haber hecho uso de ellas en el proceso.
58
Para componer las dos imgenes anteriores, utilizamos la aplicacin ImageMagick (comando composite), que permite crear, editar y componer imgenes. Puede leer, convertir y guardar imgenes en una gran variedad de formatos. Es software libre y su licencia es compatible con la licencia GPL. Realizamos un shell-script para automatizar la formacin de las muestras positivas, y que se muestra a continuacin. Este script crea 2000 imgenes con fondo blanco y un rectngulo negro situado aleatoriamente en la foto. Al mismo tiempo, va formando el archivo de ndices necesario para ejecutar la aplicacin Createsamples y una copia del mismo que usaremos en la aplicacin Performance.
59
#! /bin/bash echo > indexSimple.idx # Vaciamos los ficheros echo > Imagenes_muestras/CopiaIndexSimple.idx chmod 777 FICHERO # Todos los permisos para todos los usuarios
for i in $(seq 1 2000) do VARH=$(($RANDOM%161)) VARV=$(($RANDOM%161)) echo > FICHERO echo composite -geometry +$VARH+$VARV primerplano.jpg fondo.jpg
done
Ejemplos de las imgenes formadas mediante el script anterior son las siguientes:
El fichero de ndices generado de nombre indexSimple.idx contiene 500 lneas, una por cada imagen creada. A continuacin, mostramos una parte de dicho fichero:
60
/home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_1.jpg 1 70 47 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_2.jpg 1 159 5 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_3.jpg 1 144 74 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_4.jpg 1 80 55 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_5.jpg 1 146 159 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_6.jpg 1 56 96 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_7.jpg 1 83 91 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_8.jpg 1 30 80 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_9.jpg 1 104 50 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_10.jpg 1 65 88 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_11.jpg 1 79 151 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_12.jpg 1 107 15 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_13.jpg 1 109 155 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_14.jpg 1 2 46 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_15.jpg 1 29 44 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_16.jpg 1 82 59 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_17.jpg 1 79 79 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_18.jpg 1 136 160 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_19.jpg 1 46 58 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_20.jpg 1 47 6 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_21.jpg 1 78 24 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_22.jpg 1 67 138 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_23.jpg 1 69 146 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_24.jpg 1 157 53 14 14 /home/marcos/Proyecto/Mio/simple/Imagenes_muestras/salida_25.jpg 1 120 73 14 14
Como dijimos anteriormente, el nombre del fichero debe ir acompaado de su direccin absoluta. Una vez construidas las imgenes de fondo y el fichero de ndices, es el momento de ejecutar el programa Createsamples, cuya estructura vimos anteriormente. El comando usado para ejecutar dicho programa es la siguiente: $DIRECTORIOBASE/opencv-0.9.7/apps/haartraining/src/opencv-createsamples vec indexSimple.vec -info indexSimple.idx -w 14 -h 14 num 2000 El programa muestra por pantalla la siguiente informacin:
Info file name: indexSimple.idx Img file name: (NULL) Vec file name: indexSimple.vec BG file name: (NULL) Num: 2000 BG color: 0 BG threshold: 80 Invert: FALSE Max intensity deviation: 40 Max x angle: 1.1 Max y angle: 1.1 Max z angle: 0.5 Show samples: FALSE Width: 14 Height: 14 Create training samples from images collection... en cvsamples 1012: 14=14 x 14=14 en cvsamples.cpp 713:14*14=196 Done. Created 2000 samples
61
/home/marcos/Proyecto/Mio/Fotos/Haartraining/neutrof-827-3-AM-22-06-05-40x.jpg 1 918 447 145 191 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linfocito-400-3-AM-220605-40x.jpg 2 731 343 107 149 523 783 49 60 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit-AM_23-12-05-x-y-40x.jpg 3 313 98 158 179 564 764 149 178 906 493 285 300 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linf-oveja3-AM_15-12-05-1800x1200y-40x.jpg 4 806 122 155 123 735 525 122 157 1190 487 131 161 304 932 116 98 /home/marcos/Proyecto/Mio/Fotos/Haartraining/basof-507-1-AM_27-7-05-x-y-10x.jpg 4 960 838 115 155 470 844 41 54 261 1033 37 40 884 4 51 64 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linfcabra9491-4-AM-23-12-05-x-y10xPequeno.jpg 5 440 213 36 41 1160 335 50 59 477 896 32 44 1160 1042 31 40 418 570 17 17 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linf-896-4-AM_23-12-05_x-y-40x.jpg 1 518 253 168 217 /home/marcos/Proyecto/Mio/Fotos/Haartraining/neutrofcallao-cabra9480-5-AM-23-1205-x-y-10x.jpg 5 812 412 32 41 790 622 32 32 302 902 26 34 738 900 36 43 881 1000 29 34 /home/marcos/Proyecto/Mio/Fotos/Haartraining/neutrofcallao-cabra9491-4-AM-23-1205-x-y-10x.jpg 2 1174 101 37 39 1072 428 34 40 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit-AM-sheila_35-1-06-10xPeq.jpg 7 780 536 37 36 648 736 38 41 518 878 43 45 380 988 43 48 274 850 42 52 216 1138 48 60 1188 143 109 128 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit_oveja_15-12_05.jpg 1 844 628 170 207 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit3-507-1-AM_27-7-05-x-y-10x.jpg 4 85 342 35 42 711 373 31 40 1072 900 29 47 158 1130 42 42 /home/marcos/Proyecto/Mio/Fotos/Haartraining/basof-cabra9352-3-CT-AM_23-1205_2400x-2200y-40xPE.jpg 1 954 1002 115 176 /home/marcos/Proyecto/Mio/Fotos/Haartraining/basof-cabra9375-2-AzMet_23-1205_3000x-800y-40xPE.jpg 2 1147 308 120 159 366 47 60 81 /home/marcos/Proyecto/Mio/Fotos/Haartraining/basofilo-806-2-63_PE.jpg 1 766 652 176 236 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit-linf-AM-507-1_27-7-05-x-y10xPE.jpg 5 635 184 34 40 428 274 37 46 1041 408 38 50 864 668 53 83 216 922 40 53 /home/marcos/Proyecto/Mio/Fotos/Haartraining/epit-linf-linf-507-1-AM_27-705-x-y10x.jpg 3 931 730 84 120 913 312 40 49 1140 162 37 40 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linf-cabra9480-5-AM_23-12-05-x-y10xPE.jpg 1 1176 928 37 45 /home/marcos/Proyecto/Mio/Fotos/Haartraining/linf-cabra9480-5-AM-23-12-05-x-y10xx.jpg 5 813 411 34 40 788 622 28 31 302 902 24 32 738 902 36 39 880 1000 27 33 /home/marcos/Proyecto/Mio/Fotos/Haartraining/monocito-827-3-eos_21-12-05-10x.jpg 3 491 821 28 46 869 757 40 45 1156 342 46 56
62
Tras crear el fichero de ndices, realizamos la llamada al programa Createsamples. Esta llamada fue la siguiente: $DIRECTORIOBASE/opencv-0.9.7/apps/haartraining/src/opencv-createsamples
celulas.vec -info celulas.idx -w 20 -h 20 -vec
Como se puede observar, elegimos un tamao de 2020 para la ventana de deteccin de las clulas. Este tamao lo fuimos modificando en las sucesivas pruebas realizadas, obteniendo una deteccin ligeramente superior con dichas dimensiones. Tras ejecutar el programa, se muestra la siguiente informacin por pantalla:
marcos@lock:~/Proyecto/Mio$ ./createsamples Info file name: celulas.idx Img file name: (NULL) Vec file name: celulas.vec BG file name: (NULL) Num: 1000 BG color: 0 BG threshold: 80 Invert: FALSE Max intensity deviation: 40 Max x angle: 1.1 Max y angle: 1.1 Max z angle: 0.5 Show samples: FALSE Width: 20 Height: 15 Create training samples from images collection... en cvsamples 1012: 20=20 x 15=15 en cvsamples.cpp 713:20*15=300 celulas.idx(43) : parse errorDone. Created 107 samples
63
64
#! /bin/bash echo "" > backNoCelulas.idx chmod 777 FICHERO #Todos los privilegios for i in $(seq 1 200) do # Creamos la imagen formada por el fondo blanco y la imagen de puntos echo composite -geometry +100+100 puntos.jpg fondo.jpg /home/marcos/Proyecto/Mio/simple/NoCelulas/$i.jpg > FICHERO ./FICHERO #En cada imagen creada, insertamos 400 puntos.jpg ms situados aleatoriamente for j in $(seq 1 400) do #echo "" > FICHERO VARH=$(($RANDOM%2399)) VARV=$(($RANDOM%2399)) echo composite -geometry +$VARH+$VARV puntos.jpg /home/marcos/Proyecto/Mio/simple/NoCelulas/$i.jpg /home/marcos/Proyecto/Mio/simple/NoCelulas/$i.jpg > FICHERO ./FICHERO done done
65
Tras aplicar el programa con estas imgenes de fondo, el resultado no fue mejor. El bucle infinito mencionado anteriormente tambin se produca en algunas de estas imgenes. En otras, sin embargo, el clasificador construa las reglas adecuadamente formando la etapa correspondiente. Decidimos entonces separar las imgenes que finalizaban correctamente el proceso para juntarlas a otros fondos que conseguiramos posteriormente. El resto de imgenes fueros desechadas. Viendo el poco xito obtenido hasta ahora con las muestras negativas, decidimos buscar otro tipo de imgenes no construidas por nosotros. Para ello, recurrimos a colecciones de imgenes obtenidas a travs de Internet, seleccionando las ms apropiadas para nuestros ensayos. Tratamos de obtener primero imgenes en blanco y negro y posteriormente usamos tambin imgenes en color hasta llegar a un nmero apropiado. Segn bamos recopilando nuevas imgenes de fondo, probbamos todo el mecanismo de deteccin para ver su evolucin. Fichero ndice: Las muestras negativas tambin requieren un fichero de ndices de extensin idx o txt para que el programa pueda trabajar con ellas. Este fichero es ms sencillo que el utilizado en las muestras positivas, ya que slo contiene el nombre de las imgenes usadas como fondos. La diferencia entre este nombre y el de las muestras positivas, es que esta vez se requiere la direccin relativa de cada foto, y no la absoluta como ocurra con las muestras positivas. A continuacin mostramos una parte del fichero de ndices utilizado, de nombre backNoCelulas.idx:
NoCelulas/1.jpg NoCelulas/2.jpg NoCelulas/3.jpg NoCelulas/4.jpg NoCelulas/5.jpg NoCelulas/6.jpg NoCelulas/7.jpg NoCelulas/8.jpg NoCelulas/9.jpg NoCelulas/10.jpg NoCelulas/11.jpg NoCelulas/12.jpg NoCelulas/13.jpg NoCelulas/14.jpg NoCelulas/15.jpg NoCelulas/16.jpg
66
67
El nmero de imgenes hasta ese momento era muy escaso, y el clasificador realizaba alrededor de 4 etapas (dependiendo del orden de las imgenes el nmero variaba de 3 a 5), nmero que no ofreca garantas para un clasificador potente. Decidimos, como en el caso de las imgenes simples, obtener colecciones de imgenes de Internet para aadir a las muestras negativas. Primero buscamos imgenes microscpicas relacionadas con clulas, para obtener fondos similares a los nuestros. El nmero de imgenes encontradas fue muy escaso, por lo que decidimos buscar otros tipos de imgenes ms generales y que a su vez tuvieran algn parecido con los fondos ya obtenidos, como podan ser imgenes de agua, mares, cielos, etc. En un primer momento seleccionamos alrededor de 200 imgenes. Esta cantidad segua siendo insuficiente, por lo que recurrimos de nuevo a imgenes generales, esta vez de temtica variada. Llegamos a las 450 imgenes y 9 etapas. En ejecuciones posteriores, llegamos a las 2000 imgenes y 10 etapas. Mostramos a continuacin algunas de estas imgenes:
68
69
70
Durante nuestras pruebas, utilizamos distintos valores en los comandos del programa Haartraining. Por ejemplo, para las imgenes reales utilizamos:
$DIRECTORIOBASE/opencv-0.9.7/apps/haartraining/src/opencv-haartraining data eyes_classifier_take_1 -vec celulas.vec -w 20 -h 20 -bg backNoCelulas.idx -nsplits 1 -mem 800 -minhitrate 0.995 -maxfalsealarm 0.5 -npos 107 -nneg 2000 Uno de los comandos para las imgenes simples fue el siguiente: $DIRECTORIOBASE/opencv-0.9.7/apps/haartraining/src/opencv-haartraining data eyes_classifier_take_1 -vec indexSimple.vec -w 14 -h 14 -bg backNoCelulasGrande.idx -nstages 14 -nsplits 1 -mem 800 -minhitrate 0.995 -maxfalsealarm 0.5 -npos 4000 nneg 2000
Tras su ejecucin, se van presentando por pantalla diversa informacin referente a la etapa en construccin, nmero de splits, tiempos de ejecucin, etc. A continuacin se muestra la salida del programa por pantalla para un clasificador de 10 etapas:
marcos@lock:~/Proyecto/Haartraining/Simples$ ./haartraining_simple Data dir name: eyes_classifier_take_1 Vec file name: indexSimple.vec BG file name: backNoCelulasGrande.idx Num pos: 4000 Num neg: 2000 Num stages: 14 Num splits: 1 (stump as weak classifier) Mem: 800 MB Symmetric: TRUE Min hit rate: 0.995000 Max false alarm rate: 0.500000 Weight trimming: 0.950000 Equal weights: FALSE Mode: BASIC Width: 14 Height: 14 Max num of precalculated features: 23301 Applied boosting algorithm: GAB Error (valid only for Discrete and Real AdaBoost): misclass Max number of splits in tree cascade: 0 Min number of positive samples per cluster: 500 Required leaf false alarm rate: 6.10352e-05 Tree Classifier Stage +---+ | 0| +---+ Number of features used : 10416 Parent node: NULL *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 1 BACKGROUND PROCESSING TIME: 0.00
71
Precalculation time: 16.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.960609| 1.000000| 1.000000| 0.122333| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-1.510518| 1.000000| 1.000000| 0.213333| +----+----+-+---------+---------+---------+---------+ | 3|100%|-|-0.703373| 1.000000| 0.397500| 0.078333| +----+----+-+---------+---------+---------+---------+ Stage training time: 5.00 Number of used features: 3 Parent node: NULL Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+ | 0| +---+ 0 Parent node: 0 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.468055 BACKGROUND PROCESSING TIME: 0.00 Precalculation time: 17.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.951255| 1.000000| 1.000000| 0.131167| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.633671| 1.000000| 0.634500| 0.060667| +----+----+-+---------+---------+---------+---------+ | 3| 87%|-|-0.332637| 1.000000| 0.456000| 0.042500| +----+----+-+---------+---------+---------+---------+ Stage training time: 5.00 Number of used features: 3 Parent node: 0 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+ | 0| 1| +---+---+ 0---1 Parent node: 1 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.28401 BACKGROUND PROCESSING TIME: 0.00 Precalculation time: 15.00
72
+----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.590878| 1.000000| 1.000000| 0.210000| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-1.165284| 1.000000| 1.000000| 0.247667| +----+----+-+---------+---------+---------+---------+ | 3|100%|-|-1.723517| 1.000000| 1.000000| 0.062167| +----+----+-+---------+---------+---------+---------+ | 4| 79%|+|-1.006552| 1.000000| 0.478000| 0.044167| +----+----+-+---------+---------+---------+---------+ Stage training time: 6.00 Number of used features: 4 Parent node: 1 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+ | 0| 1| 2| +---+---+---+ 0---1---2 Parent node: 2 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.171453 BACKGROUND PROCESSING TIME: 1.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.845885| 1.000000| 1.000000| 0.175667| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.640866| 1.000000| 0.694500| 0.121833| +----+----+-+---------+---------+---------+---------+ | 3| 89%|-|-0.967728| 1.000000| 0.694500| 0.109167| +----+----+-+---------+---------+---------+---------+ | 4| 90%|+|-0.682702| 1.000000| 0.554500| 0.075500| +----+----+-+---------+---------+---------+---------+ | 5| 97%|-|-0.456611| 1.000000| 0.349500| 0.071167| +----+----+-+---------+---------+---------+---------+ Stage training time: 8.00 Number of used features: 5 Parent node: 2 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+ | 0| 1| 2| 3| +---+---+---+---+ 0---1---2---3 Parent node: 3
73
*** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.052719 BACKGROUND PROCESSING TIME: 0.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-| 0.277977| 1.000000| 0.565000| 0.188333| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.349622| 1.000000| 0.565000| 0.182000| +----+----+-+---------+---------+---------+---------+ | 3| 91%|-|-0.044455| 1.000000| 0.289000| 0.139167| +----+----+-+---------+---------+---------+---------+ Stage training time: 5.00 Number of used features: 3 Parent node: 3 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+ | 0| 1| 2| 3| 4| +---+---+---+---+---+ 0---1---2---3---4 Parent node: 4 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.0125041 BACKGROUND PROCESSING TIME: 1.00 Precalculation time: 14.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.578131| 1.000000| 1.000000| 0.199333| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-1.363890| 1.000000| 1.000000| 0.205500| +----+----+-+---------+---------+---------+---------+ | 3|100%|-|-0.788150| 1.000000| 0.590000| 0.107167| +----+----+-+---------+---------+---------+---------+ | 4|100%|+|-0.373179| 1.000000| 0.321000| 0.121167| +----+----+-+---------+---------+---------+---------+ Stage training time: 5.00 Number of used features: 4 Parent node: 4 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| +---+---+---+---+---+---+ 0---1---2---3---4---5 Parent node: 5
74
*** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.00282609 BACKGROUND PROCESSING TIME: 5.00 Precalculation time: 14.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-| 0.212121| 1.000000| 0.650000| 0.216667| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.106088| 1.000000| 0.650000| 0.386500| +----+----+-+---------+---------+---------+---------+ | 3|100%|-|-0.390762| 1.000000| 0.651000| 0.202167| +----+----+-+---------+---------+---------+---------+ | 4| 87%|+|-0.796294| 1.000000| 0.671500| 0.202167| +----+----+-+---------+---------+---------+---------+ | 5| 81%|-|-0.521858| 1.000000| 0.443000| 0.103333| +----+----+-+---------+---------+---------+---------+ Stage training time: 8.00 Number of used features: 5 Parent node: 5 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| +---+---+---+---+---+---+---+ 0---1---2---3---4---5---6 Parent node: 6 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.00220652 BACKGROUND PROCESSING TIME: 6.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.953729| 1.000000| 1.000000| 0.156333| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.743042| 1.000000| 0.774500| 0.108667| +----+----+-+---------+---------+---------+---------+ | 3| 92%|-| 0.047768| 1.000000| 0.235500| 0.078500| +----+----+-+---------+---------+---------+---------+ Stage training time: 5.00 Number of used features: 3 Parent node: 6 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| 7| +---+---+---+---+---+---+---+---+ 0---1---2---3---4---5---6---7
75
Parent node: 7 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.000462043 BACKGROUND PROCESSING TIME: 26.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.549020| 1.000000| 1.000000| 0.220500| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.114948| 1.000000| 0.450000| 0.220500| +----+----+-+---------+---------+---------+---------+ Stage training time: 2.00 Number of used features: 2 Parent node: 7 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| 7| 8| +---+---+---+---+---+---+---+---+---+ 0---1---2---3---4---5---6---7---8 Parent node: 8 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 0.000300981 BACKGROUND PROCESSING TIME: 40.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-| 0.185549| 1.000000| 0.687000| 0.229000| +----+----+-+---------+---------+---------+---------+ | 2|100%|+| 0.288253| 1.000000| 0.487500| 0.162500| +----+----+-+---------+---------+---------+---------+ Stage training time: 3.00 Number of used features: 2 Parent node: 8 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| +---+---+---+---+---+---+---+---+---+---+ 0---1---2---3---4---5---6---7---8---9 Parent node: 9 *** 1 cluster ***
76
POS: 4000 4000 1.000000 NEG: 2000 0.00011092 BACKGROUND PROCESSING TIME: 107.00 Precalculation time: 15.00 +----+----+-+---------+---------+---------+---------+ | N |%SMP|F| ST.THR | HR | FA | EXP. ERR| +----+----+-+---------+---------+---------+---------+ | 1|100%|-|-0.381691| 1.000000| 1.000000| 0.306000| +----+----+-+---------+---------+---------+---------+ | 2|100%|+|-0.639728| 1.000000| 1.000000| 0.206333| +----+----+-+---------+---------+---------+---------+ | 3|100%|-|-0.875830| 1.000000| 1.000000| 0.158667| +----+----+-+---------+---------+---------+---------+ | 4| 82%|+|-1.283330| 1.000000| 1.000000| 0.195167| +----+----+-+---------+---------+---------+---------+ | 5| 80%|-|-1.013861| 1.000000| 0.665500| 0.199333| +----+----+-+---------+---------+---------+---------+ | 6| 83%|+|-0.813190| 1.000000| 0.401000| 0.100000| +----+----+-+---------+---------+---------+---------+ Stage training time: 9.00 Number of used features: 6 Parent node: 9 Chosen number of splits: 0 Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| +---+---+---+---+---+---+---+---+---+---+---+ 0---1---2---3---4---5---6---7---8---9--10 Parent node: 10 *** 1 cluster *** POS: 4000 4000 1.000000 NEG: 2000 5.48842e-05 BACKGROUND PROCESSING TIME: 208.00 Required leaf false alarm rate achieved. Branch training terminated. Total number of splits: 0 Tree Classifier Stage +---+---+---+---+---+---+---+---+---+---+---+ | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| +---+---+---+---+---+---+---+---+---+---+---+ 0---1---2---3---4---5---6---7---8---9--10 Cascade performance POS: 4000 4000 1.000000 NEG: 2000 5.85558e-05 BACKGROUND PROCESSING TIME: 224.00
77
Tericamente, para conseguir un buen clasificador, se deberan reunir 2000 muestras como mnimo. Siempre ser mejor el clasificador cuantas ms muestras positivas se le proporcionen, pero si bajamos de esta cifra, el detector obtenido no tendra una tasa de deteccin que se pueda aceptar. As que tras el flag -npos, escribiremos como mximo el nmero de muestras de las que disponemos a diferencia del caso de las muestras negativas, ya que las primeras ya son del tamao que se solicita y por tanto, no se pueden obtener ms. El caso de las muestras negativas sin embargo es diferente; el archivo que se utiliza contiene imgenes completas que, normalmente, sern de un tamao bastante superior al de la muestra, as que el programa puede barrer cada una de las imgenes del archivo y encontrar varios candidatos negativos. De este modo, el archivo puede contener 1000 imgenes por ejemplo, y el flag -nneg puede valer 3000. De todas formas, la mejor prctica sera ajustar el valor de nneg al nmero de imgenes reales que proporcione el fichero de fondos. En cuanto al nmero de etapas del clasificador, se podra decir que hay un nmero ptimo diferente para cada clasificador dependiendo del resto de parmetros y del tipo de imgenes y muestras a las que vaya destinado. Pero por lo general, se puede asegurar que un clasificador presentar un buen comportamiento a partir de las 14 etapas que efectivamente es el valor por defecto del programa. Aunque tambin durante las distintas pruebas, obtuvimos casos de un clasificador con un ndice de aciertos mayor con menos etapas. Al ejecutar el programa, se van almacenando las etapas que se construyen en un archivo de nombre AdaBoostCARTHaarClassifier.txt del directorio correspondiente a la etapa. Este directorio es llamado por defecto eyes_classifier_take_1 y, para un clasificador de 10 etapas, tendr esta forma:
78
La siguiente figura es el contenido real del fichero AdaBoostCARTHaarClassifier.txt que constituye la primera etapa de un clasificador para nmeros construido con 2000 muestras positivas y 2000 candidatos negativos. En este fichero se encuentra toda la informacin necesaria para decidir si una subventana es el objeto buscado o no. En l aparecen 2 caractersticas como indica el primer nmero que aparece en el fichero. El siguiente nmero siempre es un 1 y anuncia el comienzo de la descripcin de una caracterstica. El siguiente refleja el nmero de rectngulos de los que se compone la caracterstica, seguido de las mismas lneas, una por cada rectngulo especificando sus coordenadas que se encuentran ordenadas en la forma: Xorigen, Yorigen, ancho, alto, 0, peso. La siguiente lnea recoge el nombre de la caracterstica en cuestin y finalmente encontramos con el umbral de la caracterstica como conjunto y los de los rectngulos que la forman por separado. Las dos cifras que se encuentran tras el primer umbral determinan el camino que ha de seguir la subventana dependiendo de si supera dicho umbral o no (nodos de la izquierda y de la derecha). En este caso, el clasificador se construy sin splits, es decir, con una nica rama que permite seguir hacia adelante o ser rechazado (por este motivo una de las bifurcaciones se expresa como 0, ya que no existe). 2 1 2 4 6 6 2 0 -1 7 6 3 2 0 2 haar_x2 -1.722216e-04 0 -1 -9.655688e-01 4.842538e-01 1 2 1 0 12 14 0 -1 5 0 4 14 0 3 haar_x3 -1.563832e-01 0 -1 5.584581e-01 -7.127285e-01 -4.071107e-01 -1 -1 Figura 19: Contenido del fichero AdaBoostCARTHaarClassifier.txt
79
3.4 Performance
Una vez ejecutado el programa Haartraining, el clasificador puede ser probado con la utilidad Performance. Es conveniente realizar el test del clasificador con muestras distintas a las utilizadas durante el entrenamiento. El comando Performance tiene los siguientes argumentos: -data: nombre del directorio donde se almacena el clasificador. -info: preceder al nombre del fichero lista que contendr todas las imgenes de los objetos que constituyen las muestras positivas. -maxSizeDiff y maxPosDiff: determinan la coincidencia de deteccin de los rectngulos. Los valores por defecto son 1,5 y 0,3 respectivamente. -sf: parmetro de deteccin. Por defecto vale 0,3. -w y h: tamao de las muestras (en pxeles). Debe ser el mismo que el usado durante el entrenamiento con la utilidad Haartraining.
La salida por pantalla ser de la forma: +================================+======+======+======+ | File Name | Hits |Missed| False| +================================+======+======+======+ donde File Name indica el nombre del archivo analizado, Hits muestra el nmero de objetos correctos encontrados en el archivo, Missed el nmero de objetos no encontrados, que el programa detecta que existen pero no los encuentra (falsos negativos) y False el nmero de falsas alarmas, que no existen pero el programa los detecta (falsos positivos). Tras su ejecucin, el programa crear por cada imagen indicada en el fichero de ndices, otra con las siguientes caractersticas: Variar el nombre del archivo, anteponiendo el cdigo det- al que tena la imagen original. Es decir, si inicialmente tenemos una imagen de nombre salida.jpg, el programa crear otra con el nombre det-salida.jpg. Si el objeto a buscar es encontrado correctamente, la nueva imagen contendr un rectngulo rojo alrededor del objeto; si devolvi un falso negativo, la imagen ser igual a la original y si devolvi un falso positivo, la imagen contendr un rectngulo rojo situado donde el programa detect el falso positivo. Las nuevas imgenes se guardarn en el mismo directorio donde se encuentran las originales.
80
Mostramos a continuacin ejemplos de imgenes con objetos encontrados, falsos positivos y falsos negativos:
81
Una de las salidas obtenidas tras la ejecucin del programa es la mostrada a continuacin. En ella se analizaron 100 imgenes y se obtuvo un porcentaje de acierto del 48%.
+================================+======+======+======+ | File Name | Hits |Missed| False| +================================+======+======+======+ | salida_1.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_2.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_3.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_4.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_5.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_6.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_7.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_8.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_9.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_10.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_11.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_12.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_13.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_14.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_15.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_16.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_17.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_18.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_19.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_20.jpg| 1| 0| 0|
82
+--------------------------------+------+------+------+ | salida_21.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_22.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_23.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_24.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_25.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_26.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_27.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_28.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_29.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_30.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_31.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_32.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_33.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_34.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_35.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_36.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_37.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_38.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_39.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_40.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_41.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_42.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_43.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_44.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_45.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_46.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_47.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_48.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_49.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_50.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_51.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_52.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_53.jpg| 1| 0| 0| +--------------------------------+------+------+------+
83
| salida_54.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_55.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_56.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_57.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_58.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_59.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_60.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_61.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_62.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_63.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_64.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_65.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_66.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_67.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_68.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_69.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_70.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_71.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_72.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_73.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_74.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_75.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_76.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_77.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_78.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_79.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_80.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_81.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_82.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_83.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_84.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_85.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_86.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_87.jpg| 1| 0| 0|
84
+--------------------------------+------+------+------+ | salida_88.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_89.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_90.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_91.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_92.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_93.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_94.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_95.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_96.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_97.jpg| 0| 1| 0| +--------------------------------+------+------+------+ | salida_98.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_99.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | salida_100.jpg| 1| 0| 0| +--------------------------------+------+------+------+ | Total| 48| 52| 0| +================================+======+======+======+ Number of stages: 11 Number of weak classifiers: 40 Total time: 10.000000 11 48 0 0.480000 0.000000 48 0 0.480000 0.000000 4 0 0.040000 0.000000 1 0 0.010000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000 0 0 0.000000 0.000000
85
0 0 0 0 0 0
0 0 0 0 0 0
El comando utilizado durante la ejecucin del Performance, vari en funcin del tamao de la ventana de bsqueda introducida, pero un ejemplo de dicho comando es el siguiente: $DIRECTORIOBASE/opencv-0.9.7/apps/haartraining/src/opencv-performance data $DIRECTORIOBASE/simple/eyes_classifier_take_1/ -info CopiaIndexSimple.idx -w 20 -h 20
86
87
Como se puede observar, en las nuevas imgenes hay una gran prdida de calidad, puesto que el rectngulo inicial en negro se difumina en las sucesivas fotos creadas, por lo que no es una aplicacin muy til y su uso es muy limitado.
88
Un extracto del archivo de ndices modificado con informacin de las nuevas imgenes es el siguiente: 0001_0410_0717_1413_1413.jpg 1 410 717 1413 1413 0002_0524_0683_1062_1062.jpg 1 524 683 1062 1062 0003_1603_0486_0243_0243.jpg 1 1603 486 243 243 0004_1154_0983_0507_0507.jpg 1 1154 983 507 507 0005_0731_1428_0486_0486.jpg 1 731 1428 486 486 0006_0273_0209_0595_0595.jpg 1 273 209 595 595 0007_1247_0898_0639_0639.jpg 1 1247 898 639 639 0008_0707_0443_1244_1244.jpg 1 707 443 1244 1244 0009_1170_1559_0598_0598.jpg 1 1170 1559 598 598 0010_0422_0236_1531_1531.jpg 1 422 236 1531 1531 0011_0372_0492_1323_1323.jpg 1 372 492 1323 1323 0012_1080_1541_0224_0224.jpg 1 1080 1541 224 224 0013_0417_0313_0988_0988.jpg 1 417 313 988 988 0014_0365_0443_0883_0883.jpg 1 365 443 883 883 0015_0246_0236_0881_0881.jpg 1 246 236 881 881 0016_1660_0409_0355_0355.jpg 1 1660 409 355 355 0017_0873_1755_0286_0286.jpg 1 873 1755 286 286 0018_0386_1005_1275_1275.jpg 1 386 1005 1275 1275 0019_0712_0823_1468_1468.jpg 1 712 823 1468 1468 0020_1398_0673_0143_0143.jpg 1 1398 673 143 143
89
Centrndonos en el directorio Haartraining, dentro de l nos encontramos con otras dos carpetas, una para la aplicacin del procedimiento sobre clulas reales y otra sobre imgenes simples:
Los dos directorios tendrn la misma estructura, por lo que nos centraremos en uno de ellos, concretamente en el de las clulas simples:
90
Como podemos observar, en este directorio se encuentra lo siguiente: Cuatro scripts que realizan las operaciones explicadas en los apartados anteriores: ejecucin del programa Createsamples para la creacin del fichero de extensin vec, generacin de fondos que constituirn la muestras negativas, generacin de las muestras positivas y aplicacin del programa Haartraining. Dos ficheros de ndices, uno para las muestras positivas (indexSimple.idx) y otro para las negativas (backNoCelulas.idx). Un directorio donde se almacenan las distintas etapas del clasificador (eyes_clasiffier_take_1) Un directorio donde se ubicarn los archivos necesarios para la aplicacin del paso Application. Dos directorios para las muestras, uno para las negativas y otro para las positivas.
91
En la carpeta de las muestras negativas, slo se encuentran las imgenes de los fondos, mientras que en el de las muestras positivas, adems de las imgenes creadas, situaremos una copia del indexSimple.idx y el script que ejecuta el testeador (Performance). Este script debe ser situado en esta carpeta, ya que en caso de ubicarlo con el resto de scripts no lograr detectar las imgenes. Podemos evitar realizar una copia del archivo de ndices poniendo el enlace correspondiente al indexSimple.idx dentro del script_Performance. Dentro del directorio de nombre Application, guardaremos los siguientes archivos: Foto a evaluar, a partir de la cual el programa crear nuevas imgenes. El archivo de ndices copia del original, que el programa modificar introduciendo datos de las nuevas imgenes creadas. El script de aplicacin del Createsamples.
92