Sie sind auf Seite 1von 92

Tabla de Contenidos

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

Manual del programador

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

Manual del programador

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

Manual del programador

Manual del programador 1 Introduccin

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.

Manual del programador

Algoritmo mastitis

2.1 Documentacin de clases


2.1.1 Referencia de la clase CV
#include <cv.h> En el mdulo Cv encontramos las primitivas de anlisis, procesamiento y reconocimiento de imgenes que son realizadas sobre las estructuras definidas en el mdulo CxCore. La biblioteca Cv define tambin operadores estndar para el clculo de gradientes, deteccin de bordes, esquinas y contornos, conversin de modelos de color, operaciones morfolgicas como dilatacin, erosin y adelgazamiento, transformadas geomtricas, etc. Tambin encontraremos funciones para tratar aspectos de la deteccin de objetos mediante su anlisis y movimiento y la deteccin de patrones a travs de conjuntos de imgenes.

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:

Manual del programador

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.

Manual del programador

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.

Manual del programador

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.

Manual del programador

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:

Manual del programador

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.

Manual del programador

10

2.1.2 Referencia a la clase HighGUI


#include <highgui.h> HighGUI permite la grabacin de imgenes en disco en los formatos vistos en el punto 1.5 de esta documentacin. Dispone de funciones para facilitar la captura y reproduccin de video y de mtodos para la captura de eventos de teclado (deteccin de teclas presionadas) o ratn.

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.

MODIFICA: Destruye la ventana de nombre name.

Manual del programador

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

Manual del programador

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.

Manual del programador

13

2.1.3 Referencia a la clase CxCore


#include <cxcore.h> El mdulo CxCore define e implementa las estructuras y operaciones que permiten realizar la edicin y manipulacin bsica de la imagen. Proporciona la estructura bsica con la que Intel representa las imgenes, denominada IplImage y que, como vimos anteriormente, est formado por una cabecera que contiene los atributos de la imagen y los punteros a los datos asociados. Adems, CxCore dispone de estructuras de datos dinmicas y operadores en las que se apoyan el resto de mdulos, como son los vectores (cvArr), matrices (cvMat), imgenes, grafos, etc. La mayora recibe por parmetro un vector mscara para especificar sobre qu elementos de la estructura se aplica el operador. Podremos encontrar operadores aritmticos (Add, Mult, Sub, etc.), lgicos (AND, OR, NOT, XOR), de comparacin, etc., as como funciones para aplicar clculos estadsticos (SUM, MAX, MIN, AVG) y operadores de conversin de tipo o escala de colores (ConvertScale).

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;

Manual del programador

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:

Manual del programador

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

Manual del programador

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).

Manual del programador

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.

Manual del programador

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.

Manual del programador

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.

typedef struct CvSeq { CV_SEQUENCE_FIELDS() } donde CV_SEQUENCE_FIELDS() se define de la siguiente manera:

Manual del programador

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.

Manual del programador

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))

Manual del programador

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.

line_type = CV_AA MODIFICA:

Dibuja los contornos exteriores de la imagen si thickness thickness < 0.

0 el rea interior a los contornos si

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.

Manual del programador

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)

Manual del programador

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

Manual del programador

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.

Manual del programador

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.

Manual del programador

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:

Figura 3: Imagen pasada como parmetro

Manual del programador

28

2.2.1 Explicacin del cdigo 2.2.1.1 Includes


#include <cv.h> // incluye la biblioteca de OpenCV

#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>

2.2.1.2 Declaracin e inicializacin de variables


// Origen contendr la imagen inicial pasada por parmetro:
IplImage *origen;

/* 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);

Manual del programador

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. */

Manual del programador

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;

// Otros lmites usados:


long int LimSupCelsContorno long int LimInfCelsContorno long int LimSupSinBordes1 long int LimInfSinBordes1 long int LimSupSinBordes2 long int LimInfSinBordes2 = 1700000; = 160000; = 1700000; = 160000; = 340000; = 5000;

long int LimSupCelEliminadas = 4999; long int LimInfCelEliminadas = 2000; int TamMedioCelulas = 12000;

// Declaramos variables que almacenarn distintas reas :


double area1_contorno double area2_contorno double area_positiva double area_negativa double area_elipse double area_total double cociente = 0; = 0; = 0; = 0; = 0; = 0; = 0;

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;

Manual del programador

31

2.2.1.3 Mostrar Imagen


void MostrarImagen (char *nombre, IplImage *im, int val) { cvNamedWindow (nombre, val); cvShowImage (nombre, im); cvWaitKey (0); // Espera indefinidamente hasta que se pulse una tecla cvDestroyWindow (nombre); // Destruye la ventana despus de pulsar la tecla anterior }

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.

Manual del programador

32

2.2.1.4 Inicio del main


int main (int argc, char** argv) { // argc contiene el nmero de argumentos de la llamada mientras que argv la lista de esos argumentos. IplImage *origen; // Cargamos en origen la imagen inicial que queremos procesar. if (argc == 2 && (origen = cvLoadImage (argv[1], 0)) != 0) { /* */ // Resto de declaraciones: 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); CvMemStorage* mem = cvCreateMemStorage(0); argv[1]: archivo que contiene la imagen 0: la imagen se carga con un canal

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;

Manual del programador

33

int LimiteInfByN int LimiteSupByN

= 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;

MostrarImagen ("Foto origen sin ningn tratamiento", origen);

Figura 4: Primera imagen mostrada

Manual del programador

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);

MostrarImagen ("Foto origen en blanco y negro", ByN);

Manual del programador

35

Figura 5: Imagen inicial binarizada

// 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 */

Manual del programador

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),

Manual del programador

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)

Manual del programador

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)

area2_contorno += fabs (cvContourArea (contorno1, CV_WHOLE_SEQ));

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

Manual del programador

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,

MostrarImagen ("Contornos exteriores", BordesExt, 0);

Figura 6: Bordes exteriores

Manual del programador

40

cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/03_BordesExt.png", BordesExt); /* 02_BordesExt.png: nombre del archivo BordesExt: nombre de la imagen a guardar */

Manual del programador

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.

Figura 7: Imagen en blanco y negro sin bordes exteriores

Manual del programador

42

cvSaveImage($DIRECTORIOBASE/Tratamiento_imagen/04_SinBordes.png", ByNSinBordes); /* 04_SinBordes.png: nombre del archivo ByNSinBordes: nombre de la imagen a guardar */

Manual del programador

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),

Manual del programador

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 */

Manual del programador

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 */

Manual del programador

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 >=

Manual del programador

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 */

cvDrawContours (ByNSinBordes, CV_RGB(0,0,255), -1, 1, 8); /*

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);

Manual del programador

48

Figura 8: Clculo de elipses (2)

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 >=

Manual del programador

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),

Manual del programador

50

Figura 9: Clulas eliminadas

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,

Manual del programador

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 */

} // fin_if } // fin_for } //fin_if }//fin_for

Manual del programador

52

2.2.1.9 Tratamiento imagen final

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: " <<

cvFindContours (ByNSinBordes, mem, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); /* ByNSinBordes: imagen fuente

&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

Manual del programador

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);

Figura 10: Imagen final

Manual del programador

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

Manual del programador

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.

3.2 Imgenes de entrenamiento


La parte ms importante del proceso de entrenamiento del clasificador es la de recoleccin de muestras positivas y negativas, de forma que de ellas se puedan extraer las mejores reglas posibles que formen un detector de objetos potente. Como ya hemos explicado anteriormente, el conjunto de imgenes se dividen en dos grupos: las muestras positivas y las negativas. El primer grupo consiste en tomar mltiples ejemplos de la clase objeto de inters. A estas imgenes las llamaremos muestras positivas (deben contener los objetos que queremos que el sistema detecte, en nuestro caso clulas). Junto a ellas, debemos contar con una coleccin de imgenes donde no se encuentren dichos objetos que pretendemos detectar. A este grupo lo llamaremos muestras negativas. En un caso ideal, el algoritmo partir del total del espacio muestral, distribuido en las muestras positivas y negativas. As, el clasificador obtenido tendra una probabilidad de deteccin mxima y la probabilidad de falso positivo sera mnima. Sin embargo, esto es imposible, por lo que resulta fundamental realizar un muestreo adecuado.

Manual del programador

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

(x11, y11) h11

Figura 11: Parmetros fichero de ndices

Manual del programador

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.

Manual del programador

58

3.2.2 Muestras positivas 3.2.2.1 Imgenes simples


Como comentamos anteriormente, formamos un conjunto de muestras positivas de manera automtica. Para ello, construimos un rectngulo negro y un fondo blanco como los siguientes:

Figura 12: Fondo y primer plano de la imagen simple

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.

Manual del programador

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

$DIRECTORIOBASE /Imagenes_muestras/salida_$i.jpg >> FICHERO


echo $DIRECTORIOBASE/Imagenes_muestras/salida_$i.jpg 1 $VARH $VARV 14 14 >> indexSimple.idx echo salida_$i.jpg 1 $VARH $VARV 14 14 >> Imagenes_muestras/CopiaIndexSimple.idx ./FICHERO

done

Ejemplos de las imgenes formadas mediante el script anterior son las siguientes:

Figura 13: Muestras positivas aleatorias

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:

Manual del programador

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

Manual del programador

61

3.2.2.2 imgenes clulas


Para realizar el procedimiento Haartraining con imgenes reales de clulas, utilizamos las proporcionadas por el equipo de microscopa. El principal problema que encontramos a priori, es el pequeo nmero de imgenes disponibles y la gran variedad de las mismas, ya que en ellas haba clulas epiteliales, monocitos, linfocitos... todas con caractersticas distintas. En total, se nos proporcionaron 65 fotos, de las que tuvimos que desechar 23 por su poca nitidez o por ser repetidas. Una parte del fichero de ndices creado, de nombre celulas.idx, es la siguiente:

/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

Manual del programador

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

Manual del programador

63

3.2.3 Muestras negativas 3.2.3.1 Imgenes simples


A continuacin explicaremos el proceso de obtencin de las muestras negativas o fondos (background) para las imgenes del rectngulo negro sobre fondo blanco. En un principio, consideramos que lo ms apropiado sera poner como fondos imgenes totalmente en blanco, de forma que el clasificador viera el gran contraste entre stas y el rectngulo negro. Tras formar 200 imgenes blancas y ejecutar el programa Haartraining vimos que entraba en un bucle infinito al evaluar cada imagen. Tras estudiar el caso, llegamos a la conclusin de que no era posible poner dichas imgenes blancas como fondo, ya que para cada una de ellas se trataba de construir las reglas necesarias para el clasificador. El programa trataba de encontrar informacin que le permitiera formar dichas reglas y, al no encontrarlas, entraba en el bucle infinito buscando indefinidamente alguna regla a construir. El siguiente paso fue construir unas imgenes de fondo formadas por numerosos puntos negros sobre fondo blanco. Partimos de estas dos imgenes:

Figura 14: Fondo blanco y puntos negros

Manual del programador

64

Construimos el siguiente shell-script para formar automticamente las imgenes:

#! /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

El resultado es un conjunto de imgenes como la siguiente:

Figura 15: Imagen con puntos negros

Manual del programador

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

Manual del programador

66

3.2.3.2 Imgenes clulas


Para las muestras negativas de imgenes reales de clulas microscpicas, nuestra primera idea fue la siguiente: cogeramos las fotos proporcionadas por el equipo de microscopa y, utilizando el programa de libre distribucin GIMP, cortaramos las clulas de la imagen para dejar slo los fondos. Con este mtodo, obtuvimos 152 imgenes. Algunos ejemplos de las imgenes obtenidas mediante este proceso son los siguientes:

Figura 16: Imgenes de fondo

Manual del programador

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:

Manual del programador

68

Figura 17: Imgenes de fondo (2)

Manual del programador

69

3.3 Comando Haartraining


Las etapas de funcionamiento del programa Haartraining fueron explicadas anteriormente con detalle. El comando para ejecutar el Haartraining tiene los siguientes argumentos: -data: nombre del directorio donde se almacena el clasificador. -vec: nombre del fichero de extensin vec creado con la utilidad Createsamples. -bg: nombre del fichero ndice de muestras negativas. -npos: nmero de muestras positivas usadas en el entrenamiento de cada etapa del clasificador. Su valor por defecto es 2000. -nneg: Aqu se introduce el nmero de muestras negativas que se le solicita al entrenamiento que encuentre en las imgenes de fondo del tamao especificado. Para cada etapa que construya, tendr que encontrar este nmero basndose en las etapas de clasificacin que ya ha construido, de forma que sean candidatos que le sigan aportando informacin. Su valor por defecto tambin es 2000. -nstages: nmero de etapas a construir. Por defecto es 14. -nsplits: Hace referencia a la estructura del rbol de clasificacin ya que permite especificar el nmero de nodos en los que se dividir cada stump. -mem: Permite seleccionar la memoria de la que har uso el programa para la ejecucin. Cuanta ms se asigne, sta ser ms rpida. -sym; -nonsym: especifica si la clase del objeto bajo entrenamiento tiene simetra vertical o no. La simetra vertical acelera el proceso de entrenamiento. -minhitrate: Mnima tasa de deteccin que se desea alcanzar en cada etapa, siendo la tasa del clasificador completo ese mismo valor elevado al nmero de etapas. El valor por defecto es 0.995. -maxfalsealarm: Valor mximo para la falsa alarma de cada etapa. La total se obtiene de la misma forma que la tasa de deteccin. Su valor por defecto es de 0.5. -mode: Permite escoger, para las caractersticas Haar, si se desea el conjunto bsico (BASIC) o el conjunto extendido (ALL). La forma por defecto es la primera. -w: Sirve para especificar el ancho de las muestras positivas proporcionadas. Su valor por defecto es 24 pxeles. -h: dem que el anterior para el alto de las muestras. Su valor por defecto es tambin 24 pxeles, y esto se corresponde con los valores por defecto del Createsamples.

Manual del programador

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

Manual del programador

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

Manual del programador

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

Manual del programador

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

Manual del programador

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

Manual del programador

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 ***

Manual del programador

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

Manual del programador

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:

Figura 18: Directorio eyes_classifier_take_1 con diez etapas

Manual del programador

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

Manual del programador

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.

Manual del programador

80

Mostramos a continuacin ejemplos de imgenes con objetos encontrados, falsos positivos y falsos negativos:

Figura 20: Objeto encontrado (Hit)

Figura 21: falso positivo (False)

Manual del programador

81

Figura 22: Falso negativo (Missed)

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|

Manual del programador

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| +--------------------------------+------+------+------+

Manual del programador

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|

Manual del programador

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

Manual del programador

85

0 0 0 0 0 0

0 0 0 0 0 0

0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

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

Manual del programador

86

3.5 Creacin de ejemplos (Application)


Esta ltima parte del proceso de deteccin de Haartraining, es, al contrario de los anteriores apartados, de ejecucin voluntaria. Slo sera necesario aplicarlo en caso de que no dispusisemos de ms colecciones de imgenes para realizar el Performance. El sistema funciona de la manera siguiente: dada una imagen de ejemplo, que deber contener el objeto a buscar, el sistema la distorsiona, girndola y escalndola arbitrariamente, y la superpone a las imgenes de fondo proporcionadas. Si los argumentos del Createsamples img y info son especificados a la vez, entonces el programa crear ficheros de ejemplo y no el archivo de extensin vec que describimos en el apartado 9.3.2.1. Hay que tener en cuenta que durante la ejecucin del programa, se modifica el archivo de ndices (indexSimple.idx), aadiendo a cada lnea informacin de las nuevas imgenes creadas, por lo que tendremos que tener una copia del mismo para no perder los datos originales. A las nuevas imgenes se les dar el siguiente nombre: NmeroDeImagen_x_y_ancho_alto.jpg, donde x, y, ancho y alto son las coordenadas del objeto superpuesto al fondo. Es conveniente utilizar otros archivos de fondo que los ya usados durante el resto del proceso Haartraining. Un ejemplo de llamada a la aplicacin es la siguiente: /home/marcos/Proyecto/Paquetes/opencv-0.9.7/apps/haartraining/src/opencvcreatesamples -info indexSimple.idx -w 15 -h 15 -bg /home/marcos/Proyecto/Mio/simple/back.idx -img salida_1.jpg A continuacin mostramos algunas de las imgenes creadas a partir de una de las fotos simples creadas. La imagen inicial es la siguiente:

Figura 23: Imagen de partida para el Createsamples

Manual del programador

87

Algunas de las imgenes creadas a raz de la anterior son:

Figura 24: Imgenes creadas con Createsamples

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.

Manual del programador

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

Manual del programador

89

3.6 Ubicacin de los archivos


Durante el estudio de las distintas partes que componan el mtodo de deteccin del Haartraining, fuimos comprobando que los archivos que bamos creando deban ir ubicados en diferentes lugares. Para la ejecucin de dichas partes, creamos scripts con los comandos necesarios. A continuacin, mostramos a travs de capturas de pantalla la ubicacin de los archivos y directorios utilizados en la aplicacin del Haartraining: Inicialmente tenemos 2 directorios, uno dedicado a la parte de la deteccin de la mastitis y otra al procedimiento Haartraining:

Figura 25: rbol de directorios (1)

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:

Figura 26: rbol de directorios (2)

Los dos directorios tendrn la misma estructura, por lo que nos centraremos en uno de ellos, concretamente en el de las clulas simples:

Manual del programador

90

Figura 27: rbol de directorios (3)

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.

Figura 28: rbol de directorios (4)

Manual del programador

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.

Figura 29: rbol de directorios (5)

Manual del programador

92

Das könnte Ihnen auch gefallen