Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia

213
Proyecto fin de carrera Gonzalo Leandro Bravo ÍNDICE Pág. 0. Introducción. 4 1.Fase 1. Estudio del sistema de vigilancia, detección de movimiento. 10 1.1. Análisis por similitud (Correlación). 10 1.1.1. Descripción de las funciones a utilizar. SIMILITUD DE FOTOGRAMAS. 11 1.1.2. Inicio de las simulaciones. 14 1.2. Análisis por igualdad. 18 1.2.1. Descripción de las funciones a utilizar. IGUALDAD DE FOTOGRAMAS. 18 1.2.2. Inicio de las simulaciones. 20 1.2.3. Conclusiones relativas al análisis por similitud e igualdad. 23 1.3. Nuevos análisis. Verificación de conclusiones. 25 1.4. Simulación en exteriores y ausencia de movimiento. 27 1.4.1. Revisión de las funciones a utilizar. 27 1.4.2. Inicio de las simulaciones. 32 1.4.2.1.Secuencia exterior. 32 1.4.2.2.Secuencia con movimiento aleatoreo. 36 1.4.2.3.Ausencia de movimiento. 37 1.5. CONCLUSIONES DE FASE 1. 41 2. FASE 2. Implementación en Matlab y en C del algoritmo de Vigilancia. 43 2.1. Consideraciones previas. 43 2.2. Nuevo sistema de trabajo. Programación adaptable a C para leer ficheros BMP. 44 2.3. Programa en Matlab. 46 1

Transcript of Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia

Proyecto fin de carrera Gonzalo Leandro Bravo

ÍNDICE

Pág. 0. Introducción. 4

1.Fase 1. Estudio del sistema de vigilancia, detección de movimiento. 10

1.1. Análisis por similitud (Correlación). 10

1.1.1. Descripción de las funciones a utilizar. SIMILITUD DE

FOTOGRAMAS. 11

1.1.2. Inicio de las simulaciones. 14

1.2. Análisis por igualdad. 18

1.2.1. Descripción de las funciones a utilizar. IGUALDAD DE

FOTOGRAMAS. 18

1.2.2. Inicio de las simulaciones. 20

1.2.3. Conclusiones relativas al análisis por similitud e igualdad.

23

1.3. Nuevos análisis. Verificación de conclusiones. 25

1.4. Simulación en exteriores y ausencia de movimiento. 27

1.4.1. Revisión de las funciones a utilizar. 27

1.4.2. Inicio de las simulaciones. 32

1.4.2.1.Secuencia exterior. 32

1.4.2.2.Secuencia con movimiento aleatoreo. 36

1.4.2.3.Ausencia de movimiento. 37

1.5. CONCLUSIONES DE FASE 1. 41

2. FASE 2. Implementación en Matlab y en C del algoritmo de Vigilancia. 43

2.1. Consideraciones previas. 43

2.2. Nuevo sistema de trabajo. Programación adaptable a C para leer ficheros

BMP. 44

2.3. Programa en Matlab. 46

1

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

2.3.1. Lectura de datos del sistema. 46

2.3.2. Cuerpo principal. 51

2.3.3. Lectura de ficheros BMP 54

2.3.3.1. Lectura de imagen completa BMP 55

2.3.3.2. Lectura de franja de imagen BMP 57

2.4. Programas en C. 60

2.5. Eficiencia. Análisis de tiempos de realización. 61

2.6. Vigilancia de regiones rectangulares. 67

2.7. Inicialización del sistema. 69

2.8. Inicialización del sistema en Matlab. 77

2.8.1. “configurar.m” 77

2.8.2. Lectura fichero configurar. “lecconfigurar.m” 81

2.8.3. Lectura BMP en tres colores. “bmpinicial.m” 83

2.8.4. Resto de ficheros. 85

2.9. Inicialización del sistema en C 85

2.10. Manual del programa de Vigilancia y Configuración. 85

3. FASE 3. Programa de captación de fotogramas. 89

3.1. Introducción 89

3.2. Programación en Visual BASIC 6.0. de Microsoft. 90

3.2.1. Cuerpo principal. “frmMain” 90

3.2.2.Guardar BMP en…, “frmguardar” 93

3.2.3. Vigilar. “frmvigilar” 94

3.2.4. Vigilancia limitada. “frmvigilarlimitada” 95

3.2.5. Acerca de..., “frmayuda” 98

3.3. Manual Capturadora. 98

3.3.1. Menu Archivo. 99

3.3.2. Menu Vigilancia. 100

3.3.2.1. Vigilar. 100

3.3.2.2. Vigilancia limitada. 101

3.3.3. Menu CopiarImagen. 102

3.3.4. Menu Herramientas. 103

.3.5. Menu Acerca de. 105

2

Proyecto fin de carrera Gonzalo Leandro Bravo

4.FASE 4. Sistema en tiempo real. 106

4.1.”vigilatpr.m” 106

4.2.”lectpr.m” 108

4.3.”bmpalltpr.m” 110

4.4.”bmptrozotpr.m” 112

4.5.”lectpr.m” 114

5. Conclusiones. 116

6. ANEXOS 119

6.1. Ayuda del comando fread 119

6.2. Ayuda del comando fseek 120

6.3. Ayuda del compilador de Matlab 121

6.4. Códigos fuente en C de programa de vigilancia. 125

6.4.1. vigila.c 125

6.4.2. vigila_main.c 137

6.4.3. lectot.c 138

6.4.4. N1N2.c 157

6.4.5. bmpallrap.c 166

6.4.6. bmptrozorap.c 176

6.4.7. vigila.h 187

6.4.8. vigila_main.h 188

6.4.9. lectot.h 188

6.4.10. N1N2.h 189

6.4.11. bmpallrap.h 189

6.4.12. bmptrozorap.h 190

6.5. Códigos fuente en C de programa de inicialización. 190

6.5.1. configurar.c 190

6.5.2. configurar_main.c 208

6.6.VideoCapX.ocx 209

3

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

0. Introducción.

Los complicados momentos que nos toca vivir plantean un permanente desafío tecnológico en cuanto a la mejor manera de preservar la integridad física y patrimonial de su familia y de sí mismo.

Dado que un edificio de propiedad horizontal, normalmente es accedido por un

sinnúmero de transeúntes, resulta a menudo difícil implementar sistemas de seguridad que satisfagan los requerimientos de particulares y profesionales en cuanto a prestaciones y precio.

La necesidad de controlar la entrada de personas a algún lugar es la base de la existencia de estos equipos, los cuales mantienen la seguridad en la entrada a comercios, oficinas, industrias, áreas de almacén, áreas de diseño, laboratorios, áreas de desarrollo etc.

Cada vez más en alza, los sistemas de vigilancia por

Circuito cerrado de TV (CCTV) resultan una de las mejores alternativas en su relación costo - prestaciones, a la hora de dotar de seguridad a un edificio. Se pueden disponer tantas cámaras

como sea necesario, en entradas principal y de servicio, plantas interiores de garaje, acceso a ascensores, interior de viviendas, etc.

Es posible monitorizar lo que las cámaras captan con uno o más monitores,

ubicados frecuentemente en las oficinas de conserjería o vigilancia, e inclusive con la posibilidad de monitorear secuencialmente las mismas, esto es, una vista alternativa de cada cámara o una imagen de pantalla partida en dos o cuatro, según sea necesario. Asimismo, es posible incorporar una video grabadora "Time Elapsed" de velocidad lenta, que permite registrar varias horas de imágenes en un simple video VHS de modo que tendremos registrados en cinta todos los ingresos y distintos movimientos acaecidos en el día.

En los últimos años este tipo de sistemas de

“Video observación” han sido los que mayor demanda han tenido, esto se ha debido a la facilidad que se obtiene al tener una evidencia de un suceso determinado de manera visual.

4

Proyecto fin de carrera Gonzalo Leandro Bravo

Cuando la vigilancia o la seguridad requieren de una observación totalmente discreta, el sistema de video inalámbrico, puede ir discretamente disfrazado en un extintor de fuego; en un libro de lectura; en un maletín; en el marco de un cuadro; o camuflado en un elemento personal. Cada sistema es diseñado para generar cientos de imágenes de alta resolución de unos metros de distancia hasta varios kilómetros cuando es usado en conjunto con un repetidor de video. La cámara ultra-miniatura con lentes de diferentes ángulos y ajuste automáticos instantáneos capta del iris desde el brillo de la luz hasta la semi-oscuridad.

Un objeto puede observarse por consiguiente y puede seguirse en cualquier parte, incluso en las áreas oscuras escasamente visible al ojo humano.

Existen hoy por hoy cámaras ocultas de 1", cámaras que llegan a observar

perfectamente hasta 3 Km de distancia en las condiciones más adversas tanto de noche y día, frío o calor extremo, interiores y exteriores, color y blanco y negro, formatos NTSC y PAL, también observar a 360º desde su escritorio o domicilio a la distancia que requiera, observar en un solo monitor hasta 32 cámaras al mismo tiempo, grabar hasta por 3 meses los sucesos ocurridos, grabadoras digitales con capacidades de grabación asombrosas que eliminan el uso de videocasetes todas estas y muchas ventajas más que tienen el objetivo de ver todo lo que se quiera ver.

Otra solución al problema planteado de la

vigilancia a bajo coste es el uso de PC para implementar sistemas de videovigilancia. El aumento en la velocidad de los microprocesadores y el desarrollo de las técnicas en tratamiento de imagen están permitiendo la creación de nuevas aplicaciones diseñadas exclusivamente para optimizar y facilitar los actuales sistemas de vigilancias con videocámaras.

Todo lo que necesita es disponer de una cámara de vídeo, un ordenador y un

software de observación personal. Es en este punto donde vamos a intervenir realizando un estudio que nos resulte base para el posterior desarrollo de una aplicación de videovigilancia automatizada con control por PC.

En nuestro caso no vamos a utilizar una cámara de vigilancia ni vamos a

procurar el análisis de un número determinado de imágenes, nos limitaremos a comprobar que es lo que le ocurre a una imagen a nivel estadístico de píxel cuando comparamos secuencias correspondientes a la captación de una cámara doméstica.

5

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Realizaremos un sistema automatizado de captación de fotogramas (Visual BASIC) y un software de vigilancia (desarrollado en lenguaje Matlab y C).

Al detectar un intruso, un sistema de vigilancia

automatizado podría disparar la alarma, grabar la escena, enviar la foto del intruso por mail, avisarle en su busca o teléfono, cerrará puertas y ventanas, bloqueará el ascensor... Hará todo lo que usted le ordene para mantenerle seguro.

Aunque por el momento nos limitaremos a dar una señal de alarma el resto de

utilidades no debe entenderse como una utopía. Ya están empezando a implantarse sistemas capaces de realizar tareas similares en vigilancia de hogares y encontramos aplicaciones similares disponibles en las empresas de seguridad.

Las ventajas de nuestro sistema, además de todas los relacionados con la tecnología digital que en los últimos cinco años se han ido aplicando son:

• Los sistemas convencionales basados en cámara y grabador necesitan almacenar imágenes las 24 horas del día. Con nuestro sistema sólo se almacena cuando es realmente necesario, lo que redunda en un considerable ahorro en soportes de almacenamiento.

• Los sistemas convencionales sólo miran y es necesario añadir complejos y costosos mecanismos adicionales para adoptar medidas complementarias. Con nuestro sistema sólo se necesita para estar protegido una cámara, un ordenador personal y el software de control.

• Demostramos y aplicamos técnicas de fotogramas por segmentos que nos proporcionan la misma eficacia de vigilancia que el análisis completo de la misma, con el correspondiente ahorro de recursos y la posibilidad de definir áreas de la imagen en las que no realizar tareas de vigilancia.

• Análisis de la imagen en tiempo real (10 fps) como valor predeterminado, pero pudiendo realizar un análisis de hasta unos 50 fotogramas por segundo comparando frame a frame.

• Posibilidad de trabajo en segundo plano, al reducir los recursos empleados por el PC.

• En definitiva: Mayor funcionalidad y menor coste.

6

Proyecto fin de carrera Gonzalo Leandro Bravo

Sus múltiples aplicaciones y el reducido coste lo convierten en el sistema más versátil, gracias al uso de componentes comerciales muy difundidos y de fácil y rápida sustitución en caso de averías o modificación de especificaciones.

Uno de las principales características de este sistema es el uso de franjas

horizontales y verticales para realizar el control de imágenes. Como podemos comprobar en los siguiente ejemplos analizar pequeñas regiones rectangulares sobre un plano plantea un muro infranqueable sobre la instancia observada.

Colocando una cámara

donde marcamos con una equis podemos analizando sólo una franja vertical detectar cualquier individuo que saliera de los ascensores.

En el caso de que

deseemos impedir cualquier paso entre puertas nos bastaría colocar una nueva franja para estar completamente seguros con este sistema. Evitándonos un análisis completo de la imagen que sí podríamos ver en el monitor al ser advertidos de la intrusión.

7

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Podríamos incluso

centrarnos en una de las puertas si ahora nuestro plano es horizontal, detectando el mínimo intento de apertura de la puerta vigilada.

Estas ideas aquí expuestas son las pretensiones iniciales de este proyecto fin de

carrera que se desarrolla a continuación, algunos objetivos se han cumplido, otros se han desechado por el camino por considerarlos inviables y los más están aun por investigar por algún compañero que desee como yo conocer y aportar algo más al mundo de la seguridad.

De una manera esquemática indicamos a continuación qué se va a encontrar el

lector de este proyecto y cómo debe enfrentarse a las aplicaciones que se acompañan.

1. Tenemos que comprobar de entre una multitud de opciones cuales resultan más eficaces a la hora de comparar imágenes y en qué circunstancias se van a utilizar.

2. Comprobado cuando podemos utilizar estos sistemas vemos cómo

conseguir que sean rápidos y eficaces en cualquier situación.

3. Concluimos que no podemos sacar generalidades y que debemos someter a nuestro sistema a un proceso de inicialización.

4. Deseamos trabajar en tiempo real y para ello hemos de disponer de los

fotogramas en memoria. Nos vemos obligados a crear en Visual BASIC un programa de adquisición de imágenes BMP.

5. Enlazando ambos sistemas conseguimos un sistema de videovigilancia

en tiempo real. Con el esquema que muestro a continuación.

8

Proyecto fin de carrera Gonzalo Leandro Bravo

PROGRAMA DE VIDEOVIGILANCIA

ESTÁ INICIALIZADO?

CAPTURAR 15 SEG.

LIBRE DE MOVIMIENTO

NO

INICIALIZAR

SI

MODIFICAR DATOS DATOS DE

INICIO OK? NO

SI

OK? NO

TODO OK?

SI

NO

REVISAR EL SISTEMA

SIREALIZAR CAPTURA

INDEFINIDA

EJECUTAR SISTEMA DE VIGILANCIA

SISTEMA DE VIGILANCIA

ACTIVO. TODO OK.

VOLVER A INICIO.

SISTEMA INACTIVO

9

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

1.Fase 1. Estudio del sistema de vigilancia, detección de movimiento.

En primer lugar y comenzado de cero hemos de considerar la necesidad de

conocer qué es lo que nos encontramos cuando una imagen cambia. ¿En qué proporción lo debe de hacer para que nos resulte apreciable?, ¿Qué cambia a nivel estadístico cuando lo hace a nivel visual?, ¿Qué nivel de ruido tenemos que considerar al trabajar con video doméstico?, etc.

Éstas y otras son preguntas cuyas respuestas se pretende responder en esta

primera fase. Vamos a comprobar la viabilidad de nuestras ideas y la realizabilidad matemática de las mismas analizando varias secuencias de video que fragmentaremos a 25 fotogramas por segundo.

Siempre que se pretende buscar un grado de semejanza entre dos objetos una de

las primeras ideas que se plantean es el uso de la correlación. En la definición de correlación se indica que es el grado de similitud de dos funciones, por este motivo será utilizada como una de las posibles opciones de comparación. Por otro lado y como otra alternativa más simple comprobaremos también el cambio numérico, es decir, un Xor entre pixels de imágenes consecutivas.

Todos los programas utilizados en esta fase primera han sido creados en Matlab.

1.1. Análisis por similitud (Correlación). Comenzamos trabajando con una secuencia de imágenes de quince

segundos de duración y un tamaño de 112x160, en ella aparece un cambio en la imagen de una persona que pasa por delante de la cámara.

Sean a y b las imágenes anterior y siguiente queda definida la correlación

como: r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b))); Cuyo valor máximo será la unidad que indica que las imágenes son

idénticas.

10

Proyecto fin de carrera Gonzalo Leandro Bravo

1.1.1. Descripción de las funciones a utilizar. SIMILITUD DE FOTOGRAMAS.

Son secuencias pequeñas en tamaño y duración (15seg), de baja calidad,

pero que nos han servido para empezar a trabajar. Por cada una de las secuencias tenemos 385 fotogramas de un tamaño de

112 X 160 con lo que lo primero planteamos para poder trabajar con todas ellas a la vez y no tener que abrirlas cada vez que las necesitemos es crear una variable tridimensional (385X112X160). De esta manera ahorramos tiempo de ejecución.

Para lo cual utilizamos una función denominada ‘generar.m’: Que queda definida como: function aux=generar(nombre,inicio,tamano) %salida=generar('nombre_fichero',foto_inicio,Nºde

fotogramas); %genera matriz con la que luego trabajaremos: % for I=inicio:inicio+tamano-1 A=[nombre, num2str(I)]; aux(I-inicio+1,:,:)=rgb2gray(imread(A,'bmp')); I end

Ahora los 385 fotogramas son en blanco y negro. Como no vamos a trabajar en la mayoría de los casos con la imagen

completa, sino con una franja de la misma creamos una función que tome el trozo que luego analizaremos. Esto es la idea originaria de este proyecto. Posteriormente comprobaremos que además de viable es aconsejable.

Definido como: function out=selec(imagen,orden,N1,N2,M1,M2) if N1=='all' aux=size(imagen(2,:,:)); N2=aux(2); M2=aux(3); N1=1;M1=1; end

11

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

for I=N1:N2 for J=M1:M2 out(I-N1+1,J-M1+1)=imagen(orden,I,J); end end

A esta función la llamaremos cuando queramos analizar una parte de la

imagen comprendida entre las líneas horizontales N1 y N2 y las verticales M1 y M2, funcionan de manera semejantes a una matriz.

Para comprobar los resultados y ver que realmente tenemos los valores

que deseamos hemos creado la función mostrar.m que nos muestra una franja blanca en la región en la que estamos trabajando.

La función es: function out=mostrar(imagen,orden,N1,N2,M1,M2) aux=size(imagen(2,:,:)); n2=aux(2); m2=aux(3); n1=1;m1=1; for I=n1:n2 for J=m1:m2 out(I,J)=imagen(orden,I,J); end end for I=N1:N2 for J=M1:M2 out(I,J)=255; end end

Notar que cualquier uso del ‘for’ relentece el sistema, pero que tanto el

uso de selec.m y mostrar.m son necesarios al obligarnos Matlab a trabajar con fotogramas en lugar de imágenes ya disponibles en memoria, además el segundo de ellos sólo lo utilizaremos para mostrar resultados de la prueba.

Hay que aclarar que el análisis de imágenes está poco desarrollado a

nivel de lenguajes de programación y las funciones que disponemos para su estudio son pocas, por lo que estamos obligados a comenzar creando funciones que realicen operaciones simples de lectura y análisis parcial de imágenes.

12

Proyecto fin de carrera Gonzalo Leandro Bravo

Una vez determinado cómo podemos seleccionar una parte dentro del fotograma comenzamos ahora a analizar las secuencias de imágenes, es decir la relación de cada una de ellas con las anteriores.

En primer lugar hemos de crear una función que estudie la correlación (el

grado de similitud) entre secuencias, ésta se denomina ‘ejemplo1.m’. Ejemplo1 recibe como entrada la matriz donde se encuentran los

fotogramas y devuelve dos vectores, el vector ‘a’ resultado de la correlación y el vector ‘b’ alarma de mi sistema. Los valores de entrada quedan definidos abajo en verde, ayuda de Matlab.

function [a,b]=ejemplo1(imagen,N,orden,umbral,N1,N2,M1,M2) %----------------------- %[a b]= ejemplo1(imagen,N,orden,umbral,N1,N2,M1,M2) %imagen matriz (:,:,:) %N numero de imagenes a tratar %posicion de la imagen relativa a comparar %umbral valor de la correlacion que consideramos correcto,

ejemp 0.96 %N1, N2 intervalo horizontal a comprobar %M1, M2 intervalo vertical a comprobar I=1; for I =1:N-orden

a(I)=correlacion(selec(imagen,I,N1,N2,M1,M2),selec(imagen,I+orden,N1,N2,M1,M2));

if a(I)>umbral b(I)=0; else b(I)=1; end end subplot(2,1,1),plot(b,'.'); subplot(2,1,2),plot (a,'.'); pause; for I=2:N-orden-1 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) imshow(mostrar(imagen,I,N1,N2,M1,M2)); pause; end end

13

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Algunos notas aclaratorias sobre el sistema utilizado en esta función son: -La segunda parte se limita a mostrar por pantalla los resultados, por lo

que no será necesario incluirlos en el proyecto final, se han añadido en este punto para facilitar el sistema de trabajo y hacer más comprensible esta memoria.

-No funciona bien cuando es seguro que no cambia mucho la imagen,

como por ejemplo cuando estamos tratando zonas muy oscuras. Esto está motivado por el hecho de que la correlación da un valor proporcional a la media y en imágenes muy uniformes el más mínimo cambio es considerado como importante.

-Para solucionar esto a partir de este punto utilizaremos una correlación

que no realice operaciones sobre la media, de esta manera el sistema funciona mejor, pero ahora la imagen debe cambiar más para detectar un movimiento.

-Parece bastante agradecido a cambios considerables en la distancia entre

imágenes de correlación. -Aunque pudiera resultar ilógico presentar en este proyecto aquello que

no funciona, hemos de decir en nuestra defensa que en el ámbito didáctico es tan útil conocer lo que podemos hacer como lo que no podemos hacer. Por lo que espero sirvan mis errores e intentos inútiles para que no se vuelvan a cometer.

1.1.2. Inicio de las simulaciones.

La única manera de comprobar si las ideas de partida son útiles para comparar imágenes es analizar cada uno de ellos en distintas situaciones. Sobre una de las secuencias antes mencionadas de video en la que se estudia un pasillo en el cual se cruza una persona de derecha a izquierda, iniciando las simulaciones tendremos los siguientes resultados:

Ejecutándose para toda la imagen la función antes descrita tendremos:

14

Proyecto fin de carrera Gonzalo Leandro Bravo

NOTA: El pico primero es porque se mueve la cámara al comenzar la

grabación. Esta imagen muestra la correlación de los 385 fotogramas, hay que decir

que la simulación de estos 15 segundos se realizó en unos 60 segundos por lo que su posible utilización tal y como está planteado es inviable.

Por otro lado y con respecto al estudio estadístico en el que nos

centramos en esta primera fase queda suficientemente marcado la existencia de movimiento y en su ausencia mantiene un valor próximo a 1 y muy constante a pesar de que hay demasiado ruido al ser la calidad de la imagen baja. En estos momentos planteamos un umbral de alarma de 0.96.

Si ahora tomamos sólo una franja vertical a la entrada del lateral

izquierdo del pasillo correspondiente a las columnas 45 a 49 tendremos:

15

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

En la imagen inferior el vector ‘a’ con las correlaciones y en la superior

la primera secuencia que sobrepasa el umbral, en este caso de 0.96. “En un principio” parece que la idea de analizar sólo franjas funciona

bien. A continuación haremos lo mismo para otra secuencia de video que nos

muestra un salón y sobre la que se producen dos situaciones de movimiento a diferentes distancias, utilizaremos en este caso una franja en el centro de la imagen, aquí veremos por primera vez que es lo que ocurre cuando los movimientos tienen distintos tamaños.

Notar que en el primer caso tenemos valores de hasta 0.55 que es un

cambio importante. Las primeras intrusiones en ambos casos son:

16

Proyecto fin de carrera Gonzalo Leandro Bravo

En este 1.1.Análisis por Similitud no hay cálculo de medias y varianzas

pues lo único que nos interesaba era comprobar que en mayor o menor grado estamos buscando algo que funcionaba.

Hemos utilizado para hacer la comparación la función corr2.m definido

en el Processing Toolbox de Matlab modificado de manera que no tuviera en cuenta la media. Pues esto, como comprobamos en las simulaciones nos daba problemas en zonas de varianza pequeña.

La función ‘correlacion.m’ está definida como. function r = correlacion(a,b) %modificacion de corr2.m en la que no restamos la media,

de esta manera evitamos %problemas con las zonas de un solo tono. %correlacion Compute 2-D correlation coefficient. % R = correlacion(A,B) computes the correlation

coefficient between A % and B, where A and B are matrices or vectors of the

same size. % % Class Support % ------------- % A and B can be of class double or of any integer

class. R % is a scalar of class double. error(nargchk(2,2,nargin)); if any(size(a)~=size(b)), error('A and B must be the same

size.'); end if (~isa(a,'double')) a = double(a); end if (~isa(b,'double')) b = double(b); end %a = a - mean2(a); %b = b - mean2(b); r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b)));

17

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

1.2.Análisis por Igualdad. 1.2.1. Descripción de las funciones a utilizar.

IGUALDAD DE FOTOGRAMAS.

Ahora en 1.2. “Análisis por Igualdad” vamos a comprobar los valores exactos que existen entre fotogramas haciendo un ‘XOR’ entre pixels. Esto será un segundo método para comparar imágenes, posteriormente veremos que cada uno de los sistemas planteados tienen sus pros y sus contras pero que según las circunstancias de las cámaras ambos son útiles.

Para hacer este cálculo utilizamos un ‘for’ anidado que nos enlentece

tremendamente la simulación. En esta primera fase esto no fue tenido en cuenta pues es en la fase 2 de este proyecto en el que realizaremos análisis temporal buscando la máxima eficiencia. A partir de esta segunda fase trabajaremos con matrices que como comprobaremos acelera las simulaciones.

La función creada es ejemplo2.m ; function [a,b]=ejemplo2(imagen,N,orden,umbral,N1,N2,M1,M2) %----------------------- %[a,b]= ejemplo2(imagen,N,orden,umbral,N1,N2,M1,M2). %imagen matriz (:,:,:). %N numero de imagenes a tratar. %pasicion de la imagen relativa a comparar. %umbral valor de la diferencia normalizada entre imagenes,

ejemp 0.8. %N1, N2 intervalo horizontal a comprobar. %M1, M2 intervalo vertical a comprobar. %Si N1='all' de considera la imagen completa, pero resulta

muy lento. if N1=='all' aux=size(imagen(2,:,:)); N2=aux(2); M2=aux(3); N1=1;M1=1;

18

Proyecto fin de carrera Gonzalo Leandro Bravo

end for I =1:N-orden b(I)=0;a(I)=0; for J=N1:N2 for K=M1:M2 if

(double(imagen(I,J,K))>=double(imagen(I+orden,J,K))-10)&(double(imagen(I,J,K))<=double(imagen(I+orden,J,K))+10)

a(I)=a(I)+1; end end end a(I)=a(I)/((M2-M1+1)*(N2-N1+1)); %I if a(I)<umbral b(I)=1; end end subplot(2,1,1),plot(b,'.'); subplot(2,1,2),plot(a,'.'); pause; for I=2:N-orden-1 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) imshow(mostrar(imagen,I,N1,N2,M1,M2)); pause; end end

Del cual tras su utilización obtenemos las siguientes conclusiones: -Tarda demasiado tiempo en comprobar la imagen completa y los

resultados son incoherentes para orden 1, es decir imágenes consecutivas, por que los fotogramas son iguales cada tres. Esto es debido a que la calidad de video, el número de fotogramas es dependiente de medio utilizado para la captación y en este caso es menor que los 25 fotogramas por segundo que se analizan y que suelen ser los existentes en filmaciones de video. Esta circunstancia nos llevó a comprobar que cualquier análisis en tiempo real a más de 30 fotogramas por segundo resulta limitado por el sistema de captación utilizado.

-Las imágenes no son exactamente iguales nunca, inconveniente que no

se presenta cuando utilizamos la correlación, de hay la diferenciación entre

19

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

ambas. Con este método estamos midiendo cuan de iguales son las imágenes y con el anterior medimos cuan de similares son.

-Aunque esto puede deberse a un posible defecto de la cámara ya que

con la correlación no daba problema, comprobaremos posteriormente que no es exactamente cierto.

Para solucionar este problema y hacer útil este sistema de detección de

movimiento hemos de añadir un margen en los valores de gris considerado como ‘igual’, es decir si un punto de una imagen tiene valor 94 y el margen es de 5, entonces consideraremos igual al mismo punto del siguiente fotograma si se encuentra entre 89 y 99.

Ahora conseguimos que funcione pero añadimos una fuerte dependencia

entre el margen que hemos definido y el valor umbral que consideramos como de alarma. La calidad de la grabación determina el margen a la hora de considerarlos iguales.

Nosotros para las simulaciones hemos utilizado esta función con un

margen de +-10, aunque posteriormente comprobamos que el umbral debía de ser inferior para conseguir los resultados deseados. En un principio esto parece un retroceso en las prestaciones pero también comprobamos que se redujo el valor mínimo alcanzado, por lo que en cualquier caso aseguramos la eficacia del método.

1.2.2. Inicio de las simulaciones. Vamos a realizar las mismas pruebas que anteriormente analizando una

franja y no la imagen completa, optamos por esto pues por lo visto hasta este momento parece que mejora las prestaciones y conseguimos mejores resultados.

Posteriormente comprobaremos que no en todas las situaciones nos

interesa este análisis zonal.

20

Proyecto fin de carrera Gonzalo Leandro Bravo

Ahora la ausencia de movimiento no se mide tan próxima al cero, pero la

intrusión da un valor de cambio próximo al 80%. En este paso la mala calidad del video no nos permitiría obtener

conclusiones positivas, por lo que en los resultados nos limitamos a comprobar la eficacia o ineficacia de los modelos con los que trabajamos.

Si hacemos lo mismo con el video del salón tendremos que la correlación

es:

21

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Y las dos secuencias primeras que sobrepasan el umbral son:

Llegamos a las mismas conclusiones anteriores. Más ruido en ausencia

de movimiento pero mayores valores extremos en caso de que intruso. Si analizamos la imagen completa vemos que el resultado es similar.

Resalta los movimientos, pero estos son muy relativos. En este caso es un sistema que resultaría muy sensible al ruido.

22

Proyecto fin de carrera Gonzalo Leandro Bravo

Tal vez el análisis de la imagen completa no sea la solución, los

resultados vemos que son mejores para franjas del fotograma.

1.2.3. Conclusiones relativas al análisis por similitud e igualdad.

En 1.2.”Análisis por igualdad”, analizamos grabaciones de 15 segundos

en las que los fotogramas (25/seg) se encuentran repetidos cada tres por lo que el cambio real de imagen se produce cada ese intervalo.

Realizamos una comparación directa de valores, es decir, un XOR entre

pixels situados en la misma posición en imágenes consecutivas. En esta situación llegamos a las siguientes conclusiones:

-Las imágenes no son nunca exactamente iguales. Por lo que de hacer la

comparación entre una de ellas y la siguiente el resultado se muestra como cambio continuo en la secuencia.

-Ese cambio se puede corregir añadiendo un margen, en el ejemplo -10

,+10 en el que no se considera cambio. -Aparece el inconveniente de que el umbral ahora es relativo a este

margen y no lo podemos considerar fijo. Aunque en el ejemplo se detecta sin problema el cambio.

En el análisis por similitud el funcionamiento es mas eficiente y

realizamos una correlación normalizada sin referenciarla a la media. r = sum(sum(a.*b))/sqrt(sum(sum(a.*a))*sum(sum(b.*b))); Siendo a y b las imágenes a correlar. Conclusiones:

23

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

-Ahora las imágenes que son cercanas y sin cambio, además tienen un valor de correlación muy próximo a la unidad (>0.98 e incluso 0.99).

-Los cambios quedan sumamente marcados tanto en la cercanía como

más lejos. Aunque en general el principal problema que impide en esta primera fase

sacar conclusiones es: -Falta de luminosidad y contraste (o uniformidad) en la imagen. -Imposibilidad de analizar pequeños cambios para compararlos con los

momentos de no cambio. Encontramos problemas cuando miramos en los lugares donde hay

reflejos, especialmente cuando se toma un cuadro pequeño. Tendremos dificultades para diferenciar en estos casos ruido de movimiento pero esto lo solucionamos posteriormente realizando un programa de inicialización que determina para cada circunstancia de video un umbral determinado.

Como parte positiva diremos que lo probado hasta estos momentos

funciona con una pequeña carga computacional y que además lo hace bastante bien. Comprobamos incluso que funciona incluso con un cuadro 5x5, que es una cantidad muy pequeña a analizar.

Posteriormente se estudiarán medias y varianzas para sacar conclusiones

sobre los valores que sirven de criterio en cada situación y se opta por no descartar ninguna de estas dos posibilidades sino por combinar ambas funciones para decidir cual de ellas funciona mejor en cada momento.

Importante: Todos estos comentarios se han incorporados al

proyecto como justificante de las decisiones que posteriormente se tomarán a la hora de realizar el sistema de inicialización.

24

Proyecto fin de carrera Gonzalo Leandro Bravo

1.3. Nuevos análisis. Verificación de conclusiones.

A continuación trabajamos con nuevas secuencias de imágenes que se encuentran en 4 videos de 15 segundos de duración y de mejor calidad y mayor tamaño que los dos anteriores, ahora es una secuencia grabada con una cámara de video e introducida en el ordenador a través de una capturadora de video proporcionada por el fabricante Avermedia junto con la tarjeta de televisión TVCapture 98 y convertidos en fotogramas posteriormente con el programa VirtualDub de libre distribución en Internet.

Ya se deja entrever en la presentación que en este proyecto se intenta

realizar un programa independiente de las características externas del sistema de vigilancia que se encuentre implantado. Por ello se decide actuar a nivel de imagen de TV, y también por el mismo motivo utilizamos una capturadora de video.

El coste de esta capturadora es de unas 12.000 pesetas y posee una sola

entrada de imagen, pero para realizar la comprobación de viabilidad y funcionamiento es suficiente. Es posible que en el hipotético caso de un desarrollo posterior sea necesario trabajar con un nuevo dispositivo de captación con un mayor número de entradas, aunque siempre buscaremos sistemas que se acojan a los estándares de PAL o NTSC.

En los tres primeros videos tenemos en su totalidad ausencia de

movimiento, por lo que nos ha servido para empezar a tomar contacto con lo que serán los valores umbrales.

Llegados a este punto nos aparece el primer problema relacionado con

las limitaciones de memoria del programa Matlab. Al ser los fotogramas mayores ( 288 X 384), estamos obligados a

fraccionar los videos en diferentes variables de tamaño 175 X 288 X 384, con lo que su estudio se hace más lento y pesado al tener que realizar múltiples simulaciones por partes, haciendo de esta manera más complicado sacar conclusiones.

Ante este problema modificamos los programas para que mantengan en

memoria el menor número posible de fotogramas. Este cambio de política en lo referente al sistema de lectura de archivos BMP lo tendremos que tomar o bien

25

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

en estos momentos o bien más adelante, pero es absolutamente necesario en el momento en el que nos planteamos un sistema en tiempo real donde no se pueden almacenar imágenes que aun no han ocurrido.

Analizaremos ahora los valores medios y las varianzas de las zonas de

silencio y no silencio con los siguientes resultados con la imagen completa. -Tenemos una media en ausencia de movimiento de 0.9939, que es muy

alta. -Aun así hay dos alarmas injustificadas muy cercanas al umbral tomado

de 0.98, esto se hubiera solucionado con el umbral en 0.97. Ahora veremos que es lo que ocurre si tomamos solo un plano.

Procurando realizar alguna variación en este caso hemos optado por analizar una línea horizontal no al completo.

Utilizaremos en primer lugar ejemplo1. “Similitud”

Notar que ahora la línea horizontal no es de extremo a extremo, esto

queda impuesto por determinaciones de la imagen. Se trata de un pasillo y sólo nos interesa estudiar la transición desde el fondo.

26

Proyecto fin de carrera Gonzalo Leandro Bravo

Vemos por un lado que es mucho más rápida que en el caso de analizar la imagen completa, esto era de esperar, las imágenes están en memoria y hemos de analizar un menor número de pixels.

El valor medio ahora en ausencia de movimiento es: 0.999 (que es un

buen valor), ahora el sistema de captación de la imagen a mejorado. Mientras que en los dos pasos anteriores la secuencia de video es de baja calidad en este caso tenemos una imagen nítida. La falta de claridad es debida al proceso de conversión a blanco y negro, su traslado a fichero de texto y su posterior impresión.

La calidad de la imagen nos parece indicar que podemos usar ejemplo2

para comprobar la existencia de movimiento. Con ejemplo2 tenemos las siguiente conclusiones.”Igualdad” -Es imposible por consideraciones temporales utilizar ejemplo2 con la

imagen completa, el análisis dura demasiado tiempo (más de 90 segundos). -Para analizar esta misma imagen y la misma franja bajo la puerta

tenemos que los cambios son considerables y la función no la podemos utilizar. Sólo con umbral 0.85 y un rango en valores de pixcel de -15, +15 empiezan los resultados a ser coherentes, aunque aun aparecen algunas falsas alarmas. En un principio comparar ‘como iguales’ son dos imágenes no parece una buena idea.

Según parece resulta más eficaz ver como de ‘parecido es (ejemplo1)’,

que como de ‘igual es (ejemplo2)’. La incoherencia que aparece en los resultados en cuanto a la

conveniencia o no de utilizar un sistema u otro quedará resuelto posteriormente determinando situaciones bien diferenciadas para el uso de ambos métodos.

1.4. Simulación en exteriores y ausencia de movimiento. 1.4.1. Revisión de las funciones a utilizar.

27

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

A continuación trabajamos con secuencias de duración variable (~1

minuto) y de igual calidad que los dos anteriores, las secuencias son grabadas con una cámara de video e introducidas en el ordenador a través de una capturadora de video.

Las nuevas funciones se denominan largo1.m y largo2.m y son

equivalentes en función a ejemplo1.m y ejemplo2.m. Largo1.m function [a,b]=largo1(imagen,N,umbral,N1,N2,M1,M2) %----------------------- %[a b]= largo1(imagen,N,umbral,N1,N2,M1,M2) %imagen 'nombre_de imagen' %N numero de imagenes a tratar %umbral valor de la correlacion que consideramos correcto,

ejemp 0.96 %N1, N2 intervalo horizontal a comprobar %M1, M2 intervalo vertical a comprobar %Para analizar toda la imagen N1='all' I=1; if N1=='all' A=[imagen, num2str(I)]; actual=rgb2gray(imread(A,'bmp')); for I =1:N B=[imagen, num2str(I+1)]; siguiente=rgb2gray(imread(B,'bmp')); a(I)=correlacion(actual,siguiente); actual=siguiente; I if a(I)>umbral b(I)=0; else b(I)=1; end end else A=[imagen, num2str(I)]; actual=selec2(A,N1,N2,M1,M2); for I =1:N B=[imagen, num2str(I+1)]; siguiente=selec2(B,N1,N2,M1,M2);

28

Proyecto fin de carrera Gonzalo Leandro Bravo

a(I)=correlacion(actual,siguiente); actual=siguiente; I if a(I)>umbral b(I)=0; else b(I)=1; end end end subplot(2,1,1),plot(b,'.'); subplot(2,1,2),plot (a,'.'); pause; subplot(1,1,1) if N1=='all' for I=2:N-1 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) A=[imagen, num2str(I)]; imshow(rgb2gray(imread(A,'bmp'))); pause; end end else for I=2:N-1 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) A=[imagen, num2str(I)]; imshow(mostrar2(A,N1,N2,M1,M2)); pause; end end end

Además hemos añadido la posibilidad de analizar la imagen completa en

la misma función introduciendo como única variable ‘all’. En el caso de largo2.m function [a,b]=largo2(imagen,N,umbral,N1,N2,M1,M2) %----------------------- %[a,b]= largo2(imagen,N,umbral,N1,N2,M1,M2). %imagen 'nombre_imagenes'. %N numero de imagenes a tratar. %umbral valor de la diferencia normalizada entre imagenes,

ejemp 0.8. %N1, N2 intervalo horizontal a comprobar.

29

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

%M1, M2 intervalo vertical a comprobar. %Si N1='all' de considera la imagen completa, pero resulta

muy lento. if N1=='all' aux=size(rgb2gray(imread([imagen '4'],'bmp'))); N2=aux(1); M2=aux(2); N1=1;M1=1; end A=[imagen, num2str(1)]; actual=selec2(A,N1,N2,M1,M2); for I =1:N-1 b(I)=0;a(I)=0; B=[imagen, num2str(I+1)]; siguiente=selec2(B,N1,N2,M1,M2); for J=1:N2-N1+1 for K=1:M2-M1+1 if (double(actual(J,K))>=double(siguiente(J,K))-

10)&(double(actual(J,K))<=double(siguiente(J,K))+10) a(I)=a(I)+1; end end end actual=siguiente; a(I)=a(I)/((M2-M1+1)*(N2-N1+1)); I if a(I)<umbral b(I)=1; end end subplot(2,1,1),plot(b,'.'); subplot(2,1,2),plot(a,'.'); pause; subplot(1,1,1); if N1=='all' for I=2:N-2 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) A=[imagen, num2str(I)]; imshow(rgb2gray(imread(A,'bmp'))); pause; end end else for I=2:N-1 if b(I)==1 & (b(I-1)==0 | b(I+1)==0) A=[imagen, num2str(I)]; imshow(mostrar2(A,N1,N2,M1,M2)); pause; end

30

Proyecto fin de carrera Gonzalo Leandro Bravo

end end

Las modificaciones realizadas nos obligan a cambiar también las

funciones que nos permiten ver por pantalla los resultados, como son mostrar2.m y selec2.m.

Estas son: Mostrar2.m function out=mostrar2(imagen,N1,N2,M1,M2) %out=mostrar2(imagen,N1,N2,M1,M2) %imagen 'nombre_imagen' sin extension aux=rgb2gray(imread(imagen,'bmp')); var=size(aux); n2=var(1); m2=var(2); n1=1;m1=1; for I=n1:n2 for J=m1:m2 out(I,J)=aux(I,J); end end for I=N1:N2 for J=M1:M2 out(I,J)=255; end end

y selec2.m function out=selec2(imagen,N1,N2,M1,M2) aux=rgb2gray(imread(imagen,'bmp')); if N1=='all' var=size(aux); N2=var(1); M2=var(2); N1=1;M1=1; end for I=N1:N2 for J=M1:M2 out(I-N1+1,J-M1+1)=aux(I,J);

31

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

end end

1.4.2. Inicio de las simulaciones.

Una vez realizadas las modificaciones necesarias fragmentamos en fotogramas un video y comenzamos a aplicar estas funciones sobre él con los siguientes resultados. De los múltiples análisis que se realizan se sacarán posteriormente las conclusiones para determinar el sistema definitivo a utilizar.

1.4.2.1.Secuencia exterior.

Comenzamos con la secuencia denominada calle1, en el que tenemos 965 fotogramas de un tamaño de 288 X 384 con lo que lo primero que se nos ocurrió para poder trabajar con todas ellas a la vez y no tener que abrirlas cada vez que las necesitaba es crear una variable tridimensional (965 X 288 X 384), que es demasiado grande.

Por este motivo nos vemos obligados a cambiar todas las funciones con las que he estado trabajando en 1.1. Análisis por Similitud, 2 y 3 de manera que ahora tenga en memoria sólo en fotograma actual y el anterior que son los dos que deseo comparar. Comenzamos analizando una línea de la imagen de calle1 por similitud también en una pequeña región de la imagen.

32

Proyecto fin de carrera Gonzalo Leandro Bravo

Con los siguientes resultados.

Este video muestra una calle sobre la que pasa un vehículo en torno al

fotograma 775. La imagen superior representa la activación de la alarma. La alarma se produce, el cambio es significativo pero vemos,

comprobando el video que el vehículo pasa realmente en torno al fotograma 740, lo detectamos un poco tarde. Esto puede deberse a que el vehículo es oscuro y al pasar a escala de grises pasa un poco inadvertido, pero eso no debería ser así. Debemos tener en cuenta que en imágenes oscuras o de colores uniformes hay que tener cuidado con los cambios relativos.

Si tenemos en cuenta que la media en ausencia de movimiento es 0.993 y

el valor mínimo que alcanza 0.9249, vemos por otro lado que podíamos solucionar el problema de la detección tardía aumentando el umbral que estaba colocado en 0.95. Parece que podríamos poner el umbral de alarma cercano al 0.98, con lo aceleraríamos la activación.

Es importante notar que en ausencia de movimiento el valor medio es

muy elevado, lo que demuestra que la imagen es bastante buena y el grado de

33

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

similitud se acerca en cualquier caso al 100% (0.95), aunque posteriormente conseguiremos valores incluso superiores(0.995).

Cuando analizamos la imagen completa tenemos un problema. No

detecta el coche que pasa. Esto nos obliga a pensar que este método sólo es válido con sistemas en

los cuales el cambio sea significativamente grande en relación con la zona a vigilar.

Intentando solucionar este problema, ahora vamos a comprobar si

podemos utilizar largo2, que realiza la comparación XOR e intentar buscar un umbral que nos dé resultados coherentes ya que parece que con el análisis anterior por similitud no conseguimos mucho en la imagen de calle1 al pasar el coche.

Comenzaremos en este caso con el plano que contiene la calle por la que

pasa el coche como en el caso anterior es un cuadro de 200 pixels. Con una tolerancia de +-10;

34

Proyecto fin de carrera Gonzalo Leandro Bravo

Afortunadamente funciona bastante bien. Detecta el vehículo en el

momento preciso de llegar a la línea (fotograma 743), la media en ausencia de movimiento es la unidad (magnifico) y el valor mínimo es 0.5317.

-Con una tolerancia de +-5;

Afortunadamente funciona muy, muy bien. Detecta el vehículo en el

momento preciso de llegar a la línea (fotograma 739), la media en ausencia de movimiento es 0.9945 (magnifico) y el valor mínimo es 0.3268. Que nos da una diferencia sustancial de trabajo. Además no resulta demasiado lento al tener el cuadro a analizar un tamaño de 200 pixels.

Vamos ahora a comprobar que ocurre en caso de analizar la imagen

completa. (+-5).

35

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Vemos que es difícil de apreciar la entrada del coche, y aunque sí

aparece, el valor diferencial que nos da es pequeño. La media en ausencia de movimiento es 0.9561 y el mínimo 0.8818 y

cuando aparece el coche tenemos un valor mínimo de 0.8742, que es una diferencia pequeña.

Parece una conclusión acertada que ninguno de esto métodos es útil en

caso de análisis de la imagen completa. Según vemos en la gráfica puede que tengamos que analizar un tramo en ausencia de movimiento y su varianza para colocar los valores umbrales, junto con el numero de pixels que voy a analizar, y de esa manera decidir si voy a utilizar similitud o igualdad, el umbral y el rango permitido. Esta apreciación será tenida en cuenta posteriormente.

1.4.2.2.Secuencia con movimiento aletoreo.

Vamos ahora a ver que es lo que ocurre con calle2, aquí tenemos un movimiento continuo, comprobaremos si este movimiento es similar al ruido o si tenemos alguna diferencia sustancial. Continuamos trabajando con largo1, análisis por simititud o correlación.

36

Proyecto fin de carrera Gonzalo Leandro Bravo

En primer lugar analizamos dos zonas sin movimiento, la esquina superior e inferior izquierda, dos cuadrados de 50X50. Obtenemos un valor medio de 0.9939.

Ahora tenemos un caso con movimiento y para que detecte algo tenemos

que poner el umbral en 0.9935 que puede ser demasiado alto teniendo en cuenta que en ausencia de movimiento se ha obtenido un valor cercano a 0.9834.

Ahora el mínimo es 0.9848, que es muy próximo a lo anterior y el valor

medio incluso mayor 0.9848. Dejaremos este apartado porque parece una excepción de lo que

queremos hacer ya que es una imagen exterior con continuos movimientos lejanos, ajeno este situación a la pretendida con este proyecto.

1.4.2.3.Ausencia de movimiento. Comenzamos con una carpeta en la cual tengo 1834 fotogramas de un

tamaño de 288 X 384. Analizamos teniendo en cuenta los siguientes problemas:

-Si vemos la siguiente imagen de un fotograma de la secuencia del video

y nos fijamos en el marco de la puerta nos damos cuenta que este no deja de moverse, con lo que no nos debe de extrañar que tengamos valores con resultados engañosos.

Con largo1, similitud, tendremos

37

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Resultando

-La media en ausencia de movimiento es 0.9992 -El valor mínimo es 0.8543. Con largo2 (+-5), igualdad, resultados;

38

Proyecto fin de carrera Gonzalo Leandro Bravo

Nos vemos obligados a utilizar un umbral menor del 20%, nosotros

pondremos 0.7 La media en ausencia de movimiento es 0.9463 y el valor mínimo es

0.5485 que por un lado tiene una media lejana de uno, pero por otro lado la imagen de valor mínimo es imposible que pase inadvertida (fotograma 887).

Vamos a ver que es lo que ocurre con -+10, para ver si reducimos el

valor medio y conseguimos mantener el mínimo.

39

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Aumentaremos el umbral a 0.8. La media en ausencia de movimiento es 0.9892 y el valor mínimo es

0.6636. Hemos mejorado algo los resultados, parece que en casos de tramos de

imagen no hay problema para resolver, tendremos que comprobar cual de ellos nos detecta antes, aunque parece que en ambos casos es imposible evitar la alarma.

Vamos a aumentar el tamaño de la imagen, considero la puerta de

entrada al completo

Utilizando largo1.

40

Proyecto fin de carrera Gonzalo Leandro Bravo

En este caso la media en ausencia de movimiento es 0.9994 y el valor

mínimo 0.9668. Como siempre la correlación es buena en ausencia de movimiento, pero

el pico de movimiento es menor.

1.5. CONCLUSIONES DE FASE 1.

Los análisis antes realizados no han sido los únicos que se han efectuados. Antes de realizar simulaciones con resultados representativos y coherentes se ha tenido que trabajar multitud de veces sobres los posibles valores de cada parámetro.

Todo esto para concluir con que: -Siempre es más eficaz y rápido el análisis de un tramo que de la imagen

completa. -Si la imagen es buena, la opción con igualdad con +-10 parece que es la

de mejor resultado. Da una mayor diferencia entre movimiento y ausencia de movimiento.

-Según empeora la imagen o el tamaño de la misma es mayor comienza a

perder eficacia XOR y a resultar útil la correlación.

41

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

-Un criterio de ‘calidad’ de las imágenes es la varianza de los pixels. -Aparentemente la correlación es más rápida, aunque aún queda por

comprobar como funciona sustituyendo el bucle for por cálculo con matrices.

Del análisis de estos datos y de otras pruebas debería de salir el criterio

para decidir los valores umbrales según la situación.

42

Proyecto fin de carrera Gonzalo Leandro Bravo

2. FASE 2. Implementación en Matlab y en C del algoritmo de Vigilancia.

2.1. Consideraciones previas. Llegado este punto nos surge la necesidad de realizar un ejecutable de

nuestra aplicación de vigilancia. Para ello vamos a utilizar el compilador Visual C/C++ 6.0 de Microsoft.

Nos encontramos ahora con el primer problema. Cuando nos planteamos

realizar la implementación en C no encontramos funciones para manejar ficheros BMP completos y no podemos utilizar el análisis matricial que Matlab nos facilita.

Para solucionar estos problemas decidimos utilizar el compilador que

Matlab 5.3 nos proporciona en su versión 2.0, de esta manera tendremos una aplicación independiente del software y podré utilizar el cálculo matricial ya que el compilador de Matlab incluye librerías que permiten su uso.

El manual HTML de la versión Matlab 5.3 incluye un completo manual

sobre el uso del compilador de C/C++. Por otro lado hay que aclarar que Matlab sólo nos proporciona una

herramienta para convertir ficheros tipo “archivo.m“ a “archivo.c”, posteriormente es el compilador Visual C/C++ 6.0 de Microsoft el que realiza el “linkado” y la creación del programa ejecutable.

A pesar de esta facilidad de compilación que Matlab ofrece nos

encontramos que la diferencia real existente entre C y Matlab se traduce en una serie de limitaciones al compilar:

Table 3-3: Unsupported Functions in Stand-Alone Mode add_block, add_line, cd, cholinc, clc, close_system, dbclear, dbdown, dbquit, dbstack, dbstatus, dbstep, dbstop, dbtype, dbup, delete_block, delete_line, dir, echo, exist, get_param, inferiorto,

43

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

inmem, int8, int16, int32, luinc, mfile2struct, new_system, open_system, pause, set_param, sim, simget, simset, single, sldebug, superiorto, system_dependent, type, uint8, uint16, uint32.

(Pag 77 manual Compiler2.0. de Matlab5.3) En negrita vemos la opción uint8, que me impide utilizar comandos

como imread o imshow por lo que todo el trabajo realizado en la fase 1 de este proyecto nos sirve sólo para analizar el sistema de vigilancia pero no para realizar un programa ejecutable.

2.2. Nuevo sistema de trabajo. Programación adaptable a C para leer ficheros BMP.

A pesar de continuar trabajando con Matlab ahora la programación que

utilizamos debe cumplir una serie de requisitos para que se nos permita su posterior compilación, para ello hemos optado por hacer la lectura del fichero BMP byte a byte, procurando en cada caso y según el análisis que fuéramos a realizar leer exclusivamente los bytes que nos son necesarios.

Para hacer esto hay que tener en cuenta que una vez leídos los bytes

iniciales de una imagen BMP y posicionados al principio de la imagen nos encontramos con una variación con respecto a los que vemos por pantalla.

Si en la pantalla nos encontramos: R11G11B11 R12G12B12 R13G13B13 R14G14B14 R15G15B15 R21G21B21 R22G22B22 R23G23B23 R24G24B24 R25G25B25 R31G31B31 R32G32B32 R33G33B33 R34G34B34 R35G35B35 R41G41B41 R42G42B42 R43G43B43 R44G44B44 R45G45B45 En el fichero se almacena empezando por el final, tal que:

44

Proyecto fin de carrera Gonzalo Leandro Bravo

R41G41B41 R42G42B42 R43G43B43 R44G44B44 R45G45B45 R31G31B31 R32G32B32 R33G33B33 R34G34B34 R35G35B35 R21G21B21 R22G22B22 R23G23B23 R24G24B24 R25G25B25 R11G11B11 R12G12B12 R13G13B13 R14G14B14 R15G15B15 Vamos a utilizar un sistema de lectura secuencial con “fread”,

instrucción que acepta tanto Matlab como C, los datos tras la lectura estarán disponibles de la siguiente forma:

Imagen= R41G41B41R42G42B42R43G43B43R44G44B44R45G45B45

R31G31B31R32G32B32R33G33B33R34G34B34R35G35B35R21G21B21R22G22B22R23G23B23R24G24B24R25G25B25R11G11B11R12G12B12R13G13B13R14G14B14R15G15B15

Por otro lado y buscando que el sistema se lo más rápido posible sólo

realizaremos la lectura de uno de los tres colores que representan a la imagen BMP.

Añado este sistema tan gráfico pues la lectura de datos es uno de los

principales problemas a la hora de conseguir que nuestro sistema resulta rápido y por lo tanto eficaz.

Si se desea hacer un análisis profundo sobre las especificaciones del

formato BMP se recomienda revisar los códigos de los programas de lecturas de tales imágenes donde se realiza paso a paso de una manera muy indicativa como debe de ser la cabecera que acompaña a estas imágenes.

45

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

2.3. Programa en Matlab.

2.3.1. Lectura de datos del sistema.

El funcionamiento del programa se ha modificado de manera que ahora no tenemos dos opciones, se ha englobado todo el sistema de vigilancia en uno solo y hemos añadido un fichero de valores de análisis que nos servirá para comunicarnos con el programa ejecutable e indicarle en cada caso cuales son los parámetros más eficaces para cada situación.

Este fichero denominado camara.txt puede ser creado por un programa

que se mostrará posteriormente y que estudiando 15 segundo de imagen sin movimiento decide los parámetros a utilizar en el sistema, o bien a mano. Esta segunda opción es muy arriesgada y nos puede llevar a un sistema de vigilancia inservible, se aconsejaría su utilización solamente una vez se conozca muy bien como funciona nuestro sistema.

Con la creación de este fichero se nos permite realizar un ejecutable

versátil y modificable en cada ejecución. Sin vernos predeterminaciones y por lo tanto limitaciones en cuanto a la imagen que vamos a analizar en cada caso.

En este fichero aparecen parámetros como el color a utilizar para el

análisis, el valor umbral de detección, la tolerancia en el valor de los bits, etc. Aunque estos parámetros tienen unos valores predeterminados y aconsejados se realiza un estudio de la imagen que capta nuestra cámara para optimizar el sistema de vigilancia.

En el fichero camara.txt tendremos los siguientes parámetros separados

por un fin de línea. imagen: Cadena de caracteres con el nombre del fichero sin extensión debe ir entre comillas. N: Numero de fotogramas que voy a analizar, posteriormente se anulara su valor. tipovig: Parámetro utilizado para decidir si se utiliza una función u otro para el análisis del sistema. Esto se decide durante la inicialización. Puede tomar dos valores:

46

Proyecto fin de carrera Gonzalo Leandro Bravo

'igual' concede un valor de igualdad y 'simil' utiliza correlación. sentido: Indica el sentido de la línea de vigilancia. Puede tomar tres valores: 'all' analiza la imagen completa 'ver' análisis vertical y 'hor' análisis horizontal umbral: valor en tanto por cien sobrepasado el cual se considera alarma. 0->Detecta cualquier cambio por mínimo que sea 100->La imagen permanece inmóvil valor aconsejado entre 80 y 95 valor: Se considera igual a los bits que se encuentren entre bit+-valor. Valor aconsejado entre 10 y 20. Solo tiene sentido si tipovig=='igual' N1 y N2: Franjas que se van a analizar. Solo tiene sentido si sentido!='all' color: Se analiza solo uno de los tres colores del formato RGB. Los posibles valores son: color=0 Rojo color=1 Verde color=2 Azul

Un ejemplo de este fichero puede ser: pasillo 300 simil ver 95 10 100 112 1

47

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

En este caso se analiza la secuencia de imágenes comprendidas entre pasillo1 y pasillo300, utilizando el método de similitud (correlación), comprueba movimiento en la franja vertical comprendida entre 100 y 112, detectado movimiento siempre que el cambio sea superior al 5% (100%-95%) y utilizando el color Verde.

En este caso el valor 10 no se utiliza pues solo tiene sentido en caso que

realicemos la vigilancia por el método de igualdad. Anotamos en este punto que en caso de análisis vertical u horizontal una

franja de 5 pixels de anchura suele ser suficiente. Para leer este fichero hemos desarrollado una función que nos

comprueba que los valores son correctos en tipo y valor y que se encuentran según las circunstancias dentro de los valores permitidos. Se denomina lectot.m.

function [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectot %[imagen,N,tipovig,sentido,umbral,valor,N1,N2,i]=lectrap %Lee del fichero denominado camara.txt y comprueba que los valores %son concordantes con los requesitos del programa de vigilancia. fid=fopen('camara.txt','rt'); if (fid==-1) error(['Error abriendo camara.txt para lectura.']); %saltar a inicializar camara.txt, else fallo=0; end; if (nargout~=9) error('Falta algun dato para comenzar el analisis.'); end; %--------------------------------------------------------------- imagen=fgetl(fid); if (isstr(imagen)~=1) fallo=1; end; %--------------------------------------------------------------- N=fgetl(fid); N=str2num(N);

48

Proyecto fin de carrera Gonzalo Leandro Bravo

%--------------------------------------------------------------- tipovig=fgetl(fid); if (tipovig~='igual') if (tipovig~='simil') fallo=2; end; end; %--------------------------------------------------------------- sentido=fgetl(fid); if (sentido~='all') if (sentido~='ver') if (sentido~='hor') fallo=3; end; end; end; %--------------------------------------------------------------- umbral=fgetl(fid); umbral=str2num(umbral); if (umbral<0|umbral>100) fallo=4; end; %--------------------------------------------------------------- valor=fgetl(fid); valor=str2num(valor); if (valor<0|valor>20) fallo=5; end; %--------------------------------------------------------------- N1=fgetl(fid); N1=str2num(N1); N2=fgetl(fid); N2=str2num(N2); if N1>N2 fallo=6; else A=[imagen, num2str(1)]; [YSize, XSize]=N1N2(A); if (sentido=='ver' & N2>YSize) fallo=6; end if (sentido=='hor' & N2>XSize) fallo=6; end end %--------------------------------------------------------------- color=fgetl(fid);

49

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

color=str2num(color); if (color~=0) if (color~=1) if (color~=2) color=0; fallo=7; end; end; end; %--------------------------------------------------------------- fclose(fid); %--------------------------------------------------------------- if fallo==0 fprintf(1,'El fichero camara.txt existe, asegurese de que es el deseado\n'); fprintf(1,'Vigilando...\n'); else switch fallo case 1, fprintf(1,'El nombre de los fotogramas ha de ser una cadena de caracteres.\n'); fprintf(1,'Tomaremos valor por defecto imagen.bmp.\n'); imagen='imagen.bmp'; case 2, fprintf(1,'El tipo de analisis ha de ser "igual" o "simil".\n'); fprintf(1,'Tomaremos valor por defecto simil.\n'); tipovig='simil'; case 3, fprintf(1,'El tipo de analisis ha de ser "all", "ver" o "hor".\n'); fprintf(1,'Tomaremos valor por defecto all.\n'); sentido='all'; case 4, fprintf(1,'El valor del umbral se debe encontrar entre 0 y 100.\n'); fprintf(1,'Tomaremos valor por defecto 90.\n') umbral=90; case 5, fprintf(1,'El valor del valor se debe encontrar entre 0 y 20.\n'); fprintf(1,'Tomaremos valor por defecto 15.\n') valor=15; case 6, fprintf(1,'El valor de N2 ha de ser mayor que el de N1 y estar dentro de los limites de la imagen.\n'); fprintf(1,'Revise el fichero de inicio.\n'); fprintf(1,'Los valores de la imagen deben de estar comprendidos entre %i y %i.\n',YSize,XSize)

50

Proyecto fin de carrera Gonzalo Leandro Bravo

fprintf(1,'Realizaremos un analisis total de la imagen.\n'); sentido='all'; case 7, fprintf(1,'Error en la eleccion del color tomaremos Rojo por defecto'); color=0; otherwise, fprintf(1,'WARNING: Es posible que haya algun error en camara.txt, asegurese de que es el deseado\n'); fprintf(1,'Vigilando...\n'); end end %---------------------------------------------------------------

Como se puede comprobar este código podría ser literalmente compilado

en C. Además se ha procurado que esta función resulte un filtro de parámetros para mi programa, es decir, ante cualquier anomalía en el valor de los mismo no se para la ejecución, sino que se toman unos valores por defecto.

En lectot.m se llama a la función N1N2.m que devuelve las dimensiones

de la imagen para poder comprobar que me encuentro dentro de los límites. Para ello utilizamos la imagen1.bmp, por lo que es necesario que esta exista en el momento de empezar la vigilancia, en caso contrario nos daría error y se pararía la ejecución del programa.

El cuerpo de esta función no se añade al ser igual que el de bmpallrap.m

con valores de salida el tamaño de la imagen, sin realizar la lectura de la imagen.

2.3.2. Cuerpo principal. En esta función se realiza la vigilancia propiamente dicha. El fichero

vigila.m no acepta parámetros de entrada ni los tiene de salida, nos comunicamos con él a través de ficheros de texto. Aquí tenemos el cuerpo principal del sistema de vigilancia que vamos a utilizar.

Podíamos haber realizado un código más corto evitando repetir

instrucciones pero como lo que hemos estado buscando es velocidad de ejecución preferimos realizar las consultas que sólo son necesarias en el momento de inicializar para luego centrarnos en el cambio de la imagen.

51

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

function vigila %vigila %los parametros de encuentra inicializados en camara.txt, %vigila lee de camara.txt los datos necesariosa para el analisis, %calcula cambio en las imágenes y escribe en intruso.txt los fotogramas que han cambiado. [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectot; umbral=umbral/100; %Esta funcion toma imagen completa o solo un trozo de la misma. A=[imagen, num2str(1)]; if sentido=='all' actual=bmpallrap(A,color); else %calculo el tamano de la imagen que voy a analizar actual=bmptrozorap(A,sentido,N1,N2,color); end tamano=length(actual); fid=fopen('intruso.txt','wt'); if (fid==-1) error(['Error abriendo intruso.txt para escribir.']); end; %Con estos bucles aumento el codigo pero me quedo dentro de una de ellos durante la vigilancia. if tipovig=='igual' if sentido=='all' for I =1:N-1 %Analisis por igualdad +-valor de la imagen completa. B=[imagen, num2str(I+1)]; siguiente=bmpallrap(B,color); a(I)=sum(abs(actual-siguiente)<valor)/(tamano); actual=siguiente; if a(I)<umbral fprintf(fid,'Alarma en el fotograma %i\n',I); fprintf(1,'Alarma en el fotograma %i\n',I); end end else for I =1:N-1 %Analisis por igualdad +-valor de lineas de la imagen. B=[imagen, num2str(I+1)]; siguiente=bmptrozorap(B,sentido,N1,N2,color); a(I)=sum(abs(actual-siguiente)<valor)/(tamano); actual=siguiente; if a(I)<umbral fprintf(fid,'Alarma en el fotograma %i\n',I); fprintf(1,'Alarma en el fotograma %i\n',I);

52

Proyecto fin de carrera Gonzalo Leandro Bravo

end end end else if sentido=='all' for I =1:N-1 %Analisis por comparacion de la imagen completa. B=[imagen, num2str(I+1)]; siguiente=bmpallrap(B,color); %modificacion de corr2.m en la que no restamos la media, de esta manera evitamos %problemas con las zonas de un solo tono. a(I) = sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); %Suponemos que este fichero no debe dar error pues solo es llamado desde dentro %de un bucle donde conocemos las funciones que vamos a enviar como parametro actual=siguiente; if a(I)<umbral fprintf(fid,'Alarma en el fotograma %i\n',I); fprintf(1,'Alarma en el fotograma %i\n',I); end end else for I =1:N-1 %Analisis por comparacion de lineas de la imagen. B=[imagen, num2str(I+1)]; siguiente=bmptrozorap(B,sentido,N1,N2,color); a(I) = sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); actual=siguiente; if a(I)<umbral fprintf(fid,'Alarma en el fotograma %i\n',I); fprintf(1,'Alarma en el fotograma %i\n',I); end end end end fclose(fid);

Esta función realiza una vigilancia limitada en el tiempo pues le indicamos el número de fotogramas que queremos analizar (N) y nos muestra

53

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

por pantalla y en el fichero intruso.txt aquellos instantes en los que ha habido cambio.

En la fase de realización en tiempo real esta función será modificada para

realizar la vigilancia para un número ilimitado de fotogramas e irá borrando de memoria aquellos en los que no detecte cambio. De esta manera evitamos la saturación del disco duro y conseguimos almacenar los fotogramas que dieron alarma.

Por otro lado y teniendo en cuenta que este programa ha sido realizado

conjuntamente con el presentado en la fase 3 para conseguir que el sistema analice una serie de fotogramas por segundo hemos optado por supeditar este programa de vigilancia a la existencia o no de los fotogramas captados. Es decir, que posteriormente el sistema de vigilancia en caso de no poder abrir una imagen esperará un cierto periodo de tiempo y volverá a intentarla trascurrido el mismo, será pues la capturadora de fotogramas la que imponga el ritmo al sistema.

Lo realizaremos de esta forma porque como comprobaremos

posteriormente este programa de vigilancia es infinitamente más rápido que el de captación (con un máximo de 30 fps) por lo que hacerlo esperar por ejemplo ¼ de segundo en caso de no encontrar un fotograma sólo nos influye en la posibilidad de detectar un movimiento ¼ de segundo más tarde, pero en ningún caso de no hacerlo.

2.3.3. Lectura de ficheros BMP Como ya indicamos anteriormente esta es la parte más complicada del

sistema. En un apartado posterior dedicado al consumo de tiempo por parte del sistema se verá la importancia que tiene la lectura de fichero sobre el tiempo total. Puede llegar a representar mas del 90 % del mismo.

La función principal vigila.m diferencia cuando está abriendo una

imagen completa de cuando lo que solicita es una franja vertical u horizontal, de esta manera evitamos gastar tiempo dentro de mi sistema leyendo de disco una imagen completa cuando luego estemos interesados en sólo una porción de la misma.

54

Proyecto fin de carrera Gonzalo Leandro Bravo

Aunque en un principio el análisis de una franja es suficiente para detectar cambios de movimientos, como se indicó en la fase 1 de proyecto, se deja esta opción para solicitarla si se desea ya que existen circunstancias en las cuales por limitaciones espaciales el posible cambio no está localizado en un sector.

Para realizar la lectura de estos ficheros se utilizan las funciones fread.m

y fseek.m, de las cuales se adjunta (Anexo 6.1 y 6.2) la ayuda que proporciona Matlab para facilitar la comprensión de las funciones de lectura.

2.3.3.1. Lectura de imagen completa BMP En caso de la imagen completa tendremos bmpallrap.m

function [X]=bmpallrap(nombrefich,color); %bmpallrap lee un fichero bmp24 de disco y devuelve un vector con los datos solicitados %de esta manera se acelera el proceso de lectura y su posterior analisis. %No acepta bmp diferentes de 24 bits. %[X]=bmpallrap(nombrefich,color); %Toma el color Rojo =0; Verde =1; Azul=2; if (nargin~=2) error('Requiere un nombre de fichero como argumento y el color a utilizar.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; fid=fopen(nombrefich,'rb','l'); if (fid==-1) error(['Error abriendo ',nombrefich,' para lectura']); end;

55

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint'); if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; %------------------------------------------------------------- %Aqui es donde realiza la lectura del fichero tras analizarlo y posicionarme. fseek(fid, bfOffBytes+color, 'bof'); X=fread(fid,Size,'uchar',2); %------------------------------------------------------------- fclose(fid);

56

Proyecto fin de carrera Gonzalo Leandro Bravo

return; end

Comienza el fichero con unas comprobaciones de parámetros de entrada y abriendo el fichero con la ayuda de fopen, posteriormente comenzamos la lectura byte a byte de las características de la imagen: Tamaño, profundidad, número de bits, tipo de compresión, etc.

Nosotros realizamos la lectura de un solo color. Aunque sabemos que

esto no es lo mismo que tratar la imagen en blanco y negro, de esta manera conseguimos agilizar el programa y los resultados son los mismos.

Aun así tenemos la posibilidad de cambiar el color. Determinados

fondos, estados de luminosidad o uniformidad de color en la imagen pueden falsear la lectura por lo que en el sistema de inicialización todo esto será tenido en cuenta y se seleccionará el color de mayor variabilidad y de media más centrada. Vamos a buscar el color que es más fácil que nos dé alarma.

El vector de salida será de este tipo: Si color = 0 (Rojo),

Imagen=R41R42R43R44R45R31R32R33R34R35R21R22R23R24R25R11R12R13R14R15

Esto es debido a que la lectura se realiza con el comando,

X=fread(fid,Size,'uchar',2), que realiza del fichero con identificador fid lecturas de tamaño ‘uchar’ (1byte), de forma que lee uno salta dos, lee uno salta dos,...hasta completar el tamaña Size (Ancho*Largo).

Como se puede observar no tiene el orden de la imagen, pero eso no nos importa siempre y cuando todas las lecturas se realicen de la misma forma. Como en realidad ocurre.

2.3.3.2. Lectura de franja de imagen BMP

En caso de la una franja de la imagen tendremos bmptrozorap.m

57

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

function [X]=bmptrozorap(nombrefich,direccion,N1,N2,color); %bmptrozorap lee un trozo de fichero bmp24 de disco y devuelve un vector con los datos solicitados %de esta manera se acelera el proceso de lectura y su posterior analisis. %No acepta bmp diferentes de 24 bits. %[X]=bmptrozorap(nombrefich,direccion,N1,N2,color); %Toma el color Rojo =0; Verde =1; Azul=2; if (nargin~=5) error('Requiere un nombre de fichero como argumento,la franja a analizar y el color deseado.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; fid=fopen(nombrefich,'rb','l'); if (fid==-1) error(['Error abriendo ',nombrefich,' para lectura']); end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint');

58

Proyecto fin de carrera Gonzalo Leandro Bravo

if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint'); if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; fseek(fid, bfOffBytes+color, 'bof'); if direccion=='hor' fseek(fid,XSize*(YSize-N2)*3,0); X=fread(fid,XSize*(N2-N1+1),'uchar',2); end if direccion=='ver' fseek(fid,(N1-1)*3,0); X=fread(fid,(N2-N1+1),'uchar',2); for I=1:YSize-1 fseek(fid,(XSize-(N2-N1+1))*3,0); Y=fread(fid,(N2-N1+1),'uchar',2); X=[X ;Y]; end end fclose(fid); return; end

Aquí el funcionamiento es muy parecido. La lectura de valores de la función es idéntica y sólo a la hora de leer los datos de la imagen distinguimos entre vertical y horizontal.

Ante el comando ‘hor’ con N1=2 y N2=3, para el color Rojo tendríamos

a la salida, Imagen=R31R32R33R34R35R21R22R23R24R25

59

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Que se realiza con un solo salto y una sola lectura, y ante las opciones

‘ver’ con los mismos valores para N1 y N2, Imagen=R42R43R32R33R22R23R12R13 Que se realiza con cinco saltos y cinco lecturas de 2 pixels. Posteriormente cuando realicemos un análisis de tiempos de ejecución

comprobaremos la importancia de estas lecturas y veremos como se pueden intentar reducir los tiempos empleados.

2.4. Programas en C. Como se puede comprobar de la lectura de los ficheros utilizados en Matlab las

limitaciones en el compilador que le acompaña nos obliga a hacer una programación muy similar a la que hubiéramos utilizado de haber optado por realizar todo el proceso de simulación en C. A pesar de ello y una vez conseguido realizar las funciones que deseamos sin acudir a la librería de imágenes que Matlab nos presenta realizamos la compilación de estos ficheros utilizando el comando.

mcc –m vigila En el Anexo 6.3 se acompaña la ayuda de la instrucción mcc que ejecuta el

compilador. Recordamos que es necesario asociar un compilador de C para obtener un ejecutable y no solo los ficheros en c. Para ello previamente ejecutaremos el comando mcc –setup.

En nuestro caso usaremos el Visual C/C++ de Microsoft. De esta manera creamos unos ficheros.c que se acompañan como Anexo 6.4. Son;

60

Proyecto fin de carrera Gonzalo Leandro Bravo

vigila.c vigila.h

vigila_main.c lectot.c lectot.h N1N2.c N1N2.h bmpallrap.c bmpallrap.h bmptrozorap.c bmptrozorap.h Estos ficheros se acompañan como Anexo porque debido a su compilación

automática la asignación de nombre a las variables no es representativa y por lo tanto hace su análisis demasiado complicado. Teniendo en cuenta que son traducciones de los programas en Matlab se recomienda su análisis para comprender el funcionamiento del sistema.

Con estos ficheros hemos conseguido una aplicación que funciona y se

acompaña al proyecto.

2.5. Eficiencia. Análisis de tiempos de realización. Motivados por conseguir la mayor eficacia posible en cuanto a tiempo de

realización se refiere en este apartado nos plantearemos buscar en qué parte de mi simulación se invierte más tiempo para de esa manera intentar reducir el mismo incidiendo en los puntos más conflictivos.

Para realizar este análisis hemos realizados una serie de grabaciones de

15 segundos de una imagen sin movimiento a 10 fotogramas por segundo. Tenemos un total de 150 fotogramas que para su mejor análisis hemos procurado tengan diferentes tamaños.

Un ejemplo puede ser:

Imagen 1. (Imagen captada en tiempo real con videocámara doméstica

con ayuda del programa desarrollado en la fase 3, tamaño 144x192).

61

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Y como muestra de una de tamaño mayor.

Imagen 2. (Imagen captada en tiempo real con videocámara doméstica

con ayuda del programa desarrollado en la fase 3, tamaño 288x384). Como muestra de los resultados se acompaña una serie de tablas donde

podemos ver los tiempos que se tarda en cada una de las posibles situaciones de simulación.

Las mediciones realizadas de tiempo han sido conseguidas con la ayuda

de Matlab aplicando el comando cputime que nos permite conocer tiempo de ejecución. Este comando da una precisión de 0.05 segundos por lo que el algunas mediciones nos aparece 0 cuando en realidad sí se invierte algo de tiempo.

Hay que tener en cuenta que la aplicación en sí siempre será más rápida.

En el manual del compilador se nos habla de conseguir una mejora que ronda el 20%.

Hemos considerado oportuno medir los siguientes valores: (tiempo

medido en segundos)

62

Proyecto fin de carrera Gonzalo Leandro Bravo

T1.- Tiempo empleado en leer el fichero de inicio. T2.- Tiempo empleado en abrir un fichero y devolver los datos en forma

de vector. T3.- Tiempo total de ejecución. Conceptos de interés. PEQ.- 144x192 GRA.- 288x384 ‘simil’.- Realiza la correlación para comprobar como de similares con las

imágenes. ‘igual’.- Comprueba byte a byte si con iguales a los anteriores con un

valor de tolerancia.

Análisis completo por ‘simil’ Análisis completo por ‘igual’ T1 T2 T3 T1 T2 T3

Imagen1. PEQ 0 0.05 7.47 0 0.06 7.75 Imagen2. PEQ 0 0.05 7.76 0 0.05 8.22 Imagen1. GRA 0 0.20 33.10 0 0.22 39.55 Imagen2. GRA 0 0.20 35.61 0 0.16 28.89

Teniendo en cuenta que la simulación corresponde a 15 segundos resulta

imposible realizar con este sistema la vigilancia en las imágenes completas de mayor tamaño.

Por otro lado vemos que el problema que se nos plantea no tiene solución

pues el tiempo es empleado en leer las imágenes de memoria.

63

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

T2 (seg/fotograma) * 150 (fotogramas) ~= T3(seg) En el sistema planteado en este proyecto, es decir, captar por un

lado, guardando en memoria para posteriormente volver a leer, no es posible analizar las imágenes completas que alcancen un determinado tamaño.

Aunque en la fase 1 la realización de la vigilancia por similitud o por

igualdad requerían un tiempo de simulación diferentes, en esos momentos parece que el tiempo empleado en ambos casos es muy parecido.

Si ahora analizamos sólo una franja vertical u horizontal de anchura 5

pixel tenemos los siguientes resultados. Utilizaremos únicamente el análisis por similitud.

Análisis horizont por ‘simil’ Análisis vertical por ‘simil’ T1 T2 T3 T1 T2 T3

Imagen1. PEQ 0 0 0.77 0 0 3.84 Imagen2. PEQ 0 0 0.99 0 0 4.06 Imagen1. GRA 0 0.06 2.15 0 0.07 8.18 Imagen2. GRA 0 0.05 2.30 0 0.05 8.24

La primera conclusión es que los tiempo se reducen

considerablemente y que “en un principio” la vigilancia sería posible. Decimos que en un principio porque este tiempo de ejecución es

dedicando todos los recursos al sistema de vigilancia, y esto no puede ocurrir tal y como planteamos este proyecto. Para que el sistema sea en tiempo real debemos además de comprobar el cambio en las imágenes capturarlas.

Posteriormente se comprobará que con el equipo con el que realizamos

las simulaciones (Pentium III a 733 MHz y 128 Mb de RAM) la vigilancia de esta forma es completamente viable.

64

Proyecto fin de carrera Gonzalo Leandro Bravo

Hay que destacar la diferencia existente entre la vigilancia horizontal y la vertical. Tardamos cuatro veces más en hacer el análisis vertical que el horizontal. Esto esta posiblemente motivado por el sistema secuencial que utilizamos para leer la imagen en el cual nos vemos obligados a realizar un bucle for para desplazarnos por las filas de la matriz correspondiente a la imagen.

Intentando comprobar si este es realmente el motivo y siempre buscando

aumentar la velocidad, veamos detalladamente como se realiza dicha lectura de datos y como podríamos modificarla.

Si entramos en detalles sobre cómo hacemos la lectura vertical e

incorporamos medidores de tiempo tal que:

t1=cputime-t if direccion=='ver' fseek(fid,(N1-1)*3,0); X=fread(fid,(N2-N1+1),'uchar',2); t2=cputime-t for I=1:YSize-1 fseek(fid,(XSize-(N2-N1+1))*3,0); Y=fread(fid,(N2-N1+1),'uchar',2); X=[X ;Y]; end end fclose(fid); t3=cputime-t

T1.- Tiempo inicial dedicado a la lectura de bits de control de la imagen,

en todos los casos es cero. T2.- Tiempo dedicada a leer los 5 píxeles de una línea. En todos los

casos es cero. T3.- Tiempo completo de lectura de una franja de 5x144 y 5x288 de una

sola imagen. Da el valor mínimo medible de 0.05 En este caso ante los comandos ‘ver’ con N1=2 y N2=3 tendríamos que

la imagen resultante en el vector de datos es. Imagen=R42R43R32R33R22R23R12R13

65

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Pero para responder a la posible pregunta de qué es lo que retarda el sistema, si la lectura (T2=0) o la utilización del comando ‘for’ planteamos una nueva forma para leer al que añadimos también indicadores de tiempo.

t1=cputime-t if direccion=='ver' fseek(fid,(N1-1)*3,0); X=fread(fid,YSize,'uchar',(XSize-1)*3+2); for I=1:N2-N1 t2=cputime-t fseek(fid, bfOffBytes, 'bof'); fseek(fid,(N1-1+I)*3,0); t3=cputime-t Y=fread(fid,YSize,'uchar',(XSize-1)*3+2); X=[X ;Y]; end t4=cputime-t

Ahora la imagen la leemos con un bucle mucho más corto, en nuestro

ejemplo entraríamos en él sólo cuatro veces y la imagen que tendríamos quedaría ordenada de la siguiente forma.

Imagen=R42R32R22R12R43R33R23R13 Que aparentemente debiera de ser más rápido, pero los tiempos nos

indican que esto no es así. T1.- Tiempo inicial dedicado a la lectura de bits de control de la imagen,

en todos los casos es cero. T3 a T2.- Tiempo dedicado a la lectura de una columna de píxeles, para

la imagen pequeña (144) 0.06 segundos y para la grande (288) de 0.11 segundos. T2 a T3.- Tiempo empleado en colocarme al principio de cada columna

para su posterior lectura. En todos las casos es cero. Esto nos da a entender que el problema reside en la función ‘fread’ y no

en ‘fseek’, por lo que no puedo reducir este tiempo ya que la lectura de datos es obligatoria. Es mejor leer trozos pequeños próximos muchas veces que hacer

66

Proyecto fin de carrera Gonzalo Leandro Bravo

pocas veces la lectura de datos muy separados en el fichero. El salto entre lectura relentiza el sistema.

2.6. Vigilancia de regiones rectangulares.

Tal y como se ha planteado el sistema no es posible realizar vigilancia de regiones rectangulares. Acompañamos las modificaciones necesarias para realizar la misma.

Para ello y como se hizo en la fase 1 los parámetros requeridos serán

cuatro, N1, N2, M1 y M2. Y hay que sustituir la función de lectura de ficheros parciales BMP antes indicados por el siguiente.

function [X]=bmptrozo(nombrefich,N1,N2,M1,M2); %leerbmp lee un fihero bmp24 de disco % No acepta bmp diferentes de 24 bits. %[X,map,out3]=leerbmp(nombrefich); if (nargin~=5) error('Requiere un nombre de fichero como argumento y la franja a analizar.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; fid=fopen(nombrefich,'rb','l'); if (fid==-1) error(['Error abriendo ',nombrefich,' para lectura']); end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.');

67

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint'); if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; fseek(fid, bfOffBytes, 'bof'); X=fread(fid,Size,'uchar',2); X=rot90(reshape(X, XSize, YSize)); X=X(N1:N2,M1:M2); fclose(fid); return; end

68

Proyecto fin de carrera Gonzalo Leandro Bravo

En este caso se devuelve una matriz y en la opción de ‘igual’ habría que

modificar la opción

a(I)=sum(abs(actual-siguiente)<valor)/(tamano);

por

a(I)=sum(sum(abs(actual-siguiente)<valor))/(tamano);

Esta opción no está permitida en el ejecutable que se acompaña. Y se

menciona como una posible mejora al sistema planteado.

2.7. Inicialización del sistema.

Este apartado se realiza en último lugar pues es necesario disponer de un ejecutable para poder comprobar el funcionamiento así como de la posibilidad de disponer de varias secuencias de video para su análisis.

Como en casos anteriores este estudio lo realizaremos con una secuencia

de 15 segundos y 10 fotogramas por segundo. Nuestro ejecutable lee de camara.txt los datos necesarios para comenzar

a funcionar. Estos datos pueden ser dispuestos manualmente por conocimiento del funcionamiento del programa con riesgo de indicar márgenes de tolerancia equivocados, umbrales incorrectos o insuficientes y de hacer el sistema completamente inservible o con la ayuda del programa que se muestra a continuación.

Necesitamos conocer valores medios de las nuevas secuencias

conseguidas con el sistema que plantearemos como definitiva para de esta manera tener datos fiables sobre valores umbrales y calidad de la imagen

Analizando nuestro fichero de entrada vemos que algunos de los

parámetros son indispensablemente suministrados por el usuario del sistema.

69

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Estos parámetros son aquellos que quedan ajenos a mi sistema de vigilancia y están relacionados con la interrelación de ambos programas.

Por ello antes de comenzar a inicializar el sistema es necesario crear un

fichero de texto llamado indicaciones.txt en el cual se nos muestre el nombre de las secuencias de imágenes, el número total de fotogramas que queremos analizar en nuestro programa de vigilancia (-1 si lo desconocemos o deseamos vigilancia ilimitada), el sistema que vamos a utilizar (vigilancia completa, vertical o horizontal) y si es necesario las franjas que analizaremos.

Hay que aclarar que el sistema que utilizaremos depende de la imagen

que esté enfocando al cámara. Como ya mencionamos anteriormente, un pasillo por ejemplo, se aconseja vigilar con solo una franja, pero una habitación que no es de paso es preferible hacer el análisis completo.

En el código de Matlab del programa de lectura se puede ver el formato

que se debe especificar en este fichero. Un ejemplo sería: imagen 300 all 100 104 Que nos indica que nuestra capturadora graba los fotogramas con el

nombre imagen1.bmp, imagen2.bmp, etc. Que vamos a analizar 300 fotogramas con un análisis total de la imagen y se deprecian los datos de las franjas al no ser necesario.

Tenemos que aclarar que en este caso no nos hemos preocupado de

conseguir un sistema de inicialización rápido pues esta aplicación sólo debe aplicarse al comenzar a trabajar o bien cuando las condiciones de la cámara han cambiado, pero en ambos casos esto se realiza siendo consciente de que el sistema no está trabajando.

Las opciones que se puede plantear nuestro sistema son las siguientes: Color.- Necesitamos conocer cual es el color que vamos a utilizar.

70

Proyecto fin de carrera Gonzalo Leandro Bravo

Para ello abrimos las 150 imágenes y estudiamos los tres colores de forma independiente. La apertura la realiza el fichero bmpinicial.m que en este caso nos devuelve tres matrices de tamaño Ancho X Largo.

Realizamos la media y la varianza correspondiente a cada fotograma,

esto se almacena en un vector. A continuación calculamos sobre ese vector tres valores que pasaremos a explicar.

Media del vector media: Con este dato conseguimos una media

completa de todos los pixeles de los 150 fotogramas, no nos interesa que sea ni demasiado alto ni demasiado bajo, por lo que de entre las tres opciones que tenemos optaremos por aquella con media intermedia.

Varianza del vector media: Nos da un valor representativo de la

calidad de la imagen que hemos captado, nos interesa ya que suponemos que la imagen no debe cambiar aquella con menor varianza de la media.

Media de la varianza: Nos indica la existencia de diferencias

dentro de un mismo fotograma, es decir la existencia de zonas claras y oscuras dentro de cada fotografía. Para evitar confusiones y falsas alarmas nos interesa el color que represente una mayor uniformidad, es decir, con una media de la varianza menor. Nosotros nos limitamos a comprobar cual de los tres colores, rojo, verde

y azul cumple más de estas condiciones y lo asignamos como color de nuestro sistema.

Tipo de vigilancia, umbral y valor son tres parámetros relacionados sobre los que debemos trabajar sobre un todo y no podemos como en el caso del color asignarlos de uno en uno.

Nos vemos obligados a comenzar el análisis y no podemos usar el bucle de lectura que utilizamos para el color porque ahora continuaremos exclusivamente para el color que hemos seleccionado. Pero ahora podemos continuar con el sistema de lectura por vector que acelera los resultados.

Las posibles situaciones que nos planteamos son cinco; análisis por similitud y análisis por igualdad para un margen de 5, 10, 15 y 20.

En este caso no analizaremos valores para cada fotograma, sino para cada posible situación de comparación. Para las cuales calcularemos la media, la varianza y el valor mínimo.

71

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Análisis de la imagen total: Para una secuencia de tamaño 144x192 tendremos; PRUEBA 1 PRUEBA 2 mediaigual5 = 0.5500 0.8967 stdeigual5 = 0.0344 0.0122 minigual5 = 0.5059 0.8748 mediaigual10 = 0.8708 0.9943 stdeigual10 = 0.0205 0.0033 minigual10 = 0.8368 0.9864 mediaigual15 = 0.9748 0.9989 stdeigual15 = 0.0057 0.0011 minigual15 = 0.9607 0.9956 mediaigual20 = 0.9923 0.9997 stdeigual20 = 0.0027 3.9597e-004 minigual20 = 0.9856 0.9985 mediasimil = 0.9985 0.9997 stdsimil = 1.7778e-004 3.7907e-005 minsimil = 0.9981 0.9996

(Tabla 1) Para una secuencia de tamaño 288x384 tendremos; PRUEBA 1 PRUEBA 2 mediaigual5 = 0.8393 0.9027 stdeigual5 = 0.0133 0.0140 minigual5 = 0.8174 0.8739 mediaigual10 = 0.9911 0.9957 stdeigual10 = 0.0049 0.0026 minigual10 = 0.9822 0.9890 mediaigual15 = 0.9984 0.9984 stdeigual15 = 0.0018 9.1737e-004 minigual15 = 0.9946 0.9955 mediaigual20 = 0.9995 0.9987 stdeigual20 = 6.3633e-004 5.6168e-004 minigual20 = 0.9981 0.9974 mediasimil = 0.9996 0.9997 stdsimil = 5.0737e-005 3.5517e-005 minsimil = 0.9995 0.9996

(Tabla 2)

72

Proyecto fin de carrera Gonzalo Leandro Bravo

Análisis de la imagen HORIZONTAL: Para una secuencia de tamaño 5x192 tendremos; PRUEBA 1 PRUEBA 2 mediaigual5 = 0.6141 0.9029 stdeigual5 = 0.0345 0.0195 minigual5 = 0.5391 0.8568 mediaigual10 = 0.8733 0.9931 stdeigual10 = 0.0238 0.0068 minigual10 = 0.8299 0.9722 mediaigual15 = 0.9655 0.9985 stdeigual15 = 0.0103 0.0026 minigual15 = 0.9375 0.9887 mediaigual20 = 0.9853 0.9995 stdeigual20 = 0.0057 0.0015 minigual20 = 0.9740 0.9948 mediasimil = 0.9991 0.9997 Stdsimil = 1.8096e-004 6.5709e-005 minsimil = 0.9986 0.9995

(Tabla 3) Para una secuencia de tamaño 5x384 tendremos; PRUEBA 1 PRUEBA 2 mediaigual5 = 0.8440 0.9159 stdeigual5 = 0.0177 0.0165 minigual5 = 0.7973 0.8776 mediaigual10 = 0.9928 0.9961 stdeigual10 = 0.0048 0.0026 minigual10 = 0.9783 0.9887 mediaigual15 = 0.9993 0.9985 stdeigual15 = 0.0010 0.0010 minigual15 = 0.9957 0.9952 mediaigual20 = 0.9998 0.9988 stdeigual20 = 2.3920e-004 7.1544e-004 minigual20 = 0.9987 0.9970 mediasimil = 0.9997 0.9999 Stdsimil = 3.7376e-005 2.0675e-005 minsimil = 0.9996 0.9998

(Tabla 4)

73

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

nálisis de la imagen VERTICAL: Para una secuencia de tamaño 5x192 tendremos; PRUEBA 1 PRUEBA 2 mediaigual5 = 0.5661 0.9151 stdeigual5 = 0.0429 0.0127 minigual5 = 0.4889 0.8708 mediaigual10 = 0.8876 0.9997 stdeigual10 = 0.0271 6.9564e-004 minigual10 = 0.8222 0.9958 Mediaigual15 = 0.9875 1 stdeigual15 = 0.0065 0 minigual15 = 0.9694 1 Mediaigual20 = 0.9991 1 stdeigual20 = 0.0014 0 minigual20 = 0.9917 1 Mediasimil = 0.9989 0.9996 Stdsimil = 1.6296e-004 3.0389e-005 minsimil = 0.9985 0.9995

(Tabla 5) Para una secuencia de tamaño 5x384 tendremos; PRUEBA 1 PRUEBA 2 Mediaigual5 = 0.8622 0.9024 stdeigual5 = 0.0128 0.0119 minigual5 = 0.8257 0.8743 Mediaigual10 = 0.9974 0.9991 stdeigual10 = 0.0015 9.5932e-004 minigual10 = 0.9924 0.9938 Mediaigual15 = 1.0000 1 stdeigual15 = 9.7870e-005 0 minigual15 = 0.9993 1 Mediaigual20 = 1 1 stdeigual20 = 0 0 minigual20 = 1 1 Mediasimil = 0.9996 0.9996 Stdsimil = 2.4639e-005 2.8347e-005 minsimil = 0.9995 0.9995

(Tabla 6)

74

Proyecto fin de carrera Gonzalo Leandro Bravo

Como punto de partida podemos decir que nos interesa que la varianza

sea mínima, es decir que tengamos una situación de no alarma bastante definida. Observamos que la máxima varianza la obtenemos siempre para ‘igual 5’ y la mínima para ‘simil’. Esto nos puede llevar a pensar que en todos los casos la situación de ‘simil’ es la deseada.

Los valores de las tablas indican que la media y el valor mínimo en el

caso ‘simil’ están muy próximos entre sí y muy próximos a la unidad, por lo que en estas situaciones el más mínimo cambio nos daría una situación de alarma indeseada.

Concluimos pues que aunque desearíamos utilizar siempre este sistema

de detección, sólo lo vamos a emplear cuando nos encontremos con una imagen de calidad media y baja.

Para decidir cuando una imagen tiene calidad media se toma la varianza

de ‘igual 5’ que es la que nos da en todos los casos un valor superior y la comparamos con 0.03, a partir de este valor optamos por el sistema de similitud.

Podemos comprobar en Tabla 1 (prueba 1) y Tabla 3 (prueba 1), que son

las dos situaciones en las que el análisis por similitud toma un valor mínimo de la comparación inferior a 0.999. Esto demuestra que la elección de este criterio parece acertado.

Una vez que hemos decidido utilizar el sistema de similitud o igualdad,

en caso de utilizar el segundo debemos determinar que valor (5, 10, 15 o 20) utilizaremos para continuar trabajando, para justificar esta decisión se muestran las siguientes tablas con los incrementemos de valor medio al pasar de 5 a10, 10 a 15 y 15 a 20.

Buscamos que el valor medio menor mayor posible con la varianza más

pequeña, pero también que nuestro margen sea el más pequeño posible pues, por ejemplo, en caso de decidirnos por 20 es posible que muchas de las situaciones de cambio pasen inadvertidas.

75

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

ANÁLISIS TOTAL ANÁLISIS HORIZONTAL PRUEBA1 PRUEBA2 PRUEBA1 PRUEBA2

5 a

10

0.0671 0.0976 0.0755 0.0980

10 a

15

0.0027 0.0046 0.0015 0.0050

IMAGEN PEQUEÑA

15 a

20

4.1121e-004 8.1684e-004 3.4955e-004 9.8574e-004

5 a

10

0.0930 0.1518 0.1484 0.0879

10 a

15

0.0027 0.0073 0.0082 0.0023

IMAGEN GRANDE

15 a

20

3.3559e-004 0.0011 0.0018 3.2159e-004

(Tabla 7). Mejora del nivel medio. Si se tiene en cuenta que vamos a trabajar con valores medios cercanos a

0.999 y que nuestro umbral estará colocado inferior a él pero bastante próximo, ampliaremos al siguiente margen siempre que el cambio nos resulte significativo, es decir, siempre que sea superior a 0.005.

Según la tabla de resultados Tabla 7 la situación de ‘igual 5’ no se puede

dar en ninguna circunstancia y es entre ‘igual 10’ e ‘igual 15’ en la que se mantiene en todo momento.

Atendiendo a otras simulaciones realizadas, que no se acompañan en esta

memoria, se considera la posibilidad de que la opción optima sea ‘igual 20’, siempre con este mismo criterio de selección.

Decidido qué tipo de vigilancia vamos a utilizar en cada caso, debemos

ahora determinar un umbral para esta situación, para ello utilizaremos el conocimiento que tenemos del valor mínimo y medio en cada situación.

76

Proyecto fin de carrera Gonzalo Leandro Bravo

Es muy importante que la grabación de configuración se encuentre

libre de movimientos. Se tomará para cada situación seleccionada el valor mínimo menos la

diferencia entre el valor medio menos el mínimo, o lo que es lo mismo, permitimos el doble de movimiento de lo que está considerado como no movimiento.

La precisión con la que trabajamos utilizando este sistema nos obliga a

determinar un umbral con cuatro cifras significativas. Por los que hemos de cambiar en el programa de vigilancia y dividir el valor que leemos del fichero camara.txt correspondiente a umbral por 10.000.

Es el programa que se muestra a continuación el que realiza estas

operaciones.

2.8. Inicialización del sistema en Matlab. Se acompañan los ficheros de los programas que difieren de los anteriormente

utilizados.

2.8.1. “configurar.m” function configurar [imagen,N,sentido,N1,N2]=lecconfigurar; %Determino el color que voy a utilizar for I =1:149 B=[imagen, num2str(I+1)]; [Rojo,Verde,Azul]=bmpinicial(B); rojomedia(I)=mean2(Rojo); rojovar(I)=std2(Rojo); verdemedia(I)=mean2(Verde); verdevar(I)=std2(Verde); azulmedia(I)=mean2(Azul); azulvar(I)=std2(Azul); end

77

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

%--------------------------------------------------------------- uno=[mean(rojomedia) mean(verdemedia) mean(azulmedia)]; dos=[std(rojomedia) std(verdemedia) std(azulmedia)]; tres=[mean(rojovar) mean(verdevar) mean(azulvar)]; colorvec=[find(uno~=max(uno)&uno~=min(uno)), find(dos==min(dos)), find(tres==min(tres))]; rojo=(sum(colorvec==1)); verde=(sum(colorvec==2)); azul=(sum(colorvec==3)); if (rojo>=2) %tomo el rojo color=0; else if (azul>=2) %tomo el azul color=2; else color=1; end end % si el tercero es muy alto no me interesa pues tiene la imagen zonas de muy alto contraste %En general me interesa el que tenga el valor medio intermedio siempre que la varianza de la media no sea muy alta, % esto indicaría demasiados cambios, y la media de la varianza no fuera tampoco excesivamente grande. %1 indica el color medio de las imagenes %2 La variacion o no de las imagenes, interesa que sea pequeño %3 La variación dentro de una imagen %--------------------------------------------------------------- A=[imagen, num2str(1)]; if sentido=='all' actual=bmpallini(A,color); else actual=bmptrozoini(A,sentido,N1,N2,color); end tamano=length(actual); if sentido=='all' N1=1; N2=2; for I =1:149 B=[imagen, num2str(I+1)]; siguiente=bmpallini(B,color); temp=abs(actual-siguiente); igual5(I)=sum(temp<5)/(tamano); igual10(I)=sum(temp<10)/(tamano); igual15(I)=sum(temp<15)/(tamano); igual20(I)=sum(temp<20)/(tamano);

78

Proyecto fin de carrera Gonzalo Leandro Bravo

simil(I)=sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); actual=siguiente; end else for I =1:149 B=[imagen, num2str(I+1)]; siguiente=bmptrozoini(B,sentido,N1,N2,color); temp=abs(actual-siguiente); igual5(I)=sum(temp<5)/(tamano); igual10(I)=sum(temp<10)/(tamano); igual15(I)=sum(temp<15)/(tamano); igual20(I)=sum(temp<20)/(tamano); simil(I)=sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); actual=siguiente; end end mediaigual5=mean2(igual5); stdigual5=std2(igual5); mediaigual10=mean2(igual10); mediaigual15=mean2(igual15); mediaigual20=mean2(igual20); mediasimil=mean2(simil); stdsimil=std2(simil); minigual5 =min(igual5); minigual10 =min(igual10); minigual15 =min(igual15); minigual20 =min(igual20); minsimil=min(simil); cinco=mediaigual10-mediaigual5; diez=mediaigual15-mediaigual10; quince=mediaigual20-mediaigual15; diferencia=[cinco, diez, quince]; %si stdigual5>0.03 utilizo simil pq la imagen no es buena, cambia demasiado, comparo con 5 pq es el más variable if stdigual5>0.03 tipovig='simil'; umbral=(10000*(minsimil-(mediasimil-minsimil))); valor=15; else tipovig='igual'; a=max(find(diferencia>=0.005)); if a==1 valor=10; umbral=(10000*(minigual10-(mediaigual10-minigual10))); else

79

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

if a==2 valor=15; umbral=(10000*(minigual15-(mediaigual15-minigual15))); else valor=20; umbral=(10000*(minigual20-(mediaigual20-minigual20))); end end end %realizo esta operación para conseguir que umbral sea un número entero umbral2=0; while umbral>0 umbral2=umbral2+1; umbral=umbral-1; end fid=fopen('camara.txt','wt'); if (fid==-1) error(['Error abriendo camara.txt para escribir.']); end; fprintf(fid,'%s\n',imagen); fprintf(fid,'%i\n',N); fprintf(fid,'%s\n',tipovig); fprintf(fid,'%s\n',sentido); fprintf(fid,'%i\n',umbral2); fprintf(fid,'%i\n',valor); fprintf(fid,'%i\n',N1); fprintf(fid,'%i\n',N2); fprintf(fid,'%i\n',color); fclose(fid); fprintf(1,'La inicialización ha finalizado correctamente, puede ejecutar el programa de vigilancia\n');

La última parte de este fichero está dedicado a escribir en el fichero camara.txt los resultados del análisis para poder ejecutar el programa de vigilancia.

80

Proyecto fin de carrera Gonzalo Leandro Bravo

2.8.2. Lectura fichero configurar. “lecconfigurar.m”

function [imagen,N,sentido,N1,N2]=lecconfigurar %[imagen,N,sentido,N1,N2]=lecconfigurar %Lee del fichero denominado indicaciones.txt y comprueba que los valores %son concordantes con los requesitos del programa de vigilancia. %Los parametros son los siguientes, con las siguientes especificaciones: % %imagen: Cadena de caracteres con el nombre del fichero sin extension % debe ir entre comillas. % %N: Numero de fotogramas que voy a analizar, posteriormente se anulara su valor. %Si N=-1 indicamos análisis ilimitado en el tiempo % %sentido: Indica el sentido de la línea de vigilancia. % Puede tomar tres valores: 'all' analiza la imagen completa % 'ver' analisis vertical y % 'hor' analisis horizontal % %N1 y N2: Franjas que se van a analizar. Solo tiene sentido si sentido!='all' % fid=fopen('indicaciones.txt','rt'); if (fid==-1) error(['Error abriendo indicaciones.txt para lectura.']); else fallo=0; end; if (nargout<=3) error('Falta algun dato para comenzar el analisis.'); end; %--------------------------------------------------------------- imagen=fgetl(fid); if (isstr(imagen)~=1) fallo=1; end; %--------------------------------------------------------------- N=fgetl(fid); N=str2num(N); %---------------------------------------------------------------

81

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

%--------------------------------------------------------------- sentido=fgetl(fid); if (sentido~='all') if (sentido~='ver') if (sentido~='hor') fallo=3; end; end; end; %--------------------------------------------------------------- %--------------------------------------------------------------- %--------------------------------------------------------------- if sentido~='all' N1=fgetl(fid); N1=str2num(N1); N2=fgetl(fid); N2=str2num(N2); if N1>N2 fallo=6; else A=[imagen, num2str(1)]; [YSize, XSize]=dimensiones(A); if (sentido=='ver' & N2>YSize) fallo=6; end if (sentido=='hor' & N2>XSize) fallo=6; end end else N1=1; N2=1; end %--------------------------------------------------------------- %--------------------------------------------------------------- fclose(fid); %--------------------------------------------------------------- if fallo==0 fprintf(1,'El fichero indicaciones.txt existe, asegurese de que es el deseado\n'); fprintf(1,'Inicializando...\n'); else switch fallo case 1, fprintf(1,'El nombre de los fotogramas ha de ser una cadena de caracteres.\n'); fprintf(1,'Tomaremos valor por defecto imagen.bmp.\n'); imagen='imagen.bmp';

82

Proyecto fin de carrera Gonzalo Leandro Bravo

case 3, fprintf(1,'El tipo de analisis ha de ser "all", "ver" o "hor".\n'); fprintf(1,'Tomaremos valor por defecto all.\n'); sentido='all'; case 6, if sentido~='all' fprintf(1,'El valor de N2 ha de ser mayor que el de N1 y estar dentro de los limites de la imagen.\n'); fprintf(1,'Revise el fichero de inicio.\n'); fprintf(1,'Los valores de la imagen deben de estar comprendidos entre %i y %i.\n',YSize,XSize) fprintf(1,'Realizaremos un analisis total de la imagen.\n'); sentido='all'; end otherwise, fprintf(1,'WARNING: Es posible que haya algun error en indicaciones.txt, asegurese de que es el deseado\n'); fprintf(1,'Inicializando...\n'); end end %---------------------------------------------------------------

2.8.3. Lectura BMP en tres colores. “bmpinicial.m”

function [Rojo,Verde,Azul]=bmpinicial(nombrefich); %[X,map,out3]=bmpinicial(nombrefich); if (nargin~=1) error('Requiere un nombre de fichero como argumento.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; fid=fopen(nombrefich,'rb','l'); if (fid==-1)

83

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

error(['Error abriendo ',nombrefich,' para lectura']); end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint'); if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; fseek(fid, bfOffBytes, 'bof'); X=fread(fid,Size*3,'uchar'); Rojo= rot90(reshape(X(1:3:length(X)), XSize, YSize)); Verde= rot90(reshape(X(2:3:length(X)), XSize, YSize)); Azul= rot90(reshape(X(3:3:length(X)), XSize, YSize)) ; fclose(fid);

84

Proyecto fin de carrera Gonzalo Leandro Bravo

return; end

2.8.4. Resto de ficheros.

También acudimos a los ficheros bmptrozoini.m y bmpallini.m iguales a bmptrozorap.m y bmpallrap.m presentados en anteriores apartados. (Apartado 2.3.3.)

El fichero N1N2.m ha sido renombrado como dimensiones.m

2.9. Inicialización del sistema en C

Se acompaña en anexo los ficheros generados con el comando mcc –m

configurar en Matlab. Comprobamos que la programación el Matlab ha sido generada para

permitir su compilación y de esta manera conseguir crear un ejecutable. En esta ocasión no se muestran todos los ficheros.c y ficheros.h pues es

en Matlab y no en C donde mejor se aprecia el sistema utilizado para realizar los cálculos.

Aparecen configura.c (6.5.1.) y configurar_main.c (6.5.2.), el resto de los

ficheros pueden generarse utilizando Matlab y son similares a los incluidos en el anexo correspondiente al programa de vigilancia en C.

2.10. Manual del programa de Vigilancia y Configuración.

En primer lugar hemos de aclarar que no buscamos una aplicación

comercial, sino que se trata de una primera fase, fase de investigación y realización simplificada de un sistema de vigilancia por comparación de fotogramas haciendo uso de tratamiento digital de imagen.

85

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Es muy importante tener en cuenta que en ninguno de estos casos se he

procurado conseguir un interfaz con el usuario cómodo y fácil de manejar y que ambas aplicaciones son ‘aplicaciones MS-DOS’ generadas con ayuda de Matlab.

Durante la ejecución de los programas de vigilancia y configuración se

han añadido mensajes suficientes para en caso de error guiar al usuario hacia la resolución del mismo, además para cualquier conocedor del lenguaje de programación Matlab una lectura de los ficheros lectot.m (2.3.1.) y lecconfigurar.m (2.8.2.) le permitirían su correcto uso.

Aun así haremos una serie de indicaciones que consideramos de interés y

que es posible aún no se hayan mencionado. Antes de ejecutar el programa de vigilancia deben existir en la misma

carpeta la imagen1.bmp y el fichero de inicialización camara.txt. Este fichero puede ser creado con ayuda de este programa de configuración o bien con el bloc de notas que proporciona Microsoft Windows con el correspondiente riesgo de dar valores ineficaces.

La lectura de datos se realiza con ayuda de la función “fgetl.m” que

retorna el contenido de una línea del fichero como una cadena de caracteres por lo que los datos que tanto en camara.txt como en indicaciones.txt se almacenan deben de encontrarse uno en cada línea y separados por un return.

En caso de ejecutar y no existir imagen1.bmp el programa finaliza con un

error. Esto nos obliga a considerar la ejecución del programa de captación de fotogramas con anterioridad al de vigilancia.

En caso de ejecutar y no existir camara.txt el programa emite un mensaje

de error indicando que se proceda a la inicialización y finaliza. Hemos de tener en cuenta que el fichero camara.txt no desaparece al

interrumpir la ejecución ya que se considera que las cámaras a vigilar no cambian sus condiciones en el periodo estudiado. Por lo tanto hemos de tener la precaución didáctica de borrar dicho fichero cuando variemos la situación de la imagen captada.

Antes de inicializar hemos de acudir a la capturadora y aplicar los

valores por defecto de la opción vigilancia limitada (3.3.2.2.)

86

Proyecto fin de carrera Gonzalo Leandro Bravo

Para proceder a la inicialización hemos de crear, esta vez

obligatoriamente, con al ayuda del bloc de notas un fichero denominado indicaciones.txt con el nombre de las imágenes con el que la capturadora almacena los fotogramas, el número de fotogramas a analizar, el sistema empleado (‘all’, ‘ver’ o ‘hor’) y las franjas que deseamos en caso de ser análisis vertical u horizontal. Se recomienda colocar N1 y N2 a 1 cuando el análisis va a ser total.

Si la inicialización transcurre sin incidencias nos aparece un mensaje

indicándonoslo y ahora podremos realizar la vigilancia. Al estar trabajando con programas MS-DOS todos los ficheros,

programas e imágenes deben encontrarse en la misma dirección (carpeta). Una vez realizado todo este proceso podemos proceder como se indica en

la fase 4 de realización en tiempo real a la ejecución conjunta de ambos programas. Activando el de capturar en el modo vigilancia ilimitada y el de seguridad puesto simplemente en ejecución.

De una manera esquemática será:

87

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

88

DESEAMOS REALIZAR

UNA VIGILANCIA

COMENZAMOS CAPTURAS ILIMITADA.

COMENZAMOS SEGURIDADTPR

EXISTE CAMARA.TXT? SI

SISTEMA ACTIVO

DETENER CAPTURAS

NO

CONTINUAR VIGILANCIA

SI

DETENER CAPTURAS

NO

FIN EJECUCION

CREAR INDICACIONES.TXT

INICIALIZAR

SI

NOOK?

CAPTURAR 15 SEG

Proyecto fin de carrera Gonzalo Leandro Bravo

3. FASE 3. Programa de captación de fotogramas.

3.1. Introducción Llegados a este punto nos planteamos la necesidad de disponer en

memoria de los fotogramas que vamos a analizar. Aunque en la fase 2 se demuestra que pasar la imagen por memoria relentiza considerablemente el sistema nosotros vamos a llegar a realizar el sistema que en un principio se consideró objetivo de este proyecto. Es decir capturar y vigilar como elementos separados para posteriormente plantear la posible unión entre ambos.

Para realizar la captura se utilizará a modo de versión 1.0. una

videocámara doméstica conectada al PC a través de una tarjeta de video TV capture 98 de la casa Avermedia. Esto nos supone la necesidad de realizar un programa con capacidad de sincronismo con el chip bt878/879 de captación de señal que utiliza la tarjeta de Avermedia.

La solución a este problema la encontramos en los controles ActiveX

videocapx.ocx de Visual BASIC que permiten la sincronía y la captación de datos utilizando funciones predefinidas. Esto conlleva otro problema, tener la necesidad de conseguir un relativo dominio de un lenguaje de programación tan amplio como es Visual BASIC.

Indicar también que aunque los lenguajes de programación visuales son

nuevos para el autor de este proyecto, me ha permitido aprender las posibilidades que actualmente se presenta con estos métodos de programación que permiten un interfaz con el usuario mucho más gráfico y versátil.

Como en un principio se plantea este programa de captación como

independiente al de vigilancia decidimos continuar por este camino y desarrollar esta aplicación de captación de fotogramas en tiempo real.

89

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

3.2. Programación en Visual BASIC 6.0. de Microsoft.

El programa de capturar está realizado en un proyecto que incorpora cinco formularios (subfunciones en C), cada uno de ellos es llamado desde en menú principal y se ejecutan al picar sobre el mismo en el menú del programa ejecutable.

Hay que decir que además de estos cinco formularios se utilizan otros

predefinidos tanto para el uso de ficheros y su almacenamiento en memoria como para el uso de la librería videocapx.ocx.

Junto con el código del programa se acompañan comentarios sobre la

utilidad de los comandos y el funcionamiento del compilador y del lenguaje de programación Visual BASIC.(Se añadirán en rojo).

Muchos de los comentarios que se acompañan serán comprendidos al

utilizar el programa ejecutable.

3.2.1. Cuerpo principal. “frmMain”

Muestra la pantalla inicial, los valores que se deben cargar al iniciar el programa y las instrucciones que hay que realizar al picar cada opción del menú que presenta. (Ver 3.3 Manual.1 )

Todos los comandos que contienen la secuencia vcx pertenecen a la

librería ActiveX de captación de imagen. En el anexo 6.5. se incorpora explicación de lo que realiza cada secuencia.

Son los valores iniciales que se cargan al ejecutar el programa. Private Sub Form_Initialize() mnuconn_Click 'conecta camera mnuimagenvivo_Click vcx.PreviewScale = mnuimagenpausa.Checked vcx.CapAbortESCKey = False vcx.CapAbortLeftMouse = True vcx.CapAbortRightMouse = False vcx.CapTimeLimitEnabled = False

90

Proyecto fin de carrera Gonzalo Leandro Bravo

vcx.CaptureAudio = False vcx.HitOKToCapture = True frmMain.StatusBar1.SimpleText = "Listo..." End Sub Private Sub Form_Resize() vcx.Height = frmMain.Height - 900 vcx.Width = frmMain.Width - 72 End Sub Al picar sobre Autor en el menu inicial se hace visible el formulario

frmAutor. Private Sub mnuautor_Click() FrmAutor.Visible = True End Sub Private Sub mnubmp_Click() frmGuardar.Visible = True End Sub Copia un fotograma con el nombre Temp..bmp en el directorio actual de

trabajo. Private Sub mnubmptemp_Click() vcx.SaveFrame ("temp.bmp") End Sub Conecta la cámara y permite a su vez que se pueda desconectar. Private Sub mnuconn_Click() vcx.Connected = True mnuconn.Enabled = False mnudesconn.Enabled = True End Sub Termina cualquier tipo de captación de imágenes, bien sea limitada o

ilimitada en el tiempo. Private Sub mnudetener_Click() frmVigilarlimitada.tmrreloj.Enabled = False frmvigilar.tmrreloj2.Enabled = False frmMain.StatusBar1.SimpleText = "Fin de la vigilancia... " Unload frmvigilar Unload frmVigilarlimitada

91

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

End Sub Copia una imagen al portapapeles Private Sub mnuporta_Click() vcx.CopyFrame End Sub Desconecta la cámara y permite a su vez que se pueda desconectar. Private Sub mnudesconn_Click() vcx.Connected = False mnuconn.Enabled = True mnudesconn.Enabled = False End Sub Private Sub mnuSalir_Click() End End Sub Estos dos formularios hacen variar el metodo de visualización de la

imagen en pantalla, continuo o en pausa. Private Sub mnuimagenpausa_Click() mnuimagenvivo.Checked = False vcx.Preview = False End Sub Private Sub mnuimagenvivo_Click() mnuimagenvivo.Checked = Not mnuimagenvivo.Checked vcx.Preview = mnuimagenvivo.Checked End Sub Private Sub mnuencajar_Click() mnuencajar.Checked = Not mnuencajar.Checked vcx.PreviewScale = mnuencajar.Checked End Sub Formularios predefinidos por videocapx.ocx para variar la fuente de

entrada de video y el formato de video. Private Sub mnuvidformat_Click() vcx.ShowVideoFormatDlg End Sub Private Sub mnuvidsrc_Click()

92

Proyecto fin de carrera Gonzalo Leandro Bravo

vcx.ShowVideoSourceDlg End Sub Private Sub Text1_Validate(Cancel As Boolean) vcx.CapFilename = Text1.Text End Sub Muestran los formularios principales del programa en relación a la

captación de fotogramas. Private Sub mnuvigilar_Click() frmvigilar.Show End Sub Private Sub mnuvigilarlimitada_Click() frmVigilarlimitada.Visible = True End Sub

3.2.2.Guardar BMP en…, “frmguardar” Se presentan varias opciones en este programa para guardar una sola

imagen. Aparen en el menu con el nombre de “copiar imagen”. Podemos copiarlas en el portapales: mnuporta En el fichero Temp..bmp: mnubmptemp O bien con el nombre que nosotros deseemos con el formulario

frmguardar: mnuguardar Los dos primeros son métodos de la librería vcx pero el código del

último es el que se indica a continuación.(Ver 3.3. Manual.7)

La opción cancelar descarga el formulario solicitado, vuelve atrás Option Explicit Private Sub cmdcancelar_Click() Unload Me End Sub

93

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Disponemos de la opción de buscar la ruta que deseamos para almacenar nuestro fichero.bmp, por omisión esta es la de ejecución del programa.

Private Sub cmdruta_Click() dlg.Filter = "BMP files (*.bmp)|*.bmp|All fiels (*.*)|*.*" dlg.DefaultExt = ".bmp" dlg.filename = "" dlg.ShowSave If dlg.filename <> "" Then filename = dlg.filename End If End Sub Guarda en filename el nombre del fichero a guardar.”imagen.bmp” Private Sub Form_Load() filename = "imagen.bmp" End Sub Realiza la campura al pulsar OK Private Sub cmdok_Click() frmMain.vcx.SaveFrame (frmGuardar.filename.Text) Unload Me End Sub

3.2.3. Vigilar. “frmvigilar” Hemos llamado vigilar a esta opción porque es la que deberíamos utilizar

en el momento en que ambas aplicaciones, capturar y vigilar quedasen enlazadas. Este formulario nos almacena en memoria por tiempo ilimitado 10 fotogramas por segundo. Serán los que posteriormente tendremos que analizar para comprobar si hay o no movimiento.(Ver 3.3. Manual.3)

Para entender este formulario es necesario conocer el funcionamiento de

los ‘timers’, objetos que una vez activados repiten su contenido periódicamente hasta que son desactivados.

Declaración de variables. Option Explicit Dim i As Integer

94

Proyecto fin de carrera Gonzalo Leandro Bravo

Dim z As Integer Dim nombre As String Dim archivo As String Private Sub cmdcancelar_Click() Unload Me End Sub Comienza la vigilancia, activo el timer “tmrreloj2” Private Sub cmdok_Click() tmrreloj2.Interval = 100 tmrreloj2.Enabled = False frmMain.StatusBar1.SimpleText = "Vigilando... " z = 1 tmrreloj2.Enabled = True frmMain.vcx.Preview = True frmvigilar.Hide End Sub Declaración de valores iniciales, el timer aparece desactivado Private Sub Form_Load() tmrreloj2.Interval = 90 tmrreloj2.Enabled = False z = 1 End Sub Cuerpo de “tmrreloj2”, que realiza la lectura cada intervalo de 100

milisegundos. Private Sub tmrreloj2_Timer() archivo = "fotograma" & z & ".bmp" frmMain.vcx.SaveFrame (archivo) z = z + 1 End Sub

3.2.4. Vigilancia limitada. “frmvigilarlimitada” Esta opción se ha incorporado para hacer más versátil la aplicación y

permitir su uso como capturadora de imágenes, permitiendo modificar tanto el

95

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

tiempo de captura como el número de fotogramas por segundo capturados. (Ver 3.3. Manual.5)

Definición de variables a utilizar y características de las mismas. Option Explicit Dim i As Integer Dim z As Integer Dim nombre As String Dim archivo As String Controla que sólo se active la lectura distinta del valor predeterminado

10 para número de fotogramas por segundo. Private Sub chkfps_Click() If chkfps.Value = 1 Then txtfps.Enabled = True txtfps.Text = 10 Else: txtfps.Enabled = False txtfps.Text = 10 End If End Sub Controla que sólo se active la lectura distinta del valor predeterminado

15 para tiempo de captación. Private Sub chkparar_Click() If chkparar.Value = 1 Then txtseg.Enabled = True txtseg.Text = 15 Else: txtseg.Enabled = False txtseg.Text = 15 End If End Sub Disponemos de la opción de buscar la ruta que deseamos para almacenar

nuestro fichero.bmp, por omisión esta es la de ejecución del programa. Private Sub cmdruta_Click() dlg.Filter = " Archivos BMP (*.bmp)|*.bmp|Todos (*.*)|*.*" dlg.DefaultExt = ".bmp" dlg.FileName = "" dlg.ShowSave

96

Proyecto fin de carrera Gonzalo Leandro Bravo

If dlg.FileName <> "" Then txtarchivo = dlg.FileName End If End Sub Private Sub cmdcancelar_Click() Unload Me End Sub Valores iniciales que se cargan al activar el formulario, notar que el timer

está desactivado. Private Sub Form_Load() txtarchivo.Text = "imagen.bmp" txtseg.Enabled = False txtfps.Enabled = False txtseg = 15 txtfps = 10 tmrreloj.Interval = Int(900 / txtfps.Text) tmrreloj.Enabled = False z = 1 End Sub Cuando pulso OK se guarda en nombre el nombre asignado sin el punto,

se activa el timer y se oculta el formulario. Private Sub cmdok_Click() tmrreloj.Interval = Int(900 / txtfps.Text) tmrreloj.Enabled = False For i = 1 To Len(txtarchivo) If Mid(txtarchivo.Text, i, 1) = "." Then nombre = Mid(txtarchivo, 1, i - 1) End If Next i frmMain.StatusBar1.SimpleText = "Vigilando... " z = 1 tmrreloj.Enabled = True frmMain.vcx.Preview = True frmVigilarlimitada.Hide End Sub

97

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Cuerpo del timer que guarda los fotogramas con diferentes nombre, para ello utiliza un contador, esta función se debe de desactivar asi misma para evitar que esté funcionando ilimitadamente.

Private Sub tmrreloj_Timer() archivo = nombre & z & ".bmp" frmMain.vcx.SaveFrame (archivo) z = z + 1 If z = (txtseg * txtfps) + 1 Then tmrreloj.Enabled = False frmMain.StatusBar1.SimpleText = "Fin de la vigilancia... " Unload Me End If End Sub

3.2.5. Acerca de..., “frmayuda” Muestra datos sobre el programa. (Ver 3.3. Manual.10)

3.3. Manual Capturadora.

Este manual ha sido realizado mientras en el programa se veian imágenes de la televisión. Una de las ventajas de utilizar los controles ActiveX es que me permite configurar la captadora de imágenes tanto para ver lo que optenemos con la cámara de video como para ver la televisión o una cámara digital.

Al iniciar el programa la pantalla aparece conectada a la tarjeta de datos

y con imagen en vivo. Mantiene la configuración con la que se cerró. Si la cámara está conectada el programa puede configurarse para que al

arrancar aparezca lo que se ve por ella.

98

Proyecto fin de carrera Gonzalo Leandro Bravo

(Imagen Manual.1) Como se puede observar el interfaz con el usuario es idéntico al

empleado por Microsoft. En el menú aparecen cinco opciones.

3.3.1. Menu Archivo.

(Imagen Manual.2)

99

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Nos permite desconectar la cámara sin necesidad de cerar el programa,

con esta opción la pantalla aparece en negro. Al iniciar el programa siempre comenzamos conectados.

3.3.2. Menu Vigilancia.

(Imagen Manual.3) Nos permite acceder a dos posible métodos de captura.

3.3.2.1. Vigilar.

(Imagen Manual.4)

100

Proyecto fin de carrera Gonzalo Leandro Bravo

Nos da paso a una ventana que nos permite realizar por tiempo

ilimitado captación a 10 fotogramas por segundo. Esto está realizado expresamente para trabajar con el programa de vigilancia.

3.3.2.2. Vigilancia limitada.

(Imagen Manual.5) Con esta pantalla podemos realizar capturas modificando tanto el

tiempo de realización como el tiempo entre fotogramas. Se ha indicado como valores por omisión los necesarios para inicializar el sistema.

Los valores de grabación durante 15 segundos a 10 fotogramas

por segundo serán tenidos en cuenta siempre que las opciones de “Detener captura tras” y “Variar Fotogramas por segundo a” aparezcan desmarcadas.

101

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

La tercera opción que nos aparece en el menú vigilancia no despliega ninguna nueva ventana, sino que interrumpe cualquier grabación que esté realizándose en ese momento, bien sea limitada o ilimitada.

3.3.3. Menu CopiarImagen.

(Imagen Manual.6) Copia un solo fotograma BMP en: (De abajo a arriba.) 1.- El portapapeles 2.- En el directorio actual con el nombre temporal.bmp 3.- Donde se le indique con el nombre que se desee utilizando la

siguiente ventana.

(Imagen Manual.7)

102

Proyecto fin de carrera Gonzalo Leandro Bravo

3.3.4. Menu Herramientas.

(Imagen Manual.8) Este menú está integramente formado por opciones pertenecientes a

comandos Actives. Encajar ventana nos permite cambiar el tamaño de la imagen que

vemos por la pantalla del ordenador, hay que tener en cuenta que los recursos requeridos aumentan proporcionalmente con el tamaño de la pantalla. Esta opción se deshabilita marcando nuevamente sobre ella.

Formato video nos permite cambiar el tamaño predefinido de la imagen,

se recomienda utilzar ¼ o ½ . Para que posteriormente estas imágenes se pueden abrir con el programa de vigilancia es necesario que esté marcada la opción 24 bit RGB

103

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

(Imagen Manual.9) Entrada video, en esta ventana podemos cambiar la entrada de video,

pudiendo escoger entre Tuner (TV), Composite(Cámara de video) y Svideo(Monitor).

Aquí podemos también modificar las características luminosas de la imagen. Se acondeja dejarlas en el valor central en cada caso.

(Imagen Manual.10)

104

Proyecto fin de carrera Gonzalo Leandro Bravo

3.3.5. Menu Acerca de.

(Imagen Manual.11) Que muestra la siguiente ventana.

(Imagen Manual.12)

105

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

4.FASE 4. Sistema en tiempo real. Con el estudio que hemos realizado y ambos programas presentados en las dos

fases anteriores conseguimos un sistema que funciona en tiempo no real. Aunque como se puede apreciar en todo momento hemos ido buscando su funcionamiento en tiempo real, en ningún caso hasta esta cuarta fase ambos se han utilizado simultáneamente.

Para conseguir que el sistema funcione en tiempo real y resulte efectiva la

vigilancia hemos de realizar unas pequeñas modificaciones en los ficheros para evitar problemas de lectura por inexistencia de imágenes y utilización de memoria excesiva en disco duro. Los cambios son los que siguen:

1.- La alarma actual consiste en un mensaje que se muestra por pantalla

indicando en qué fotograma aparece el movimiento. 2.- En caso de no estar disponible el fichero para lectura esperamos que este se

encuentre disponible. La ejecución finaliza tras tres segundos sin aparecer ningún nuevo fotograma, tras lo cual se decide que se ha interrumpido la captación (Esto es así si se indica que el número de fotogramas a analizar es N=-1, es decir ilimitado).

3.- Por otro lado las imágenes sin movimiento son borradas de memoria. Para no hacer tan largos los códigos y por su similitud con los anteriormente

mostrados hemos eliminados los comentarios existentes en Matlab.

4.1.”vigilatpr.m”

function vigilatpr [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectpr; umbral=umbral/10000; A=[imagen, num2str(1)]; if sentido=='all' actual=bmpalltpr(A,color); else actual=bmptrozotpr(A,sentido,N1,N2,color); end tamano=length(actual); if tipovig=='igual' if sentido=='all' for I =1:N-1

106

Proyecto fin de carrera Gonzalo Leandro Bravo

B=[imagen, num2str(I+1)]; siguiente=bmpalltpr(B,color); a(I)=sum(abs(actual-siguiente)<valor)/(tamano); actual=siguiente; if a(I)<umbral fprintf(1,'Alarma en el fotograma %i\n',I); else delete([B '.bmp']); end end else for I =1:N-1 B=[imagen, num2str(I+1)]; siguiente=bmptrozotpr(B,sentido,N1,N2,color); a(I)=sum(abs(actual-siguiente)<valor)/(tamano); actual=siguiente; if a(I)<umbral fprintf(1,'Alarma en el fotograma %i\n',I); else delete([B '.bmp']); end end end else if sentido=='all' for I =1:N-1 B=[imagen, num2str(I+1)]; siguiente=bmpalltpr(B,color); a(I) = sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); actual=siguiente; if a(I)<umbral fprintf(1,'Alarma en el fotograma %i\n',I); else delete([B '.bmp']); end end else for I =1:N-1 B=[imagen, num2str(I+1)]; siguiente=bmptrozotpr(B,sentido,N1,N2,color); a(I) = sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente))); actual=siguiente; if a(I)<umbral fprintf(1,'Alarma en el fotograma %i\n',I); else

107

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

delete([B '.bmp']); end end end end

4.2.”lectpr.m”

function [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectpr fid=fopen('camara.txt','rt'); if (fid==-1) fprintf(1,'El fichero de inicializacion no existe, \n'); fprintf(1,'proceda a inicializar el sistema utilizando el programa configurar.\n'); error(['Error abriendo camara.txt para lectura.']); else fallo=0; end; if (nargout~=9) error('Falta algun dato para comenzar el analisis.'); end; imagen=fgetl(fid); if (isstr(imagen)~=1) fallo=1; end; N=fgetl(fid); N=str2num(N); if N==-1 N=10000; end tipovig=fgetl(fid); if (tipovig~='igual') if (tipovig~='simil') fallo=2; end; end; sentido=fgetl(fid); if (sentido~='all') if (sentido~='ver') if (sentido~='hor') fallo=3; end; end; end; umbral=fgetl(fid);

108

Proyecto fin de carrera Gonzalo Leandro Bravo

umbral=str2num(umbral); if (umbral<0|umbral>10000) fallo=4; end; valor=fgetl(fid); valor=str2num(valor); if (valor<0|valor>20) fallo=5; end; N1=fgetl(fid); N1=str2num(N1); N2=fgetl(fid); N2=str2num(N2); if N1>N2 fallo=6; else A=[imagen, num2str(1)]; [YSize, XSize]=dimensiones(A); if (sentido=='ver' & N2>YSize) fallo=6; end if (sentido=='hor' & N2>XSize) fallo=6; end end color=fgetl(fid); color=str2num(color); if (color~=0) if (color~=1) if (color~=2) color=0; fallo=7; end; end; end; fclose(fid); if fallo==0 fprintf(1,'El fichero camara.txt existe, asegurese de que es el deseado\n'); fprintf(1,'Vigilando...\n'); else switch fallo case 1, fprintf(1,'El nombre de los fotogramas ha de ser una cadena de caracteres.\n'); fprintf(1,'Tomaremos valor por defecto imagen.bmp.\n'); imagen='imagen.bmp'; case 2,

109

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

fprintf(1,'El tipo de analisis ha de ser "igual" o "simil".\n'); fprintf(1,'Tomaremos valor por defecto simil.\n'); tipovig='simil'; case 3, fprintf(1,'El tipo de analisis ha de ser "all", "ver" o "hor".\n'); fprintf(1,'Tomaremos valor por defecto all.\n'); sentido='all'; case 4, fprintf(1,'El valor del umbral se debe encontrar entre 0 y 100.\n'); fprintf(1,'Tomaremos valor por defecto 9900.\n') umbral=9900; case 5, fprintf(1,'El valor del valor se debe encontrar entre 0 y 20.\n'); fprintf(1,'Tomaremos valor por defecto 15.\n') valor=15; case 6, fprintf(1,'El valor de N2 ha de ser mayor que el de N1 y estar dentro de los limites de la imagen.\n'); fprintf(1,'Revise el fichero de inicio.\n'); fprintf(1,'Los valores de la imagen deben de estar comprendidos entre %i y %i.\n',YSize,XSize) fprintf(1,'Realizaremos un analisis total de la imagen.\n'); sentido='all'; case 7, fprintf(1,'Error en la eleccion del color tomaremos Rojo por defecto'); color=0; otherwise, fprintf(1,'WARNING: Es posible que haya algun error en camara.txt, asegurese de que es el deseado\n'); fprintf(1,'Vigilando...\n'); end end

4.3.”bmpalltpr.m”

function [X]=bmpalltpr(nombrefich,color); if (nargin~=2) error('Requiere un nombre de fichero como argumento y el color a utilizar.'); end;

110

Proyecto fin de carrera Gonzalo Leandro Bravo

if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; aux=1; fid=fopen(nombrefich,'rb','l'); if (fid==-1) fprintf(1,'Esperando fichero %s\n',nombrefich); while (fid==-1) for i=1:50000, end aux=aux+1; if aux==100 fprintf(1,'Fin de ejecución por falta de imágenes\n'); error(['Error abriendo ',nombrefich,' para lectura']); end fid=fopen(nombrefich,'rb','l'); end end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint');

111

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; fseek(fid, bfOffBytes+color, 'bof'); X=fread(fid,Size,'uchar',2); fclose(fid); return; end

4.4.”bmptrozotpr.m”

function [X]=bmptrozotpr(nombrefich,direccion,N1,N2,color); if (nargin~=5) error('Requiere un nombre de fichero como argumento,la franja a analizar y el color deseado.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; aux=1; fid=fopen(nombrefich,'rb','l'); if (fid==-1) fprintf(1,'Esperando fichero %s\n',nombrefich); while (fid==-1) for i=1:50000, end aux=aux+1; if aux==100 fprintf(1,'Fin de ejecución por falta de imágenes\n'); error(['Error abriendo ',nombrefich,' para lectura']); end fid=fopen(nombrefich,'rb','l'); end end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid);

112

Proyecto fin de carrera Gonzalo Leandro Bravo

error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint'); if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; Size=XSize*YSize; fseek(fid, bfOffBytes+color, 'bof'); if direccion=='hor' fseek(fid,XSize*(YSize-N2)*3,0); X=fread(fid,XSize*(N2-N1+1),'uchar',2); end if direccion=='ver' fseek(fid,(N1-1)*3,0); X=fread(fid,(N2-N1+1),'uchar',2); for I=1:YSize-1 fseek(fid,(XSize-(N2-N1+1))*3,0); Y=fread(fid,(N2-N1+1),'uchar',2); X=[X ;Y]; end end fclose(fid); return; end

113

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

4.5.”lectpr.m”

function [YSize,XSize]=dimensiones(nombrefich); if (nargin~=1) error('Requiere un nombre de fichero como argumento y el color a utilizar.'); end; if (isstr(nombrefich)~=1) error('Requiere una cadena de caracteres como nombre del fichero.'); end; if (isempty(findstr(nombrefich,'.'))==1) nombrefich=[nombrefich,'.bmp']; end; fid=fopen(nombrefich,'rb','l'); if (fid==-1) error(['Error abriendo ',nombrefich,' para lectura']); end; bfType=fread(fid,2,'uchar'); if (bfType~=[66;77]) fclose(fid); error('No es un fichero BMP.'); end; bfSize=fread(fid,1,'uint'); bfReserved1=fread(fid,1,'ushort'); bfReserved2=fread(fid,1,'ushort'); bfOffBytes=fread(fid,1,'uint'); biSize=fread(fid,1,'uint'); if (biSize~=40) fclose(fid); error('No es un fichero MS Windows Device Bitmap BMP.'); end; biWidth=fread(fid,1,'uint'); biHeight=fread(fid,1,'uint'); biPlanes=fread(fid,1,'ushort'); biBitCount=fread(fid,1,'ushort'); biCompression=fread(fid,1,'uint'); if biCompression~=0 error('No puede leer ficheros BMP comprimidos.'); end; biSizeImage=fread(fid,1,'uint'); biXPels=fread(fid,1,'uint'); biYPels=fread(fid,1,'uint'); biClrUsed=fread(fid,1,'uint'); biClrImportant=fread(fid,1,'uint');

114

Proyecto fin de carrera Gonzalo Leandro Bravo

if (biBitCount == 24) if (rem(biWidth,4)~=0) XSize=biWidth+(4-rem(biWidth,4)); else XSize=biWidth; end YSize=biHeight; fclose(fid); return; end

115

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

5. Conclusiones.

El programa cuyo código aparece en el apartado anterior en lenguaje Matlab es

la versión definitiva de este proyecto fin de carrera aunque se ha optado por no presentar el código en C y el ejecutable por no considerar esta opción de vigilancia y seguridad conjunta funcionalmente útil.

El sistema SÍ funciona, pero se recomienda en caso de desear su utilización en

un sistema de seguridad real la integración de ambos en uno solo, para lo cual consideramos de debería utilizar como base el programa de captación de Visual BASIC y añadirle el sistema de vigilancia teniendo en cuenta todo lo mostrado anteriormente. De esta manera conseguiríamos aumentar la velocidad de análisis al no tener que leer las imágenes de memoria.

Llegados a este punto resumiremos todo lo que cualquier lector de este proyecto

se ha encontrado en las páginas anteriores. Aunque no se ha conseguido una aplicación completa de un sistema de vigilancia se ha realizado un estudio sobre análisis de movimientos en la fase 1, estudio de tiempos de ejecución y de acceso a ficheros bmp en la fase 2, se ofrecen los códigos fuentes tanto en Matlab como en C del sistema de inicialización y vigilancia y el código fuente del programa de captación de Visual BASIC.

Además de todo esto a este proyecto se acompañan cuatro ejecutables en disco

adjunto: 1. -Sistema de comparación de fotogramas por sistema óptimo para la detección

de movimiento. 2. -Sistema de captación en tiempo real de fotogramas a través de cámara

doméstica. Existen versiones similares de este programa en Internet, pero están destinados a capturar videos que podemos posteriormente convertir en fotogramas, no existe ningún programa que nos permita realizar lo que nosotros hemos conseguido: Capturar hasta 50 fotogramas por segundo en tiempo real.

3.- Sistema de inicialización de la cámara para optimización de la vigilancia. 4.-Conjunto de funciones de matlab que ejecutados conjuntamente con el

programa de captación nos realiza tareas de vigilancia.

116

Proyecto fin de carrera Gonzalo Leandro Bravo

Por todo lo expuesto anteriormente podemos afirmar casi son absoluta certeza la

posibilidad de idear un sistema de vigilancia que a través de un PC controle y compruebe la existencia de movimiento en las imágenes analizando su contenido.

El tiempo requerido en comprobar el movimiento, sin tener en cuenta la lectura

en disco de los fotogramas bmp, es considerablemente pequeño y el sistema de análisis por franjas efectivo.

Como puntos en los que se pudiera realizar una continuación en este proyecto ya

se dejó entrever de posibilidad de realizar una versión mejorada del sistema de captación que incluyera comparación de imágenes para de esta manera conseguir un sistema de vigilancia eficaz y un interfaz con el usuario gráfico.

Todo lo planteado nos lleva a considerar la posibilidad de analizar con éxito el

tratamiento de múltiples cámaras reduciendo el número de fotogramas en cada una de ellas. Aquí aparecería otro problema a solucionar, la necesidad de disponer de todas ellas en memoria simultáneamente para poder procesarlas. Como posible solución se podría plantear la modulación en diferentes canales de cada una de las imágenes ofrecidas por las cámaras.

A quien pudiera interesar continuar con lo que aquí he expuesto en forma de

proyecto de fin de carrera quedaría encantado en colaborar aportando mis conocimientos sobre el sistema desarrollado, puede ponerse en contacto conmigo a través de la dirección de correos [email protected].

Aunque los sistemas de seguridad deberían ser innecesarios en algunas

ocasiones nunca está de más recordar algunas... MEDIDAS PRECAUTORIAS A TENER EN CUENTA

• Mantener la puerta de entrada de su casa cerrada con llave las 24 horas. • Mantener cerrada con llave las puertas de acceso a terrazas. • En horario nocturno, iluminar adecuadamente cocheras, sótanos y

terrazas. • Los vehículos estacionados en las cocheras deberán estar cerrados ,

evitando dejar en su interior objetos de valor.

117

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

• Abra la puerta de su vivienda recién cuando haya identificado al requirente por la mirilla. Los empleados de las empresas de servicios, correos, TV por cable, etc, deberán acreditarse exhibiendo su credencial.

• Evite ingresar a los ascensores con personas extrañas o que le resulten sospechosas.

• Evite que personas extrañas ingresen o circulen por el edificio sin ser controladas.

• Evite que los niños viajen solos en los ascensores. Podrían sufrir algún accidente.

• Cuando solicite encargos a domicilio, recíbalos en la puerta del edificio. No abra cuando pretendan llevar un recado para un vecino.

• No coloque nombres, direcciones, o números de teléfono en los llaveros pues si los pierde pueden ser hallados por delincuentes.

• Cuando se ausente de su domicilio, disminuya el volumen de la campanilla de su teléfono.

• Si sospecha que lo están siguiendo camino a casa desvíese de la dirección de su domicilio y solicite ayuda.

• Cuando llegue a su domicilio hágalo con la llave en la mano. No comience a buscarla parado frente a la puerta del edificio.

• No esconda una copia de las llaves en algún lugar del palier cercano a la entrada de su departamento. Es conveniente dejar una llave extra a un vecino de confianza.

• Cuando esté por ingresar al garaje del edificio con su automóvil, pase de largo si advierte la presencia de personas sospechosas en las proximidades del portón de garaje.

• Nunca coloque carteles como "No estoy", "Vuelvo en 5 minutos", etc. • Nunca guarde sumas importantes de dinero o joyas en su departamento.

De hacerlo, jamás lo comente con nadie. • Los encargados de edificio al limpiar las aceras deben hacerlo

manteniendo cerrada con llave la puerta del edificio. • Si observa que por debajo de la puerta de su departamento entra agua o

humo, no abra sin cerciorarse de quién se encuentra al otro lado de la puerta.

Muchas gracias por conseguir llegar hasta este punto de lectura. Gonzalo Leandro.

118

Proyecto fin de carrera Gonzalo Leandro Bravo

6. ANEXOS

6.1 Ayuda del comando fread

FREAD Read binary data from file. [A, COUNT] = FREAD(FID,SIZE,PRECISION) reads binary data

from the specified file and writes it into matrix A. Optional output argument COUNT returns the number of elements successfully read.

FID is an integer file identifier obtained from FOPEN. The size argument is optional; if not specified, the entire file is read; if specified, valid entries are: N read N elements into a column vector. inf read to the end of the file. [M,N] read elements to fill an M-by-N matrix, in column order.

N can be inf, but M can't. The precision argument controls the number of bits read for each value

and the interpretation of those bits as character, integer or floating point values. Any of the following strings, either the MATLAB versions, or their C or Fortran equivalents, may be used. If not specified, the default is 'uchar'. By default, numeric values are returned in double precision arrays.

MATLAB C or Fortran Description 'uchar' 'unsigned char' unsigned character, 8 bits. 'schar' 'signed char' signed character, 8 bits. 'int8' 'integer*1' integer, 8 bits. 'int16' 'integer*2' integer, 16 bits. 'int32' 'integer*4' integer, 32 bits. 'int64' 'integer*8' integer, 64 bits. 'uint8' 'integer*1' unsigned integer, 8 bits. 'uint16' 'integer*2' unsigned integer, 16 bits. 'uint32' 'integer*4' unsigned integer, 32 bits. 'uint64' 'integer*8' unsigned integer, 64 bits. 'single' 'real*4' floating point, 32 bits. 'float32' 'real*4' floating point, 32 bits. 'double' 'real*8' floating point, 64 bits. 'float64' 'real*8' floating point, 64 bits. The following platform dependent formats are also supported but

they are not guaranteed to be the same size on all platforms. 'char' 'char*1' character, 8 bits (signed or unsigned). 'short' 'short' integer, 16 bits. 'int' 'int' integer, 32 bits. 'long' 'long' integer, 32 or 64 bits.

119

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

'ushort' 'unsigned short' unsigned integer, 16 bits. 'uint' 'unsigned int' unsigned integer, 32 bits. 'ulong' 'unsigned long' unsigned integer, 32 bits or 64 bits. 'float' 'float' floating point, 32 bits. The following formats map to an input stream of bits rather than

bytes. 'bitN' signed integer, N bits (1<=N<=64). 'ubitN' unsigned integer, N bits (1<=N<=64). The PRECISION string may contain a positive integer repetition factor

of the form 'N*' which prepends one of the strings above, like '40*uchar'. For example, fid = fopen('fread.m','r'); F = fread(fid); s = setstr(F') opens the file containing this HELP entry, then reads and displays

the entire file, using default size = inf and precision = 'uchar'. The resulting length(F) is the number of characters in the file.

[A, COUNT] = FREAD(FID,SIZE,PRECISION,SKIP) includes an

optional SKIP argument that specifies the number of bytes to skip after each PRECISION value is read. With the SKIP argument present, FREAD reads in one value and does a skip of input, reads in another value and does a skip of input, etc. for at most SIZE times. If PRECISION is a bit format like 'bitN' or 'ubitN' SKIP is specified in bits.

This is useful for extracting data in noncontiguous fields from fixed length records.

6.2 Ayuda del comando fseek FSEEK Set file position indicator. STATUS = FSEEK(FID, OFFSET, ORIGIN) repositions the file

position indicator in the file with the given FID to the byte with the specified OFFSET relative to ORIGIN. FID is an integer file identifier obtained from FOPEN. OFFSET values are interpreted as follows: > 0 Move toward the end of the file. = 0 Do not change position. < 0 Move toward the beginning of the file.

120

Proyecto fin de carrera Gonzalo Leandro Bravo

ORIGIN values are interpreted as follows: 'bof' or -1 Beginning of file 'cof' or 0 Current position in file 'eof' or 1 End of file STATUS is 0 on success and -1 on failure. If an error occurs use FERROR to get more information. Example: fseek(fid,0,-1) "rewinds" the file.

6.3. Ayuda del compilador de Matlab MCC MATLAB to C/C++ Compiler (Version 2.0). MCC [-options] fun [fun2 ... ] Translate fun.m to fun.c or fun.cpp, and optionally create any

supported binary file. Write any resulting files into the current directory, by default. If more than one M-file is specified, a C or C++ file is generated for each M-file. If C files are specified, they are passed to MEX or MBUILD along with any generated C files. If conflicting options are presented to MCC, the rightmost conflicting option is used.

NOTE to Compiler 1.2 users: The options for Compiler 2.0 are

somewhat different from Compiler 1.2. Type "mcc -V1.2 -?" to obtain the online help for Compiler 1.2.

In order to assist in migrating to this new release, we have prepared a

quick-reference card which contains both the Compiler 1.2.1 and the Compiler 2.0 options. You can access this pdf file by selecting "Online Manuals" from the HELPDESK.

OPTIONS: A <keyword>:<setting> Specify annotation. <keyword> can be one of

"annotation", "line", or "debugline". "annotation" specifies how much of the source M-file the Compiler should write into the generated output file as comments. The <setting> following "annotation" can be "all" (default), "comments", or "none", specifying all M-code, only M-code comments, and no M-code respectively. "line" specifies the presence or absence of #line directives which map lines in a generated C/C++ file to corresponding lines in the source M-file. The <setting> following "line" can be "off" (default), or "on", specifying absence or presence of #line directives. "debugline" specifies whether error messages report the source file name and line number. The <setting>

121

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

following "debugline" can be "off" (default), or "on", specifying the absence or presence of source file and line number information in run-time error messages.

B <filename> Specify bundle file. <filename> is a text file containing

Compiler command line options. The Compiler behaves as if the "-B <filename>" were replaced by the contents of the bundle file. Newlines appearing in these files are allowed and are treated as whitespace.

c C only. Translate M-file to C, but do not produce a MEX-file or

stand-alone application. This is equivalent to "-T codegen" as the rightmost argument on the command line.

d <directory> Output directory. All generated files will be put in

<directory>. F list. List the <option>s available in the next form of the command,

together with their current values and a short explanation. F <option>:<number> Typesetting format options. Assign the value

<number> to the formatting option <option>. See "F list" for <option>s. f <filename> Use the specified options file when calling MEX or

MBUILD. This allows you to use different ANSI compilers. This option is a direct pass-through to the MEX or MBUILD script. See the "Application Program Interface Guide" for more information.

g Debug. Include debugging symbol information. h Compile helper functions by default. Any M-functions called will be

compiled into the resulting MEX-file or stand-alone application. I <path> Include path. Add <path> to the list of paths to search for M-

files. The MATLAB path is automatically included when running from

MATLAB, but NOT when running from DOS or the Unix shell. See "help mccsavepath".

L <option> Language. Specifies target language. <option> can be

either "C" for C or "Cpp" for C++. l Line. Generates code that reports file name and line numbers on

run-time errors. (Equivalent to -A debugline:on) m Macro that generates a C stand-alone application. This is

equivalent to "-t -W main -L C -h -T link:exe". Note: the "-h" means that helper functions will be included.

M "<string>" Pass <string> to the MBUILD or MEX script used to

build an executable. If -M is used multiple times, the rightmost occurrence is used.

122

Proyecto fin de carrera Gonzalo Leandro Bravo

o <outputfilename> Output name. Set the name of the final executable

output (MEX or stand-alone application) to <outputfilename>. A suitable, possibly platform-dependent, extension is added to <outputfilename> (e.g., ".exe" for PC stand-alone applications, ".mexsol" for Solaris MEX-files).

p Macro that generates C++ stand-alone application. This is

equivalent to "-t -W main -L Cpp -h -T link:exe". Note: the "-h" means that helper functions will be included.

S Macro that generates Simulink C-MEX S-Function. This is

equivalent to "-t -W simulink -L C -T link:mex". Note: the absence of "-h" means that helper functions will not be included.

t Translate M code to target language. Translate any M-functions

specified on the command line to C or C++ functions. This option is included in all macro options. Omitting it allows the generation of wrapper C/C++ files without generating the C/C++ files corresponding to M-files.

T <option> Specify target phase. <option> must be "codegen",

"compile:<bintype>", "link:<bintype>", or "lib:<bintype>", where <bintype> must be one of "mex", "exe", or "lib". If <option> is "codegen", the Compiler stops after performing M-to-C/C++ translation and wrapper file generation. If <option> starts with "compile:", the Compiler performs the previous step and then compiles the C/C++ file(s) into object file(s). The built object file(s) are suitable for linking into a MEX-file if <bintype> is "mex", into a stand-alone application if <bintype> is "exe", or into a shared library if <bintype> is "lib". If <option> begins with "link:", the Compiler performs both previous steps and then links the object code into a MEX-file (if <bintype> is "mex"), a stand-alone application (if <bintype> is "exe"), or a shared library (if <bintype> is "lib").

u <number> Specify that the number of inputs to a generated Simulink

S-function should be <number>. Valid only if either "-S" or "-W simulink" option has also been specified.

v Verbose. Show compilation steps. V1.2 Access Compiler 1.2.1. The options described in this text are for

Compiler 2.0 only. Type "mcc -V1.2 -?" to obtain the online help for Compiler 1.2.1.

w list. List the <msg> strings allowed in the next form of the

command, together with the full text of the warning messages to which they correspond.

w <option>[:<msg>] Warnings. The possible options are "enable",

"disable", and "error". If "enable:<msg>" or "disable:<msg>" is specified, enable or disable the warning associated with <msg>. If "error:<msg>" is specified, enable the warning associated with <msg> and treat any instances of

123

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

that warning as an error. If the <option> but not ":<msg>" is specified, the Compiler applies the action to all warning messages. For compatibility with Compiler 1.2, "-w" (with no option) is the same as "-w enable".

W <option> Wrapper functions. Specify which type of wrapper file

should be generated by the Compiler. <option> can be one of "mex", "main", "simulink", "lib:<string>", or "none" (default). For the lib wrapper, <string> contains the name of the generated header, source and exports file.

x Macro that generates a MEX file. This is equivalent to "-t -W mex

-L C -T link:mex". Note: the absence of "-h" means that helper functions will not be included.

y <number> Specify that the number of outputs from a generated

Simulink S-function should be <number>. Valid only if either "-S" or "-W simulink" option has also been specified.

Y <license.dat file> Override default license.dat file with specified

argument. z <path> Specify the path to use for library and include files. This

option uses the specified path for the Compiler libraries instead of MATLABROOT.

? Help. Display this help message. EXAMPLES: Make a C translation and a MEX-file for myfun.m: mcc -x myfun Make a C translation and a stand-alone executable for myfun.m: mcc -m myfun Make a C++ translation and a stand-alone executable for myfun.m: mcc -p myfun Make a C translation and a Simulink S-function for myfun.m (using dynamically sized inputs and outputs): mcc -S myfun Make a C translation and a Simulink S-function for myfun.m (explicitly calling for one input and two outputs): mcc -S -u 1 -y 2 myfun Make a C translation and stand-alone executable for myfun.m. Look

for myfun.m in the directory /files/source, and put the resulting C files and executable in the directory /files/target:

mcc -m -I /files/source -d /files/target myfun

124

Proyecto fin de carrera Gonzalo Leandro Bravo

Make a C translation and a MEX-file for myfun.m. Also translate and include all M-functions called directly or indirectly by myfun.m. Incorporate the full text of the original M-files into their corresponding C files as C comments:

mcc -x -h -A annotation:all myfun Make a generic C translation of myfun.m: mcc -t -L C myfun Make a generic C++ translation of myfun.m: mcc -t -L Cpp myfun Make a C MEX wrapper file from myfun1.m and myfun2.m: mcc -W mex -L C myfun1 myfun2 Make a C translation and a stand-alone executable from myfun1.m and

myfun2.m (using one mcc call): mcc -m myfun1 myfun2 Make a C translation and a stand-alone executable from myfun1.m and

myfun2.m (by generating each output file with a separate mcc call): mcc -t -L C myfun1 % yields myfun1.c mcc -t -L C myfun2 % yields myfun2.c mcc -W main -L C myfun1 myfun2 % yields myfun1_main.c mcc -T compile:exe myfun1.c % yields myfun1.o mcc -T compile:exe myfun2.c % yields myfun2.o mcc -T compile:exe myfun1_main.c % yields myfun1_main.o mcc -T link:exe myfun1.o myfun2.o myfun1_main.o Note: on PCs, filenames ending with .o above would actually end

with .obj.

6.4. Códigos fuente en C de programa de vigilancia. 6.4.1. vigila.c /* * MATLAB Compiler: 2.0 * Date: Mon Nov 19 19:21:13 2001 * Arguments: "-m" "vigila" */ #include "vigila.h"

125

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

#include "bmpallrap.h" #include "bmptrozorap.h" #include "lectot.h" /* * The function "Mvigila" is the implementation version of the "vigila" * M-function from file * "D:\escuela\Matlab\work\funcionaC\definitivo\seguridad\vigila.m"

(lines * 1-94). It contains the actual compiled code for that M-function. It is a * static function and must only be called from one of the interface

functions, * appearing below. */ /* * function vigila */ static void Mvigila(void) { mxArray * A = mclGetUninitializedArray(); mxArray * B = mclGetUninitializedArray(); mxArray * I = mclGetUninitializedArray(); mxArray * N = mclGetUninitializedArray(); mxArray * N1 = mclGetUninitializedArray(); mxArray * N2 = mclGetUninitializedArray(); mxArray * a = mclGetUninitializedArray(); mxArray * actual = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * color = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mxArray * imagen = mclGetUninitializedArray(); mclForLoopIterator iterator_0; mxArray * sentido = mclGetUninitializedArray(); mxArray * siguiente = mclGetUninitializedArray(); mxArray * tamano = mclGetUninitializedArray(); mxArray * tipovig = mclGetUninitializedArray(); mxArray * umbral = mclGetUninitializedArray(); mxArray * valor = mclGetUninitializedArray(); /* * %vigila * %los parametros de encuentra inicializados en camara.txt, * %vigila lee de camara.txt los datos necesariosa para el analisis, * %calcula cambio en las imágenes y escribe en intruso.txt los

fotogramas que han cambiado. * %Posteriormente borra los fotogramas en los que no ha habido

cambio. * %con delete borro dondehaya movimiento * * [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectot; */ mlfAssign(

126

Proyecto fin de carrera Gonzalo Leandro Bravo

&imagen, mlfNLectot(9, &N, &tipovig, &sentido, &umbral, &valor, &N1,

&N2, &color)); /* * * umbral=umbral/10000; */ mlfAssign(&umbral, mlfMrdivide(umbral, mlfScalar(10000.0))); /* * %Esta funcion toma imagen completa o solo un trozo de la misma. * A=[imagen, num2str(1)]; */ mlfAssign(&A, mlfHorzcat(imagen, mlfNum2str(mlfScalar(1.0),

NULL), NULL)); /* * if sentido=='all' */ if (mlfTobool(mlfEq(sentido, mxCreateString("all")))) { /* * %la imagen va en rojo y en un solo vector. * actual=bmpallrap(A,color); */ mlfAssign(&actual, mlfBmpallrap(A, color)); /* * * else */ } else { /* * %calculo el tamano de la imagen que voy a analizar * %comprobar que se cumple que los dos son menores que los unos * actual=bmptrozorap(A,sentido,N1,N2,color); */ mlfAssign(&actual, mlfBmptrozorap(A, sentido, N1, N2, color)); /* * * end */ } /* * tamano=length(actual); */ mlfAssign(&tamano, mlfLength(actual)); /* * fid=fopen('intruso.txt','wt'); */ mlfAssign( &fid, mlfFopen(

127

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

NULL, NULL, mxCreateString("intruso.txt"), mxCreateString("wt"), NULL));

/* * if (fid==-1) */ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo intruso.txt para escribir.']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo intruso.txt para escribir."),

NULL)); /* * end; */ } /* * %Con estos bucles aumento el codigo pero me quedo dentro de una

de ellos durante la vigilancia. * if tipovig=='igual' */ if (mlfTobool(mlfEq(tipovig, mxCreateString("igual")))) { /* * if sentido=='all' */ if (mlfTobool(mlfEq(sentido, mxCreateString("all")))) { /* * for I =1:N-1 */ for (mclForStart( &iterator_0, mlfScalar(1.0), mlfMinus(N, mlfScalar(1.0)), NULL); mclForNext(&iterator_0, &I); ) { /* * %Analisis por igualdad +-valor de la imagen completa. * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL), NULL)); /* * siguiente=bmpallrap(B,color); */

128

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(&siguiente, mlfBmpallrap(B, color)); /* * a(I)=sum(abs(actual-siguiente)<valor)/(tamano); */ mlfIndexAssign( &a, "(?)", I, mlfMrdivide( mlfSum( mlfLt(mlfAbs(mlfMinus(actual, siguiente)), valor),

NULL), tamano)); /* * actual=siguiente; */ mlfAssign(&actual, siguiente); /* * if a(I)<umbral */ if (mlfTobool(mlfLt(mlfIndexRef(a, "(?)", I), umbral))) { /* * fprintf(fid,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( fid, mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * fprintf(1,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * end */ } /* * end */ } /*

129

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* else */ } else { /* * for I =1:N-1 */ for (mclForStart( &iterator_0, mlfScalar(1.0), mlfMinus(N, mlfScalar(1.0)), NULL); mclForNext(&iterator_0, &I); ) { /* * %Analisis por igualdad +-valor de lineas de la imagen. * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL), NULL)); /* * siguiente=bmptrozorap(B,sentido,N1,N2,color); */ mlfAssign( &siguiente, mlfBmptrozorap(B, sentido, N1, N2, color)); /* * a(I)=sum(abs(actual-siguiente)<valor)/(tamano); */ mlfIndexAssign( &a, "(?)", I, mlfMrdivide( mlfSum( mlfLt(mlfAbs(mlfMinus(actual, siguiente)), valor),

NULL), tamano)); /* * actual=siguiente; */ mlfAssign(&actual, siguiente); /* * if a(I)<umbral */ if (mlfTobool(mlfLt(mlfIndexRef(a, "(?)", I), umbral))) { /* * fprintf(fid,'Alarma en el fotograma %i\n',I);

130

Proyecto fin de carrera Gonzalo Leandro Bravo

*/ mclAssignAns( &ans, mlfFprintf( fid, mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * fprintf(1,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * end */ } /* * end */ } /* * end */ } /* * else */ } else { /* * if sentido=='all' */ if (mlfTobool(mlfEq(sentido, mxCreateString("all")))) { /* * for I =1:N-1 */ for (mclForStart( &iterator_0, mlfScalar(1.0), mlfMinus(N, mlfScalar(1.0)), NULL); mclForNext(&iterator_0, &I); ) { /* * %Analisis por comparacion de la imagen completa.

131

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL), NULL)); /* * siguiente=bmpallrap(B,color); */ mlfAssign(&siguiente, mlfBmpallrap(B, color)); /* * %modificacion de corr2.m en la que no restamos la media,

de esta manera evitamos * %problemas con las zonas de un solo tono. * a(I) =

sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente)));

*/ mlfIndexAssign( &a, "(?)", I, mlfMrdivide( mlfSum(mlfSum(mlfTimes(actual, siguiente), NULL),

NULL), mlfSqrt( mlfMtimes( mlfSum(mlfSum(mlfTimes(actual, actual), NULL),

NULL), mlfSum( mlfSum(mlfTimes(siguiente, siguiente), NULL), NULL))))); /* * %Suponemos que este fichero no debe dar error pues solo es

llamado desde dentro * %de un bucle donde conocemos las funciones que vamos a

enviar como parametro * actual=siguiente; */ mlfAssign(&actual, siguiente); /* * if a(I)<umbral */ if (mlfTobool(mlfLt(mlfIndexRef(a, "(?)", I), umbral))) { /* * fprintf(fid,'Alarma en el fotograma %i\n',I); */ mclAssignAns(

132

Proyecto fin de carrera Gonzalo Leandro Bravo

&ans, mlfFprintf( fid, mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * fprintf(1,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * end */ } /* * end */ } /* * else */ } else { /* * for I =1:N-1 */ for (mclForStart( &iterator_0, mlfScalar(1.0), mlfMinus(N, mlfScalar(1.0)), NULL); mclForNext(&iterator_0, &I); ) { /* * %Analisis por comparacion de lineas de la imagen. * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL), NULL)); /* * siguiente=bmptrozorap(B,sentido,N1,N2,color);

133

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ mlfAssign( &siguiente, mlfBmptrozorap(B, sentido, N1, N2, color)); /* * a(I) =

sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente)));

*/ mlfIndexAssign( &a, "(?)", I, mlfMrdivide( mlfSum(mlfSum(mlfTimes(actual, siguiente), NULL),

NULL), mlfSqrt( mlfMtimes( mlfSum(mlfSum(mlfTimes(actual, actual), NULL),

NULL), mlfSum( mlfSum(mlfTimes(siguiente, siguiente), NULL), NULL))))); /* * actual=siguiente; */ mlfAssign(&actual, siguiente); /* * if a(I)<umbral */ if (mlfTobool(mlfLt(mlfIndexRef(a, "(?)", I), umbral))) { /* * fprintf(fid,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( fid, mxCreateString("Alarma en el fotograma %i\\n"), I, NULL)); /* * fprintf(1,'Alarma en el fotograma %i\n',I); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Alarma en el fotograma %i\\n"), I, NULL));

134

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * end */ } /* * end */ } /* * end */ } /* * end */ } /* * * * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); mxDestroyArray(A); mxDestroyArray(B); mxDestroyArray(I); mxDestroyArray(N); mxDestroyArray(N1); mxDestroyArray(N2); mxDestroyArray(a); mxDestroyArray(actual); mxDestroyArray(ans); mxDestroyArray(color); mxDestroyArray(fid); mxDestroyArray(imagen); mxDestroyArray(sentido); mxDestroyArray(siguiente); mxDestroyArray(tamano); mxDestroyArray(tipovig); mxDestroyArray(umbral); mxDestroyArray(valor); /* * * * * %El tiempo de ejecuciion se pierde en abrir el fichero bmp pues

aunque analice el mismo trozo se tarda mucho mas * %cuando el fichero es de mayor tamaño */ }

135

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

/* * The function "mlfVigila" contains the normal interface for the "vigila" * M-function from file * "D:\escuela\Matlab\work\funcionaC\definitivo\seguridad\vigila.m"

(lines * 1-94). This function processes any input arguments and passes them to

the * implementation version of the function, appearing above. */ void mlfVigila(void) { mlfEnterNewContext(0, 0); Mvigila(); mlfRestorePreviousContext(0, 0); } /* * The function "mlxVigila" contains the feval interface for the "vigila" * M-function from file * "D:\escuela\Matlab\work\funcionaC\definitivo\seguridad\vigila.m"

(lines * 1-94). The feval function calls the implementation version of vigila

through * this function. This function processes any input arguments and passes

them * to the implementation version of the function, appearing above. */ void mlxVigila(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) { if (nlhs > 0) { mlfError( mxCreateString( "Run-time Error: File: vigila Line: 1 Column: " "0 The function \"vigila\" was called with mor" "e than the declared number of outputs (0)")); } if (nrhs > 0) { mlfError( mxCreateString( "Run-time Error: File: vigila Line: 1 Column: " "0 The function \"vigila\" was called with mor" "e than the declared number of inputs (0)")); } mlfEnterNewContext(0, 0); Mvigila(); mlfRestorePreviousContext(0, 0); }

136

Proyecto fin de carrera Gonzalo Leandro Bravo

6.4.2. vigila_main.c /* * MATLAB Compiler: 2.0 * Date: Thu Nov 22 17:34:39 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #include "matlab.h" #include "N1N2.h" #include "lectot.h" #include "bmptrozorap.h" #include "bmpallrap.h" #include "vigila.h" static mlfFunctionTableEntry function_table[5] = { { "N1N2", mlxN1N2, 1, 2 }, { "lectot", mlxLectot, 0, 9 }, { "bmptrozorap", mlxBmptrozorap, 5, 1 }, { "bmpallrap", mlxBmpallrap, 2, 1 }, { "vigila", mlxVigila, 0, 0 } }; /* * The function "main" is a Compiler-generated main wrapper, suitable

for * building a stand-alone application. It initializes a function table for use * by the feval function, and then calls the function "mlxVigila". Finally,

it * clears the feval table and exits. */ int main(int argc, const char * * argv) { mxArray * varargin = mclInitialize(NULL); mlfEnterNewContext(0, 0); mlfFunctionTableSetup(5, function_table); mlfAssign(&varargin, mclCreateCellFromStrings(argc - 1, argv + 1)); mlfFeval( mclAnsVarargout(), mlxVigila, mlfIndexRef(varargin, "{?}", mlfCreateColonIndex()), NULL); mxDestroyArray(varargin); mlfFunctionTableTakedown(5, function_table); mlfRestorePreviousContext(0, 0); return 0; }

137

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

6.4.3. lectot.c /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #include "lectot.h" #include "N1N2.h" /* * The function "Mlectot" is the implementation version of the "lectot" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\lectot.m" * (lines 1-158). It contains the actual compiled code for that M-function.

It * is a static function and must only be called from one of the interface * functions, appearing below. */ /* * function [imagen,N,tipovig,sentido,umbral,valor,N1,N2,color]=lectot */ static mxArray * Mlectot(mxArray * * N, mxArray * * tipovig, mxArray * * sentido, mxArray * * umbral, mxArray * * valor, mxArray * * N1, mxArray * * N2, mxArray * * color, int nargout_) { mxArray * imagen = mclGetUninitializedArray(); mxArray * A = mclGetUninitializedArray(); mxArray * XSize = mclGetUninitializedArray(); mxArray * YSize = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * fallo = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mxArray * nargout = mclInitialize(mlfScalar(nargout_)); /* * %[imagen,N,tipovig,sentido,umbral,valor,N1,N2,i]=lectrap * %Lee del fichero denominado camara.txt y comprueba que los

valores * %son concordantes con los requesitos del programa de vigilancia. * %Los parametros son los siguientes, con las siguientes

especificaciones: * % * %imagen: Cadena de caracteres con el nombre del fichero sin

extension

138

Proyecto fin de carrera Gonzalo Leandro Bravo

* % debe ir entre comillas. * % * %N: Numero de fotogramas que voy a analizar, posteriormente se

anulara su valor. * % * %tipovig: Parametro utilizado para decidir si se utiliza una funcion

u otro para el * % analisis del sistema. Esto se decide durante la inicializacion. * % Puede tomar dos valores: 'igual' concede un valor de igualdad y * % 'simil'

utiliza correlacion. * % * %sentido: Indica el sentido de la línea de vigilancia. * % Puede tomar tres valores: 'all' analiza la imagen completa * % 'ver'

analisis vertical y * % 'hor'

analisis horizontal * % * %umbral: valor en tanto por cien sobrepasado el cual se considera

alarma. * % 0->Detecta cualquier cambio por minimo que sea * % 100->La imagen permanece inmovil * % valor aconsejado entre 80 y 95 * % * %valor: Se considera igual a los bit que se encuentren entre bit+-

valor * % Valor aconsejado entre 10 y 20. Solo tiene sentido si

tipovig=='igual' * % * %N1 y N2: Franjas que se van a analizar. Solo tiene sentido si

sentido!='all' * % * %color: Se analiza solo uno de los tres colores del formato RGB. * % Los posibles valores son: color=0 Rojo * %

color=1 Verde * %

color=2 Azul * * * fid=fopen('camara.txt','rt'); */ mlfAssign( &fid, mlfFopen( NULL, NULL, mxCreateString("camara.txt"),

mxCreateString("rt"), NULL)); /* * if (fid==-1)

139

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo camara.txt para lectura.']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo camara.txt para lectura."),

NULL)); /* * %saltar a inicializar camara.txt, * %ver qeu color tomo para seguir trabajando * else */ } else { /* * fallo=0; */ mlfAssign(&fallo, mlfScalar(0.0)); /* * end; */ } /* * * if (nargout~=9) */ if (mlfTobool(mlfNe(nargout, mlfScalar(9.0)))) { /* * error('Falta algun dato para comenzar el analisis.'); */ mlfError(mxCreateString("Falta algun dato para comenzar el

analisis.")); /* * end; */ } /* * %-------------------------------------------------------------------- * * imagen=fgetl(fid); */ mlfAssign(&imagen, mlfFgetl(fid)); /* * if (isstr(imagen)~=1) */ if (mlfTobool(mlfNe(mlfIsstr(imagen), mlfScalar(1.0)))) { /* * fallo=1; */

140

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(&fallo, mlfScalar(1.0)); /* * end; */ } /* * %-------------------------------------------------------------------- * N=fgetl(fid); */ mlfAssign(N, mlfFgetl(fid)); /* * N=str2num(N); */ mlfAssign(N, mlfStr2num(*N)); /* * %-------------------------------------------------------------------- * tipovig=fgetl(fid); */ mlfAssign(tipovig, mlfFgetl(fid)); /* * if (tipovig~='igual') */ if (mlfTobool(mlfNe(*tipovig, mxCreateString("igual")))) { /* * if (tipovig~='simil') */ if (mlfTobool(mlfNe(*tipovig, mxCreateString("simil")))) { /* * fallo=2; */ mlfAssign(&fallo, mlfScalar(2.0)); /* * end; */ } /* * end; */ } /* * %-------------------------------------------------------------------- * sentido=fgetl(fid); */ mlfAssign(sentido, mlfFgetl(fid)); /* * if (sentido~='all') */ if (mlfTobool(mlfNe(*sentido, mxCreateString("all")))) { /* * if (sentido~='ver')

141

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ if (mlfTobool(mlfNe(*sentido, mxCreateString("ver")))) { /* * if (sentido~='hor') */ if (mlfTobool(mlfNe(*sentido, mxCreateString("hor")))) { /* * fallo=3; */ mlfAssign(&fallo, mlfScalar(3.0)); /* * end; */ } /* * end; */ } /* * end; */ } /* * %-------------------------------------------------------------------- * umbral=fgetl(fid); */ mlfAssign(umbral, mlfFgetl(fid)); /* * umbral=str2num(umbral); */ mlfAssign(umbral, mlfStr2num(*umbral)); /* * if (umbral<0|umbral>100) */ { mxArray * a_ = mclInitialize(mlfLt(*umbral, mlfScalar(0.0))); if (mlfTobool(a_) || mlfTobool(mlfOr(a_, mlfGt(*umbral, mlfScalar(100.0))))) { mxDestroyArray(a_); /* * fallo=4; */ mlfAssign(&fallo, mlfScalar(4.0)); } else { mxDestroyArray(a_); } /* * end; */ }

142

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * %-------------------------------------------------------------------- * valor=fgetl(fid); */ mlfAssign(valor, mlfFgetl(fid)); /* * valor=str2num(valor); */ mlfAssign(valor, mlfStr2num(*valor)); /* * if (valor<0|valor>20) */ { mxArray * a_ = mclInitialize(mlfLt(*valor, mlfScalar(0.0))); if (mlfTobool(a_) || mlfTobool(mlfOr(a_, mlfGt(*valor, mlfScalar(20.0))))) { mxDestroyArray(a_); /* * fallo=5; */ mlfAssign(&fallo, mlfScalar(5.0)); } else { mxDestroyArray(a_); } /* * end; */ } /* * * %-------------------------------------------------------------------- * N1=fgetl(fid); */ mlfAssign(N1, mlfFgetl(fid)); /* * N1=str2num(N1); */ mlfAssign(N1, mlfStr2num(*N1)); /* * * N2=fgetl(fid); */ mlfAssign(N2, mlfFgetl(fid)); /* * N2=str2num(N2); */ mlfAssign(N2, mlfStr2num(*N2)); /* * if N1>N2 */

143

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

if (mlfTobool(mlfGt(*N1, *N2))) { /* * fallo=6; */ mlfAssign(&fallo, mlfScalar(6.0)); /* * else */ } else { /* * A=[imagen, num2str(1)]; */ mlfAssign( &A, mlfHorzcat(imagen, mlfNum2str(mlfScalar(1.0), NULL),

NULL)); /* * [YSize, XSize]=N1N2(A); */ mlfAssign(&YSize, mlfN1N2(&XSize, A)); /* * if (sentido=='ver' & N2>YSize) */ { mxArray * a_ = mclInitialize( mlfEq(*sentido, mxCreateString("ver"))); if (mlfTobool(a_) && mlfTobool(mlfAnd(a_, mlfGt(*N2,

YSize)))) { mxDestroyArray(a_); /* * fallo=6; */ mlfAssign(&fallo, mlfScalar(6.0)); } else { mxDestroyArray(a_); } /* * end */ } /* * if (sentido=='hor' & N2>XSize) */ { mxArray * a_ = mclInitialize( mlfEq(*sentido, mxCreateString("hor"))); if (mlfTobool(a_) && mlfTobool(mlfAnd(a_, mlfGt(*N2,

XSize)))) { mxDestroyArray(a_); /* * fallo=6;

144

Proyecto fin de carrera Gonzalo Leandro Bravo

*/ mlfAssign(&fallo, mlfScalar(6.0)); } else { mxDestroyArray(a_); } /* * end */ } /* * end */ } /* * %-------------------------------------------------------------------- * color=fgetl(fid); */ mlfAssign(color, mlfFgetl(fid)); /* * color=str2num(color); */ mlfAssign(color, mlfStr2num(*color)); /* * if (color~=0) */ if (mlfTobool(mlfNe(*color, mlfScalar(0.0)))) { /* * if (color~=1) */ if (mlfTobool(mlfNe(*color, mlfScalar(1.0)))) { /* * if (color~=2) */ if (mlfTobool(mlfNe(*color, mlfScalar(2.0)))) { /* * color=0; */ mlfAssign(color, mlfScalar(0.0)); /* * fallo=7; */ mlfAssign(&fallo, mlfScalar(7.0)); /* * end; */ } /* * end; */ }

145

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

/* * end; */ } /* * %-------------------------------------------------------------------- * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * %-------------------------------------------------------------------- * if fallo==0 */ if (mlfTobool(mlfEq(fallo, mlfScalar(0.0)))) { /* * fprintf(1,'El fichero camara.txt existe, asegurese de que es el

deseado\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El fichero camara.txt existe, ase" "gurese de que es el deseado\\n"), NULL)); /* * fprintf(1,'Vigilando...\n'); */ mclAssignAns( &ans, mlfFprintf(mlfScalar(1.0), mxCreateString("Vigilando...\\n"),

NULL)); /* * else */ } else { /* * switch fallo * case 1, */ if (mclSwitchCompare(fallo, mlfScalar(1.0))) { /* * fprintf(1,'El nombre de los fotogramas ha de ser una cadena de

caracteres.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0),

146

Proyecto fin de carrera Gonzalo Leandro Bravo

mxCreateString( "El nombre de los fotogramas ha de " "ser una cadena de caracteres.\\n"), NULL)); /* * fprintf(1,'Tomaremos valor por defecto imagen.bmp.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Tomaremos valor por defecto

imagen.bmp.\\n"), NULL)); /* * imagen='imagen.bmp'; */ mlfAssign(&imagen, mxCreateString("imagen.bmp")); /* * case 2, */ } else if (mclSwitchCompare(fallo, mlfScalar(2.0))) { /* * fprintf(1,'El tipo de analisis ha de ser "igual" o "simil".\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El tipo de analisis ha de ser \"igual\" o \"simil\".\\n"), NULL)); /* * fprintf(1,'Tomaremos valor por defecto simil.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Tomaremos valor por defecto simil.\\n"),

NULL)); /* * tipovig='simil'; */ mlfAssign(tipovig, mxCreateString("simil")); /* * case 3, */ } else if (mclSwitchCompare(fallo, mlfScalar(3.0))) { /*

147

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* fprintf(1,'El tipo de analisis ha de ser "all", "ver" o "hor".\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El tipo de analisis ha de ser \"" "all\", \"ver\" o \"hor\".\\n"), NULL)); /* * fprintf(1,'Tomaremos valor por defecto all.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Tomaremos valor por defecto all.\\n"),

NULL)); /* * sentido='all'; */ mlfAssign(sentido, mxCreateString("all")); /* * case 4, */ } else if (mclSwitchCompare(fallo, mlfScalar(4.0))) { /* * fprintf(1,'El valor del umbral se debe encontrar entre 0 y

100.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El valor del umbral se debe encontrar entre 0 y 100.\\n"), NULL)); /* * fprintf(1,'Tomaremos valor por defecto 90.\n') */ mclPrintAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Tomaremos valor por defecto 90.\\n"),

NULL)); /* * umbral=90; */

148

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(umbral, mlfScalar(90.0)); /* * case 5, */ } else if (mclSwitchCompare(fallo, mlfScalar(5.0))) { /* * fprintf(1,'El valor del valor se debe encontrar entre 0 y 20.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El valor del valor se debe encontrar entre 0 y 20.\\n"), NULL)); /* * fprintf(1,'Tomaremos valor por defecto 15.\n') */ mclPrintAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Tomaremos valor por defecto 15.\\n"),

NULL)); /* * valor=15; */ mlfAssign(valor, mlfScalar(15.0)); /* * case 6, */ } else if (mclSwitchCompare(fallo, mlfScalar(6.0))) { /* * fprintf(1,'El valor de N2 ha de ser mayor que el de N1 y estar

dentro de los limites de la imagen.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "El valor de N2 ha de ser mayor que el de N1 y " "estar dentro de los limites de la imagen.\\n"), NULL)); /* * fprintf(1,'Revise el fichero de inicio.\n'); */ mclAssignAns( &ans, mlfFprintf(

149

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mlfScalar(1.0), mxCreateString("Revise el fichero de inicio.\\n"), NULL)); /* * fprintf(1,'Realizaremos un analisis total de la imagen.\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "Realizaremos un analisis total de la imagen.\\n"), NULL)); /* * sentido='all'; */ mlfAssign(sentido, mxCreateString("all")); /* * case 7, */ } else if (mclSwitchCompare(fallo, mlfScalar(7.0))) { /* * fprintf(1,'Error en la eleccion del color tomaremos Rojo por

defecto'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "Error en la eleccion del color tomaremos Rojo por defecto"), NULL)); /* * color=0; */ mlfAssign(color, mlfScalar(0.0)); /* * otherwise, */ } else { /* * fprintf(1,'WARNING: Es posible que haya algun error en

camara.txt, asegurese de que es el deseado\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "WARNING: Es posible que haya algun error en c" "amara.txt, asegurese de que es el deseado\\n"),

150

Proyecto fin de carrera Gonzalo Leandro Bravo

NULL)); /* * fprintf(1,'Vigilando...\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString("Vigilando...\\n"), NULL)); /* * end */ } /* * end */ } mclValidateOutputs( "lectot", 9, nargout_, &imagen, N, tipovig, sentido, umbral, valor, N1, N2, color); mxDestroyArray(A); mxDestroyArray(XSize); mxDestroyArray(YSize); mxDestroyArray(ans); mxDestroyArray(fallo); mxDestroyArray(fid); mxDestroyArray(nargout); /* * %-------------------------------------------------------------------- */ return imagen; } /* * The function "mlfNLectot" contains the nargout interface for the

"lectot" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\lectot.m" * (lines 1-158). This interface is only produced if the M-function uses

the * special variable "nargout". The nargout interface allows the number of

151

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* requested outputs to be specified via the nargout argument, as opposed to

* the normal interface which dynamically calculates the number of outputs

* based on the number of non-NULL inputs it receives. This function processes

* any input arguments and passes them to the implementation version of the

* function, appearing above. */ mxArray * mlfNLectot(int nargout, mxArray * * N, mxArray * * tipovig, mxArray * * sentido, mxArray * * umbral, mxArray * * valor, mxArray * * N1, mxArray * * N2, mxArray * * color) { mxArray * imagen = mclGetUninitializedArray(); mxArray * N__ = mclGetUninitializedArray(); mxArray * tipovig__ = mclGetUninitializedArray(); mxArray * sentido__ = mclGetUninitializedArray(); mxArray * umbral__ = mclGetUninitializedArray(); mxArray * valor__ = mclGetUninitializedArray(); mxArray * N1__ = mclGetUninitializedArray(); mxArray * N2__ = mclGetUninitializedArray(); mxArray * color__ = mclGetUninitializedArray(); mlfEnterNewContext(8, 0, N, tipovig, sentido, umbral, valor, N1, N2,

color); imagen = Mlectot( &N__, &tipovig__, &sentido__, &umbral__, &valor__, &N1__, &N2__, &color__, nargout); mlfRestorePreviousContext( 8, 0, N, tipovig, sentido, umbral, valor, N1, N2, color); if (N != NULL) { mclCopyOutputArg(N, N__); } else { mxDestroyArray(N__); } if (tipovig != NULL) { mclCopyOutputArg(tipovig, tipovig__);

152

Proyecto fin de carrera Gonzalo Leandro Bravo

} else { mxDestroyArray(tipovig__); } if (sentido != NULL) { mclCopyOutputArg(sentido, sentido__); } else { mxDestroyArray(sentido__); } if (umbral != NULL) { mclCopyOutputArg(umbral, umbral__); } else { mxDestroyArray(umbral__); } if (valor != NULL) { mclCopyOutputArg(valor, valor__); } else { mxDestroyArray(valor__); } if (N1 != NULL) { mclCopyOutputArg(N1, N1__); } else { mxDestroyArray(N1__); } if (N2 != NULL) { mclCopyOutputArg(N2, N2__); } else { mxDestroyArray(N2__); } if (color != NULL) { mclCopyOutputArg(color, color__); } else { mxDestroyArray(color__); } return mlfReturnValue(imagen); } /* * The function "mlfLectot" contains the normal interface for the "lectot" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\lectot.m" * (lines 1-158). This function processes any input arguments and passes

them * to the implementation version of the function, appearing above. */ mxArray * mlfLectot(mxArray * * N, mxArray * * tipovig, mxArray * * sentido, mxArray * * umbral, mxArray * * valor, mxArray * * N1,

153

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mxArray * * N2, mxArray * * color) { int nargout = 1; mxArray * imagen = mclGetUninitializedArray(); mxArray * N__ = mclGetUninitializedArray(); mxArray * tipovig__ = mclGetUninitializedArray(); mxArray * sentido__ = mclGetUninitializedArray(); mxArray * umbral__ = mclGetUninitializedArray(); mxArray * valor__ = mclGetUninitializedArray(); mxArray * N1__ = mclGetUninitializedArray(); mxArray * N2__ = mclGetUninitializedArray(); mxArray * color__ = mclGetUninitializedArray(); mlfEnterNewContext(8, 0, N, tipovig, sentido, umbral, valor, N1, N2,

color); if (N != NULL) { ++nargout; } if (tipovig != NULL) { ++nargout; } if (sentido != NULL) { ++nargout; } if (umbral != NULL) { ++nargout; } if (valor != NULL) { ++nargout; } if (N1 != NULL) { ++nargout; } if (N2 != NULL) { ++nargout; } if (color != NULL) { ++nargout; } imagen = Mlectot( &N__, &tipovig__, &sentido__, &umbral__, &valor__, &N1__, &N2__, &color__, nargout); mlfRestorePreviousContext(

154

Proyecto fin de carrera Gonzalo Leandro Bravo

8, 0, N, tipovig, sentido, umbral, valor, N1, N2, color); if (N != NULL) { mclCopyOutputArg(N, N__); } else { mxDestroyArray(N__); } if (tipovig != NULL) { mclCopyOutputArg(tipovig, tipovig__); } else { mxDestroyArray(tipovig__); } if (sentido != NULL) { mclCopyOutputArg(sentido, sentido__); } else { mxDestroyArray(sentido__); } if (umbral != NULL) { mclCopyOutputArg(umbral, umbral__); } else { mxDestroyArray(umbral__); } if (valor != NULL) { mclCopyOutputArg(valor, valor__); } else { mxDestroyArray(valor__); } if (N1 != NULL) { mclCopyOutputArg(N1, N1__); } else { mxDestroyArray(N1__); } if (N2 != NULL) { mclCopyOutputArg(N2, N2__); } else { mxDestroyArray(N2__); } if (color != NULL) { mclCopyOutputArg(color, color__); } else { mxDestroyArray(color__); } return mlfReturnValue(imagen); } /* * The function "mlfVLectot" contains the void interface for the "lectot" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\lectot.m" * (lines 1-158). The void interface is only produced if the M-function

uses

155

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* the special variable "nargout", and has at least one output. The void * interface function specifies zero output arguments to the

implementation * version of the function, and in the event that the implementation

version * still returns an output (which, in MATLAB, would be assigned to the

"ans" * variable), it deallocates the output. This function processes any input * arguments and passes them to the implementation version of the

function, * appearing above. */ void mlfVLectot(void) { mxArray * imagen = mclUnassigned(); mxArray * N = mclUnassigned(); mxArray * tipovig = mclUnassigned(); mxArray * sentido = mclUnassigned(); mxArray * umbral = mclUnassigned(); mxArray * valor = mclUnassigned(); mxArray * N1 = mclUnassigned(); mxArray * N2 = mclUnassigned(); mxArray * color = mclUnassigned(); mlfEnterNewContext(0, 0); imagen = Mlectot(&N, &tipovig, &sentido, &umbral, &valor, &N1, &N2,

&color, 0); mlfRestorePreviousContext(0, 0); mxDestroyArray(imagen); mxDestroyArray(N); mxDestroyArray(tipovig); mxDestroyArray(sentido); mxDestroyArray(umbral); mxDestroyArray(valor); mxDestroyArray(N1); mxDestroyArray(N2); mxDestroyArray(color); } /* * The function "mlxLectot" contains the feval interface for the "lectot" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\lectot.m" * (lines 1-158). The feval function calls the implementation version of

lectot * through this function. This function processes any input arguments and * passes them to the implementation version of the function, appearing

above. */ void mlxLectot(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) { mxArray * mplhs[9];

156

Proyecto fin de carrera Gonzalo Leandro Bravo

int i; if (nlhs > 9) { mlfError( mxCreateString( "Run-time Error: File: lectot Line: 1 Column: " "0 The function \"lectot\" was called with mor" "e than the declared number of outputs (9)")); } if (nrhs > 0) { mlfError( mxCreateString( "Run-time Error: File: lectot Line: 1 Column: " "0 The function \"lectot\" was called with mor" "e than the declared number of inputs (0)")); } for (i = 0; i < 9; ++i) { mplhs[i] = NULL; } mlfEnterNewContext(0, 0); mplhs[0] = Mlectot( &mplhs[1], &mplhs[2], &mplhs[3], &mplhs[4], &mplhs[5], &mplhs[6], &mplhs[7], &mplhs[8], nlhs); mlfRestorePreviousContext(0, 0); plhs[0] = mplhs[0]; for (i = 1; i < 9 && i < nlhs; ++i) { plhs[i] = mplhs[i]; } for (; i < 9; ++i) { mxDestroyArray(mplhs[i]); } } 6.4.4. N1N2.c /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #include "N1N2.h"

157

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

static double __Array0_r[2] = { 66.0, 77.0 }; /* * The function "MN1N2" is the implementation version of the "N1N2"

M-function * from file "D:\escuela\Matlab\work\funcionaC\final1\N1N2.m" (lines

1-69). It * contains the actual compiled code for that M-function. It is a static * function and must only be called from one of the interface functions, * appearing below. */ /* * function [YSize,XSize]=N1N2(nombrefich); */ static mxArray * MN1N2(mxArray * * XSize, int nargout_, mxArray *

nombrefich) { mxArray * YSize = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * bfOffBytes = mclGetUninitializedArray(); mxArray * bfReserved1 = mclGetUninitializedArray(); mxArray * bfReserved2 = mclGetUninitializedArray(); mxArray * bfSize = mclGetUninitializedArray(); mxArray * bfType = mclGetUninitializedArray(); mxArray * biBitCount = mclGetUninitializedArray(); mxArray * biClrImportant = mclGetUninitializedArray(); mxArray * biClrUsed = mclGetUninitializedArray(); mxArray * biCompression = mclGetUninitializedArray(); mxArray * biHeight = mclGetUninitializedArray(); mxArray * biPlanes = mclGetUninitializedArray(); mxArray * biSize = mclGetUninitializedArray(); mxArray * biSizeImage = mclGetUninitializedArray(); mxArray * biWidth = mclGetUninitializedArray(); mxArray * biXPels = mclGetUninitializedArray(); mxArray * biYPels = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mxArray * nargin_ = mclGetUninitializedArray(); mlfAssign(&nargin_, mlfNargin(0, nombrefich, NULL)); mclValidateInputs("N1N2", 1, &nombrefich); mclCopyArray(&nombrefich); /* * %[YSize,XSize]=N1N2(nombrefich) * %DEvuelve el tamano de la imagen * %No acepta bmp diferentes de 24 bits. * %Toma el color Rojo =0; ; * * * if (nargin~=1) */ if (mlfTobool(mlfNe(nargin_, mlfScalar(1.0)))) { /*

158

Proyecto fin de carrera Gonzalo Leandro Bravo

* error('Requiere un nombre de fichero como argumento y el color a utilizar.');

*/ mlfError( mxCreateString( "Requiere un nombre de fichero como " "argumento y el color a utilizar.")); /* * end; */ } /* * * if (isstr(nombrefich)~=1) */ if (mlfTobool(mlfNe(mlfIsstr(nombrefich), mlfScalar(1.0)))) { /* * error('Requiere una cadena de caracteres como nombre del

fichero.'); */ mlfError( mxCreateString( "Requiere una cadena de caracteres como nombre del fichero.")); /* * end; */ } /* * * if (isempty(findstr(nombrefich,'.'))==1) */ if (mlfTobool( mlfEq( mlfIsempty(mlfFindstr(nombrefich, mxCreateString("."))), mlfScalar(1.0)))) { /* * nombrefich=[nombrefich,'.bmp']; */ mlfAssign( &nombrefich, mlfHorzcat(nombrefich, mxCreateString(".bmp"),

NULL)); /* * end; */ } /* * * fid=fopen(nombrefich,'rb','l'); */ mlfAssign(

159

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

&fid, mlfFopen( NULL, NULL, nombrefich, mxCreateString("rb"),

mxCreateString("l"))); /* * if (fid==-1) */ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo ',nombrefich,' para lectura']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo "), nombrefich, mxCreateString(" para lectura"), NULL)); /* * end; */ } /* * * bfType=fread(fid,2,'uchar'); */ mlfAssign( &bfType, mlfFread(NULL, fid, mlfScalar(2.0), mxCreateString("uchar"),

NULL)); /* * if (bfType~=[66;77]) */ if (mlfTobool(mlfNe(bfType, mlfDoubleMatrix(2, 1, __Array0_r,

NULL)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero BMP.'); */ mlfError(mxCreateString("No es un fichero BMP.")); /* * end; */ } /* * * bfSize=fread(fid,1,'uint'); */

160

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign( &bfSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * bfReserved1=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved1, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfReserved2=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved2, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfOffBytes=fread(fid,1,'uint'); */ mlfAssign( &bfOffBytes, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * * biSize=fread(fid,1,'uint'); */ mlfAssign( &biSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if (biSize~=40) */ if (mlfTobool(mlfNe(biSize, mlfScalar(40.0)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero MS Windows Device Bitmap BMP.'); */ mlfError( mxCreateString("No es un fichero MS Windows Device Bitmap

BMP.")); /* * end; */

161

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

} /* * * biWidth=fread(fid,1,'uint'); */ mlfAssign( &biWidth, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if biCompression~=0 */ if (mlfTobool(mlfNe(biCompression, mlfScalar(0.0)))) { /* * error('No puede leer ficheros BMP comprimidos.'); */ mlfError(mxCreateString("No puede leer ficheros BMP

comprimidos.")); /* * end; */ }

162

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * biSizeImage=fread(fid,1,'uint'); */ mlfAssign( &biSizeImage, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biXPels=fread(fid,1,'uint'); */ mlfAssign( &biXPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biYPels=fread(fid,1,'uint'); */ mlfAssign( &biYPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrUsed=fread(fid,1,'uint'); */ mlfAssign( &biClrUsed, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrImportant=fread(fid,1,'uint'); */ mlfAssign( &biClrImportant, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * * * if (biBitCount == 24) */ if (mlfTobool(mlfEq(biBitCount, mlfScalar(24.0)))) { /* * if (rem(biWidth,4)~=0) */ if (mlfTobool(mlfNe(mlfRem(biWidth, mlfScalar(4.0)),

mlfScalar(0.0)))) { /* * XSize=biWidth+(4-rem(biWidth,4)); */ mlfAssign(

163

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

XSize, mlfPlus( biWidth, mlfMinus(mlfScalar(4.0), mlfRem(biWidth, mlfScalar(4.0))))); /* * else */ } else { /* * XSize=biWidth; */ mlfAssign(XSize, biWidth); /* * end */ } /* * YSize=biHeight; */ mlfAssign(&YSize, biHeight); /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * return; * end */ } mclValidateOutputs("N1N2", 2, nargout_, &YSize, XSize); mxDestroyArray(ans); mxDestroyArray(bfOffBytes); mxDestroyArray(bfReserved1); mxDestroyArray(bfReserved2); mxDestroyArray(bfSize); mxDestroyArray(bfType); mxDestroyArray(biBitCount); mxDestroyArray(biClrImportant); mxDestroyArray(biClrUsed); mxDestroyArray(biCompression); mxDestroyArray(biHeight); mxDestroyArray(biPlanes); mxDestroyArray(biSize); mxDestroyArray(biSizeImage); mxDestroyArray(biWidth); mxDestroyArray(biXPels); mxDestroyArray(biYPels); mxDestroyArray(fid); mxDestroyArray(nargin_); mxDestroyArray(nombrefich);

164

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * * */ return YSize; } /* * The function "mlfN1N2" contains the normal interface for the "N1N2" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\N1N2.m" (lines * 1-69). This function processes any input arguments and passes them to

the * implementation version of the function, appearing above. */ mxArray * mlfN1N2(mxArray * * XSize, mxArray * nombrefich) { int nargout = 1; mxArray * YSize = mclGetUninitializedArray(); mxArray * XSize__ = mclGetUninitializedArray(); mlfEnterNewContext(1, 1, XSize, nombrefich); if (XSize != NULL) { ++nargout; } YSize = MN1N2(&XSize__, nargout, nombrefich); mlfRestorePreviousContext(1, 1, XSize, nombrefich); if (XSize != NULL) { mclCopyOutputArg(XSize, XSize__); } else { mxDestroyArray(XSize__); } return mlfReturnValue(YSize); } /* * The function "mlxN1N2" contains the feval interface for the "N1N2" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\N1N2.m" (lines * 1-69). The feval function calls the implementation version of N1N2

through * this function. This function processes any input arguments and passes

them * to the implementation version of the function, appearing above. */ void mlxN1N2(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]) { mxArray * mprhs[1]; mxArray * mplhs[2]; int i; if (nlhs > 2) { mlfError( mxCreateString(

165

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

"Run-time Error: File: N1N2 Line: 1 Column: 0 The function \"N1N2\""

" was called with more than the declared number of outputs (2)"));

} if (nrhs > 1) { mlfError( mxCreateString( "Run-time Error: File: N1N2 Line: 1 Column: 0 The function

\"N1N2" "\" was called with more than the declared number of inputs

(1)")); } for (i = 0; i < 2; ++i) { mplhs[i] = NULL; } for (i = 0; i < 1 && i < nrhs; ++i) { mprhs[i] = prhs[i]; } for (; i < 1; ++i) { mprhs[i] = NULL; } mlfEnterNewContext(0, 1, mprhs[0]); mplhs[0] = MN1N2(&mplhs[1], nlhs, mprhs[0]); mlfRestorePreviousContext(0, 1, mprhs[0]); plhs[0] = mplhs[0]; for (i = 1; i < 2 && i < nlhs; ++i) { plhs[i] = mplhs[i]; } for (; i < 2; ++i) { mxDestroyArray(mplhs[i]); } } 6.4.5. bmpallrap.c /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #include "bmpallrap.h" static double __Array0_r[2] = { 66.0, 77.0 }; /* * The function "Mbmpallrap" is the implementation version of the

"bmpallrap"

166

Proyecto fin de carrera Gonzalo Leandro Bravo

* M-function from file "D:\escuela\Matlab\work\funcionaC\final1\bmpallrap.m"

* (lines 1-78). It contains the actual compiled code for that M-function. It

* is a static function and must only be called from one of the interface * functions, appearing below. */ /* * function [X]=bmpallrap(nombrefich,color); */ static mxArray * Mbmpallrap(int nargout_, mxArray * nombrefich, mxArray * color) { mxArray * X = mclGetUninitializedArray(); mxArray * Size = mclGetUninitializedArray(); mxArray * XSize = mclGetUninitializedArray(); mxArray * YSize = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * bfOffBytes = mclGetUninitializedArray(); mxArray * bfReserved1 = mclGetUninitializedArray(); mxArray * bfReserved2 = mclGetUninitializedArray(); mxArray * bfSize = mclGetUninitializedArray(); mxArray * bfType = mclGetUninitializedArray(); mxArray * biBitCount = mclGetUninitializedArray(); mxArray * biClrImportant = mclGetUninitializedArray(); mxArray * biClrUsed = mclGetUninitializedArray(); mxArray * biCompression = mclGetUninitializedArray(); mxArray * biHeight = mclGetUninitializedArray(); mxArray * biPlanes = mclGetUninitializedArray(); mxArray * biSize = mclGetUninitializedArray(); mxArray * biSizeImage = mclGetUninitializedArray(); mxArray * biWidth = mclGetUninitializedArray(); mxArray * biXPels = mclGetUninitializedArray(); mxArray * biYPels = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mxArray * nargin_ = mclGetUninitializedArray(); mlfAssign(&nargin_, mlfNargin(0, nombrefich, color, NULL)); mclValidateInputs("bmpallrap", 2, &nombrefich, &color); mclCopyArray(&nombrefich); /* * %bmpallrap lee un fichero bmp24 de disco y devuelve un vector

con los datos solicitados * %de esta manera se acelera el proceso de lectura y su posterior

analisis. * %No acepta bmp diferentes de 24 bits. * %[X]=bmpallrap(nombrefich,color); * %Toma el color Rojo =0; Verde =1; Azul=2; * * * if (nargin~=2)

167

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ if (mlfTobool(mlfNe(nargin_, mlfScalar(2.0)))) { /* * error('Requiere un nombre de fichero como argumento y el color

a utilizar.'); */ mlfError( mxCreateString( "Requiere un nombre de fichero como " "argumento y el color a utilizar.")); /* * end; */ } /* * * if (isstr(nombrefich)~=1) */ if (mlfTobool(mlfNe(mlfIsstr(nombrefich), mlfScalar(1.0)))) { /* * error('Requiere una cadena de caracteres como nombre del

fichero.'); */ mlfError( mxCreateString( "Requiere una cadena de caracteres como nombre del fichero.")); /* * end; */ } /* * * if (isempty(findstr(nombrefich,'.'))==1) */ if (mlfTobool( mlfEq( mlfIsempty(mlfFindstr(nombrefich, mxCreateString("."))), mlfScalar(1.0)))) { /* * nombrefich=[nombrefich,'.bmp']; */ mlfAssign( &nombrefich, mlfHorzcat(nombrefich, mxCreateString(".bmp"),

NULL)); /* * end; */ } /* *

168

Proyecto fin de carrera Gonzalo Leandro Bravo

* fid=fopen(nombrefich,'rb','l'); */ mlfAssign( &fid, mlfFopen( NULL, NULL, nombrefich, mxCreateString("rb"),

mxCreateString("l"))); /* * if (fid==-1) */ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo ',nombrefich,' para lectura']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo "), nombrefich, mxCreateString(" para lectura"), NULL)); /* * end; */ } /* * * bfType=fread(fid,2,'uchar'); */ mlfAssign( &bfType, mlfFread(NULL, fid, mlfScalar(2.0), mxCreateString("uchar"),

NULL)); /* * if (bfType~=[66;77]) */ if (mlfTobool(mlfNe(bfType, mlfDoubleMatrix(2, 1, __Array0_r,

NULL)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero BMP.'); */ mlfError(mxCreateString("No es un fichero BMP.")); /* * end; */ } /*

169

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* * bfSize=fread(fid,1,'uint'); */ mlfAssign( &bfSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * bfReserved1=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved1, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfReserved2=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved2, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfOffBytes=fread(fid,1,'uint'); */ mlfAssign( &bfOffBytes, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * * biSize=fread(fid,1,'uint'); */ mlfAssign( &biSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if (biSize~=40) */ if (mlfTobool(mlfNe(biSize, mlfScalar(40.0)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero MS Windows Device Bitmap BMP.'); */ mlfError( mxCreateString("No es un fichero MS Windows Device Bitmap

BMP."));

170

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * end; */ } /* * * biWidth=fread(fid,1,'uint'); */ mlfAssign( &biWidth, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if biCompression~=0 */ if (mlfTobool(mlfNe(biCompression, mlfScalar(0.0)))) { /* * error('No puede leer ficheros BMP comprimidos.'); */ mlfError(mxCreateString("No puede leer ficheros BMP

comprimidos.")); /*

171

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* end; */ } /* * biSizeImage=fread(fid,1,'uint'); */ mlfAssign( &biSizeImage, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biXPels=fread(fid,1,'uint'); */ mlfAssign( &biXPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biYPels=fread(fid,1,'uint'); */ mlfAssign( &biYPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrUsed=fread(fid,1,'uint'); */ mlfAssign( &biClrUsed, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrImportant=fread(fid,1,'uint'); */ mlfAssign( &biClrImportant, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * * * if (biBitCount == 24) */ if (mlfTobool(mlfEq(biBitCount, mlfScalar(24.0)))) { /* * if (rem(biWidth,4)~=0) */ if (mlfTobool(mlfNe(mlfRem(biWidth, mlfScalar(4.0)),

mlfScalar(0.0)))) { /*

172

Proyecto fin de carrera Gonzalo Leandro Bravo

* XSize=biWidth+(4-rem(biWidth,4)); */ mlfAssign( &XSize, mlfPlus( biWidth, mlfMinus(mlfScalar(4.0), mlfRem(biWidth, mlfScalar(4.0))))); /* * else */ } else { /* * XSize=biWidth; */ mlfAssign(&XSize, biWidth); /* * end */ } /* * YSize=biHeight; */ mlfAssign(&YSize, biHeight); /* * Size=XSize*YSize; */ mlfAssign(&Size, mlfMtimes(XSize, YSize)); /* * * %-------------------------------------------------------------------- * %Aqui es donde realiza la lectura del fichero tras analizarlo y

posicionarme. * fseek(fid, bfOffBytes+color, 'bof'); */ mclAssignAns( &ans, mlfFseek(fid, mlfPlus(bfOffBytes, color),

mxCreateString("bof"))); /* * X=fread(fid,Size,'uchar',2); */ mlfAssign( &X, mlfFread(NULL, fid, Size, mxCreateString("uchar"),

mlfScalar(2.0))); /* * %-------------------------------------------------------------------- * * fclose(fid); */

173

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mclAssignAns(&ans, mlfFclose(fid)); /* * return; * end */ } mclValidateOutputs("bmpallrap", 1, nargout_, &X); mxDestroyArray(Size); mxDestroyArray(XSize); mxDestroyArray(YSize); mxDestroyArray(ans); mxDestroyArray(bfOffBytes); mxDestroyArray(bfReserved1); mxDestroyArray(bfReserved2); mxDestroyArray(bfSize); mxDestroyArray(bfType); mxDestroyArray(biBitCount); mxDestroyArray(biClrImportant); mxDestroyArray(biClrUsed); mxDestroyArray(biCompression); mxDestroyArray(biHeight); mxDestroyArray(biPlanes); mxDestroyArray(biSize); mxDestroyArray(biSizeImage); mxDestroyArray(biWidth); mxDestroyArray(biXPels); mxDestroyArray(biYPels); mxDestroyArray(fid); mxDestroyArray(nargin_); mxDestroyArray(nombrefich); /* * * * %Lo que mas enlentece es leer saltando grandes cantidades. */ return X; } /* * The function "mlfBmpallrap" contains the normal interface for the * "bmpallrap" M-function from file * "D:\escuela\Matlab\work\funcionaC\final1\bmpallrap.m" (lines 1-78).

This * function processes any input arguments and passes them to the

implementation * version of the function, appearing above. */ mxArray * mlfBmpallrap(mxArray * nombrefich, mxArray * color) { int nargout = 1; mxArray * X = mclGetUninitializedArray();

174

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfEnterNewContext(0, 2, nombrefich, color); X = Mbmpallrap(nargout, nombrefich, color); mlfRestorePreviousContext(0, 2, nombrefich, color); return mlfReturnValue(X); } /* * The function "mlxBmpallrap" contains the feval interface for the

"bmpallrap" * M-function from file

"D:\escuela\Matlab\work\funcionaC\final1\bmpallrap.m" * (lines 1-78). The feval function calls the implementation version of * bmpallrap through this function. This function processes any input

arguments * and passes them to the implementation version of the function,

appearing * above. */ void mlxBmpallrap(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]) { mxArray * mprhs[2]; mxArray * mplhs[1]; int i; if (nlhs > 1) { mlfError( mxCreateString( "Run-time Error: File: bmpallrap Line: 1 Column:" " 0 The function \"bmpallrap\" was called with m" "ore than the declared number of outputs (1)")); } if (nrhs > 2) { mlfError( mxCreateString( "Run-time Error: File: bmpallrap Line: 1 Column:" " 0 The function \"bmpallrap\" was called with m" "ore than the declared number of inputs (2)")); } for (i = 0; i < 1; ++i) { mplhs[i] = NULL; } for (i = 0; i < 2 && i < nrhs; ++i) { mprhs[i] = prhs[i]; } for (; i < 2; ++i) { mprhs[i] = NULL; } mlfEnterNewContext(0, 2, mprhs[0], mprhs[1]); mplhs[0] = Mbmpallrap(nlhs, mprhs[0], mprhs[1]); mlfRestorePreviousContext(0, 2, mprhs[0], mprhs[1]); plhs[0] = mplhs[0];

175

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

} 6.4.6. bmptrozorap.c /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #include "bmptrozorap.h" static double __Array0_r[2] = { 66.0, 77.0 }; /* * The function "Mbmptrozorap" is the implementation version of the * "bmptrozorap" M-function from file * "D:\escuela\Matlab\work\funcionaC\final1\bmptrozorap.m" (lines 1-

84). It * contains the actual compiled code for that M-function. It is a static * function and must only be called from one of the interface functions, * appearing below. */ /* * function [X]=bmptrozorap(nombrefich,direccion,N1,N2,color); */ static mxArray * Mbmptrozorap(int nargout_, mxArray * nombrefich, mxArray * direccion, mxArray * N1, mxArray * N2, mxArray * color) { mxArray * X = mclGetUninitializedArray(); mxArray * I = mclGetUninitializedArray(); mxArray * Size = mclGetUninitializedArray(); mxArray * XSize = mclGetUninitializedArray(); mxArray * Y = mclGetUninitializedArray(); mxArray * YSize = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * bfOffBytes = mclGetUninitializedArray(); mxArray * bfReserved1 = mclGetUninitializedArray(); mxArray * bfReserved2 = mclGetUninitializedArray(); mxArray * bfSize = mclGetUninitializedArray(); mxArray * bfType = mclGetUninitializedArray(); mxArray * biBitCount = mclGetUninitializedArray(); mxArray * biClrImportant = mclGetUninitializedArray(); mxArray * biClrUsed = mclGetUninitializedArray(); mxArray * biCompression = mclGetUninitializedArray(); mxArray * biHeight = mclGetUninitializedArray(); mxArray * biPlanes = mclGetUninitializedArray();

176

Proyecto fin de carrera Gonzalo Leandro Bravo

mxArray * biSize = mclGetUninitializedArray(); mxArray * biSizeImage = mclGetUninitializedArray(); mxArray * biWidth = mclGetUninitializedArray(); mxArray * biXPels = mclGetUninitializedArray(); mxArray * biYPels = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mclForLoopIterator iterator_0; mxArray * nargin_ = mclGetUninitializedArray(); mlfAssign( &nargin_, mlfNargin(0, nombrefich, direccion, N1, N2, color,

NULL)); mclValidateInputs( "bmptrozorap", 5, &nombrefich, &direccion, &N1, &N2, &color); mclCopyArray(&nombrefich); /* * %bmptrozorap lee un trozo de fichero bmp24 de disco y devuelve

un vector con los datos solicitados * %de esta manera se acelera el proceso de lectura y su posterior

analisis. * %No acepta bmp diferentes de 24 bits. * %[X]=bmptrozorap(nombrefich,direccion,N1,N2,color); * %Toma el color Rojo =0; Verde =1; Azul=2; * if (nargin~=5) */ if (mlfTobool(mlfNe(nargin_, mlfScalar(5.0)))) { /* * error('Requiere un nombre de fichero como argumento,la franja a

analizar y el color deseado.'); */ mlfError( mxCreateString( "Requiere un nombre de fichero como argumento" ",la franja a analizar y el color deseado.")); /* * end; */ } /* * * if (isstr(nombrefich)~=1) */ if (mlfTobool(mlfNe(mlfIsstr(nombrefich), mlfScalar(1.0)))) { /* * error('Requiere una cadena de caracteres como nombre del

fichero.'); */ mlfError( mxCreateString( "Requiere una cadena de caracteres como nombre del fichero.")); /*

177

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* end; */ } /* * * if (isempty(findstr(nombrefich,'.'))==1) */ if (mlfTobool( mlfEq( mlfIsempty(mlfFindstr(nombrefich, mxCreateString("."))), mlfScalar(1.0)))) { /* * nombrefich=[nombrefich,'.bmp']; */ mlfAssign( &nombrefich, mlfHorzcat(nombrefich, mxCreateString(".bmp"),

NULL)); /* * end; */ } /* * * fid=fopen(nombrefich,'rb','l'); */ mlfAssign( &fid, mlfFopen( NULL, NULL, nombrefich, mxCreateString("rb"),

mxCreateString("l"))); /* * if (fid==-1) */ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo ',nombrefich,' para lectura']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo "), nombrefich, mxCreateString(" para lectura"), NULL)); /* * end; */ } /* * * bfType=fread(fid,2,'uchar');

178

Proyecto fin de carrera Gonzalo Leandro Bravo

*/ mlfAssign( &bfType, mlfFread(NULL, fid, mlfScalar(2.0), mxCreateString("uchar"),

NULL)); /* * if (bfType~=[66;77]) */ if (mlfTobool(mlfNe(bfType, mlfDoubleMatrix(2, 1, __Array0_r,

NULL)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero BMP.'); */ mlfError(mxCreateString("No es un fichero BMP.")); /* * end; */ } /* * * bfSize=fread(fid,1,'uint'); */ mlfAssign( &bfSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * bfReserved1=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved1, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfReserved2=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved2, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * bfOffBytes=fread(fid,1,'uint'); */ mlfAssign( &bfOffBytes,

179

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"), NULL));

/* * * biSize=fread(fid,1,'uint'); */ mlfAssign( &biSize, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if (biSize~=40) */ if (mlfTobool(mlfNe(biSize, mlfScalar(40.0)))) { /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * error('No es un fichero MS Windows Device Bitmap BMP.'); */ mlfError( mxCreateString("No es un fichero MS Windows Device Bitmap

BMP.")); /* * end; */ } /* * * biWidth=fread(fid,1,'uint'); */ mlfAssign( &biWidth, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL));

180

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("ushort"),

NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * if biCompression~=0 */ if (mlfTobool(mlfNe(biCompression, mlfScalar(0.0)))) { /* * error('No puede leer ficheros BMP comprimidos.'); */ mlfError(mxCreateString("No puede leer ficheros BMP

comprimidos.")); /* * end; */ } /* * biSizeImage=fread(fid,1,'uint'); */ mlfAssign( &biSizeImage, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biXPels=fread(fid,1,'uint'); */ mlfAssign( &biXPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biYPels=fread(fid,1,'uint'); */ mlfAssign( &biYPels, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrUsed=fread(fid,1,'uint');

181

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ mlfAssign( &biClrUsed, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * biClrImportant=fread(fid,1,'uint'); */ mlfAssign( &biClrImportant, mlfFread(NULL, fid, mlfScalar(1.0), mxCreateString("uint"),

NULL)); /* * * * if (biBitCount == 24) */ if (mlfTobool(mlfEq(biBitCount, mlfScalar(24.0)))) { /* * if (rem(biWidth,4)~=0) */ if (mlfTobool(mlfNe(mlfRem(biWidth, mlfScalar(4.0)),

mlfScalar(0.0)))) { /* * XSize=biWidth+(4-rem(biWidth,4)); */ mlfAssign( &XSize, mlfPlus( biWidth, mlfMinus(mlfScalar(4.0), mlfRem(biWidth, mlfScalar(4.0))))); /* * else */ } else { /* * XSize=biWidth; */ mlfAssign(&XSize, biWidth); /* * end */ } /* * YSize=biHeight; */ mlfAssign(&YSize, biHeight); /* * Size=XSize*YSize; */

182

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(&Size, mlfMtimes(XSize, YSize)); /* * * fseek(fid, bfOffBytes+color, 'bof'); */ mclAssignAns( &ans, mlfFseek(fid, mlfPlus(bfOffBytes, color),

mxCreateString("bof"))); /* * if direccion=='hor' */ if (mlfTobool(mlfEq(direccion, mxCreateString("hor")))) { /* * fseek(fid,XSize*(YSize-N2)*3,0); */ mclAssignAns( &ans, mlfFseek( fid, mlfMtimes( mlfMtimes(XSize, mlfMinus(YSize, N2)), mlfScalar(3.0)), mlfScalar(0.0))); /* * X=fread(fid,XSize*(N2-N1+1),'uchar',2); */ mlfAssign( &X, mlfFread( NULL, fid, mlfMtimes(XSize, mlfPlus(mlfMinus(N2, N1),

mlfScalar(1.0))), mxCreateString("uchar"), mlfScalar(2.0))); /* * end */ } /* * if direccion=='ver' */ if (mlfTobool(mlfEq(direccion, mxCreateString("ver")))) { /* * fseek(fid,(N1-1)*3,0); */ mclAssignAns( &ans, mlfFseek( fid,

183

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mlfMtimes(mlfMinus(N1, mlfScalar(1.0)), mlfScalar(3.0)), mlfScalar(0.0))); /* * X=fread(fid,(N2-N1+1),'uchar',2); */ mlfAssign( &X, mlfFread( NULL, fid, mlfPlus(mlfMinus(N2, N1), mlfScalar(1.0)), mxCreateString("uchar"), mlfScalar(2.0))); /* * for I=1:YSize-1 */ for (mclForStart( &iterator_0, mlfScalar(1.0), mlfMinus(YSize, mlfScalar(1.0)), NULL); mclForNext(&iterator_0, &I); ) { /* * fseek(fid,(XSize-(N2-N1+1))*3,0); */ mclAssignAns( &ans, mlfFseek( fid, mlfMtimes( mlfMinus( XSize, mlfPlus(mlfMinus(N2, N1), mlfScalar(1.0))), mlfScalar(3.0)), mlfScalar(0.0))); /* * Y=fread(fid,(N2-N1+1),'uchar',2); */ mlfAssign( &Y, mlfFread( NULL, fid, mlfPlus(mlfMinus(N2, N1), mlfScalar(1.0)), mxCreateString("uchar"), mlfScalar(2.0))); /* * X=[X ;Y]; */ mlfAssign(

184

Proyecto fin de carrera Gonzalo Leandro Bravo

&X, mlfVertcat(mlfHorzcat(X, NULL), mlfHorzcat(Y, NULL),

NULL)); /* * end */ } /* * end */ } /* * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * return; * end */ } mclValidateOutputs("bmptrozorap", 1, nargout_, &X); mxDestroyArray(I); mxDestroyArray(Size); mxDestroyArray(XSize); mxDestroyArray(Y); mxDestroyArray(YSize); mxDestroyArray(ans); mxDestroyArray(bfOffBytes); mxDestroyArray(bfReserved1); mxDestroyArray(bfReserved2); mxDestroyArray(bfSize); mxDestroyArray(bfType); mxDestroyArray(biBitCount); mxDestroyArray(biClrImportant); mxDestroyArray(biClrUsed); mxDestroyArray(biCompression); mxDestroyArray(biHeight); mxDestroyArray(biPlanes); mxDestroyArray(biSize); mxDestroyArray(biSizeImage); mxDestroyArray(biWidth); mxDestroyArray(biXPels); mxDestroyArray(biYPels); mxDestroyArray(fid); mxDestroyArray(nargin_); mxDestroyArray(nombrefich); /* * * */

185

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

return X; } /* * The function "mlfBmptrozorap" contains the normal interface for the * "bmptrozorap" M-function from file * "D:\escuela\Matlab\work\funcionaC\final1\bmptrozorap.m" (lines 1-

84). This * function processes any input arguments and passes them to the

implementation * version of the function, appearing above. */ mxArray * mlfBmptrozorap(mxArray * nombrefich, mxArray * direccion, mxArray * N1, mxArray * N2, mxArray * color) { int nargout = 1; mxArray * X = mclGetUninitializedArray(); mlfEnterNewContext(0, 5, nombrefich, direccion, N1, N2, color); X = Mbmptrozorap(nargout, nombrefich, direccion, N1, N2, color); mlfRestorePreviousContext(0, 5, nombrefich, direccion, N1, N2,

color); return mlfReturnValue(X); } /* * The function "mlxBmptrozorap" contains the feval interface for the * "bmptrozorap" M-function from file * "D:\escuela\Matlab\work\funcionaC\final1\bmptrozorap.m" (lines 1-

84). The * feval function calls the implementation version of bmptrozorap

through this * function. This function processes any input arguments and passes them

to the * implementation version of the function, appearing above. */ void mlxBmptrozorap(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]) { mxArray * mprhs[5]; mxArray * mplhs[1]; int i; if (nlhs > 1) { mlfError( mxCreateString( "Run-time Error: File: bmptrozorap Line: 1 Column" ": 0 The function \"bmptrozorap\" was called with" " more than the declared number of outputs (1)")); } if (nrhs > 5) {

186

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfError( mxCreateString( "Run-time Error: File: bmptrozorap Line: 1 Column" ": 0 The function \"bmptrozorap\" was called with" " more than the declared number of inputs (5)")); } for (i = 0; i < 1; ++i) { mplhs[i] = NULL; } for (i = 0; i < 5 && i < nrhs; ++i) { mprhs[i] = prhs[i]; } for (; i < 5; ++i) { mprhs[i] = NULL; } mlfEnterNewContext(0, 5, mprhs[0], mprhs[1], mprhs[2], mprhs[3],

mprhs[4]); mplhs[0] = Mbmptrozorap(nlhs, mprhs[0], mprhs[1], mprhs[2], mprhs[3],

mprhs[4]); mlfRestorePreviousContext( 0, 5, mprhs[0], mprhs[1], mprhs[2], mprhs[3], mprhs[4]); plhs[0] = mplhs[0]; } 6.4.7. vigila.h /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #ifndef __vigila_h #define __vigila_h 1 #include "matlab.h" extern void mlfVigila(void); extern void mlxVigila(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]); #endif

187

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

6.4.8. vigila_main.h No existe. 6.4.9. lectot.h /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #ifndef __lectot_h #define __lectot_h 1 #include "matlab.h" extern mxArray * mlfNLectot(int nargout, mxArray * * N, mxArray * * tipovig, mxArray * * sentido, mxArray * * umbral, mxArray * * valor, mxArray * * N1, mxArray * * N2, mxArray * * color); extern mxArray * mlfLectot(mxArray * * N, mxArray * * tipovig, mxArray * * sentido, mxArray * * umbral, mxArray * * valor, mxArray * * N1, mxArray * * N2, mxArray * * color); extern void mlfVLectot(void); extern void mlxLectot(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]); #endif

188

Proyecto fin de carrera Gonzalo Leandro Bravo

6.4.10. N1N2.h /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #ifndef __N1N2_h #define __N1N2_h 1 #include "matlab.h" extern mxArray * mlfN1N2(mxArray * * XSize, mxArray *

nombrefich); extern void mlxN1N2(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]); #endif 6.4.11. bmpallrap.h /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #ifndef __bmpallrap_h #define __bmpallrap_h 1 #include "matlab.h" extern mxArray * mlfBmpallrap(mxArray * nombrefich, mxArray *

color); extern void mlxBmpallrap(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]);

189

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

#endif 6.4.12. bmptrozorap.h /* * MATLAB Compiler: 2.0 * Date: Wed Nov 07 12:39:14 2001 * Arguments: "-m" "vigila" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #ifndef __bmptrozorap_h #define __bmptrozorap_h 1 #include "matlab.h" extern mxArray * mlfBmptrozorap(mxArray * nombrefich, mxArray * direccion, mxArray * N1, mxArray * N2, mxArray * color); extern void mlxBmptrozorap(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]); #endif

6.5. Códigos fuente en C de programa de inicialización. 6.5.1. configurar.c /* * MATLAB Compiler: 2.0 * Date: Mon Nov 12 11:40:53 2001 * Arguments: "-m" "configurar" */ #include "configurar.h" #include "bmpallini.h" #include "bmpinicial.h" #include "bmptrozoini.h" #include "lecconfigurar.h"

190

Proyecto fin de carrera Gonzalo Leandro Bravo

#include "mean2.h" #include "std2.h" /* * The function "Mconfigurar" is the implementation version of the

"configurar" * M-function from file

"D:\escuela\Matlab\work\funcionaC\inicial\configurar.m" * (lines 1-140). It contains the actual compiled code for that M-function.

It * is a static function and must only be called from one of the interface * functions, appearing below. */ /* * function configurar */ static void Mconfigurar(void) { mxArray * A = mclGetUninitializedArray(); mxArray * Azul = mclGetUninitializedArray(); mxArray * B = mclGetUninitializedArray(); mxArray * I = mclGetUninitializedArray(); mxArray * N = mclGetUninitializedArray(); mxArray * N1 = mclGetUninitializedArray(); mxArray * N2 = mclGetUninitializedArray(); mxArray * Rojo = mclGetUninitializedArray(); mxArray * Verde = mclGetUninitializedArray(); mxArray * a = mclGetUninitializedArray(); mxArray * actual = mclGetUninitializedArray(); mxArray * ans = mclInitializeAns(); mxArray * azul = mclGetUninitializedArray(); mxArray * azulmedia = mclGetUninitializedArray(); mxArray * azulvar = mclGetUninitializedArray(); mxArray * cinco = mclGetUninitializedArray(); mxArray * color = mclGetUninitializedArray(); mxArray * colorvec = mclGetUninitializedArray(); mxArray * diez = mclGetUninitializedArray(); mxArray * diferencia = mclGetUninitializedArray(); mxArray * dos = mclGetUninitializedArray(); mxArray * fid = mclGetUninitializedArray(); mxArray * igual10 = mclGetUninitializedArray(); mxArray * igual15 = mclGetUninitializedArray(); mxArray * igual20 = mclGetUninitializedArray(); mxArray * igual5 = mclGetUninitializedArray(); mxArray * imagen = mclGetUninitializedArray(); mclForLoopIterator iterator_0; mxArray * mediaigual10 = mclGetUninitializedArray(); mxArray * mediaigual15 = mclGetUninitializedArray(); mxArray * mediaigual20 = mclGetUninitializedArray(); mxArray * mediaigual5 = mclGetUninitializedArray(); mxArray * mediasimil = mclGetUninitializedArray();

191

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mxArray * minigual10 = mclGetUninitializedArray(); mxArray * minigual15 = mclGetUninitializedArray(); mxArray * minigual20 = mclGetUninitializedArray(); mxArray * minigual5 = mclGetUninitializedArray(); mxArray * minsimil = mclGetUninitializedArray(); mxArray * quince = mclGetUninitializedArray(); mxArray * rojo = mclGetUninitializedArray(); mxArray * rojomedia = mclGetUninitializedArray(); mxArray * rojovar = mclGetUninitializedArray(); mxArray * sentido = mclGetUninitializedArray(); mxArray * siguiente = mclGetUninitializedArray(); mxArray * simil = mclGetUninitializedArray(); mxArray * stdigual5 = mclGetUninitializedArray(); mxArray * stdsimil = mclGetUninitializedArray(); mxArray * tamano = mclGetUninitializedArray(); mxArray * temp = mclGetUninitializedArray(); mxArray * tipovig = mclGetUninitializedArray(); mxArray * tres = mclGetUninitializedArray(); mxArray * umbral = mclGetUninitializedArray(); mxArray * umbral2 = mclGetUninitializedArray(); mxArray * uno = mclGetUninitializedArray(); mxArray * valor = mclGetUninitializedArray(); mxArray * verde = mclGetUninitializedArray(); mxArray * verdemedia = mclGetUninitializedArray(); mxArray * verdevar = mclGetUninitializedArray(); /* * * [imagen,N,sentido,N1,N2]=lecconfigurar; */ mlfAssign(&imagen, mlfNLecconfigurar(5, &N, &sentido, &N1,

&N2)); /* * %Determino el color que voy a utilizar * for I =1:149 */ for (mclForStart(&iterator_0, mlfScalar(1.0), mlfScalar(149.0),

NULL); mclForNext(&iterator_0, &I); ) { /* * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL),

NULL)); /* * [Rojo,Verde,Azul]=bmpinicial(B); */

192

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(&Rojo, mlfBmpinicial(&Verde, &Azul, B)); /* * rojomedia(I)=mean2(Rojo); */ mlfIndexAssign(&rojomedia, "(?)", I, mlfMean2(Rojo)); /* * rojovar(I)=std2(Rojo); */ mlfIndexAssign(&rojovar, "(?)", I, mlfStd2(Rojo)); /* * verdemedia(I)=mean2(Verde); */ mlfIndexAssign(&verdemedia, "(?)", I, mlfMean2(Verde)); /* * verdevar(I)=std2(Verde); */ mlfIndexAssign(&verdevar, "(?)", I, mlfStd2(Verde)); /* * azulmedia(I)=mean2(Azul); */ mlfIndexAssign(&azulmedia, "(?)", I, mlfMean2(Azul)); /* * azulvar(I)=std2(Azul); */ mlfIndexAssign(&azulvar, "(?)", I, mlfStd2(Azul)); /* * end */ } /* * %--------------------------------------------------------------------------------

-- * uno=[mean(rojomedia) mean(verdemedia) mean(azulmedia)]; */ mlfAssign( &uno, mlfHorzcat( mlfMean(rojomedia, NULL), mlfMean(verdemedia, NULL), mlfMean(azulmedia, NULL), NULL)); /* * dos=[std(rojomedia) std(verdemedia) std(azulmedia)]; */ mlfAssign( &dos, mlfHorzcat( mlfStd(rojomedia, NULL, NULL), mlfStd(verdemedia, NULL, NULL), mlfStd(azulmedia, NULL, NULL),

193

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

NULL)); /* * tres=[mean(rojovar) mean(verdevar) mean(azulvar)]; */ mlfAssign( &tres, mlfHorzcat( mlfMean(rojovar, NULL), mlfMean(verdevar, NULL), mlfMean(azulvar, NULL), NULL)); /* * colorvec=[find(uno~=max(uno)&uno~=min(uno)),

find(dos==min(dos)), find(tres==min(tres))]; */ mlfAssign( &colorvec, mlfHorzcat( mlfFind( NULL, NULL, mlfAnd( mlfNe(uno, mlfMax(NULL, uno, NULL, NULL)), mlfNe(uno, mlfMin(NULL, uno, NULL, NULL)))), mlfFind(NULL, NULL, mlfEq(dos, mlfMin(NULL, dos, NULL,

NULL))), mlfFind(NULL, NULL, mlfEq(tres, mlfMin(NULL, tres, NULL,

NULL))), NULL)); /* * rojo=(sum(colorvec==1)); */ mlfAssign(&rojo, mlfSum(mlfEq(colorvec, mlfScalar(1.0)), NULL)); /* * verde=(sum(colorvec==2)); */ mlfAssign(&verde, mlfSum(mlfEq(colorvec, mlfScalar(2.0)),

NULL)); /* * azul=(sum(colorvec==3)); */ mlfAssign(&azul, mlfSum(mlfEq(colorvec, mlfScalar(3.0)), NULL)); /* * if (verde>=2) */ if (mlfTobool(mlfGe(verde, mlfScalar(2.0)))) { /* * %tomo el verde * color=1; */

194

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfAssign(&color, mlfScalar(1.0)); /* * else */ } else { /* * if (azul>=2) */ if (mlfTobool(mlfGe(azul, mlfScalar(2.0)))) { /* * %tomo el azul * color=2; */ mlfAssign(&color, mlfScalar(2.0)); /* * else */ } else { /* * color=0; */ mlfAssign(&color, mlfScalar(0.0)); /* * end */ } /* * end */ } /* * % si el tercero es muy alto no me interesa pues tiene la imagen

zonas de muy alto contraste * %En general me interesa el que tenga el valor medio intermedio

siempre que la varianza de la media no sea muy alta, * % esto indicaría demasiados cambios, y la media de la varianza no

fuera tampoco excesivamente grande. * %1 indica el color medio de las imagenes * %2 La variacion o no de las imagenes, interesa que sea pequeño * %3 La variación dentro de una imagen * %-------------------------------------------------------------------------------- * A=[imagen, num2str(1)]; */ mlfAssign(&A, mlfHorzcat(imagen, mlfNum2str(mlfScalar(1.0),

NULL), NULL)); /* * if sentido=='all' */ if (mlfTobool(mlfEq(sentido, mxCreateString("all")))) { /*

195

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

* actual=bmpallini(A,color); */ mlfAssign(&actual, mlfBmpallini(A, color)); /* * else */ } else { /* * actual=bmptrozoini(A,sentido,N1,N2,color); */ mlfAssign(&actual, mlfBmptrozoini(A, sentido, N1, N2, color)); /* * end */ } /* * tamano=length(actual); */ mlfAssign(&tamano, mlfLength(actual)); /* * if sentido=='all' */ if (mlfTobool(mlfEq(sentido, mxCreateString("all")))) { /* * N1=1; */ mlfAssign(&N1, mlfScalar(1.0)); /* * N2=2; */ mlfAssign(&N2, mlfScalar(2.0)); /* * for I =1:149 */ for (mclForStart(&iterator_0, mlfScalar(1.0), mlfScalar(149.0),

NULL); mclForNext(&iterator_0, &I); ) { /* * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL),

NULL)); /* * siguiente=bmpallini(B,color); */ mlfAssign(&siguiente, mlfBmpallini(B, color));

196

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * temp=abs(actual-siguiente); */ mlfAssign(&temp, mlfAbs(mlfMinus(actual, siguiente))); /* * igual5(I)=sum(temp<5)/(tamano); */ mlfIndexAssign( &igual5, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(5.0)), NULL),

tamano)); /* * igual10(I)=sum(temp<10)/(tamano); */ mlfIndexAssign( &igual10, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(10.0)), NULL),

tamano)); /* * igual15(I)=sum(temp<15)/(tamano); */ mlfIndexAssign( &igual15, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(15.0)), NULL),

tamano)); /* * igual20(I)=sum(temp<20)/(tamano); */ mlfIndexAssign( &igual20, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(20.0)), NULL),

tamano)); /* *

simil(I)=sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente)));

*/ mlfIndexAssign( &simil, "(?)", I, mlfMrdivide(

197

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mlfSum(mlfSum(mlfTimes(actual, siguiente), NULL), NULL), mlfSqrt( mlfMtimes( mlfSum(mlfSum(mlfTimes(actual, actual), NULL), NULL), mlfSum( mlfSum(mlfTimes(siguiente, siguiente), NULL),

NULL))))); /* * actual=siguiente; */ mlfAssign(&actual, siguiente); /* * end */ } /* * else */ } else { /* * for I =1:149 */ for (mclForStart(&iterator_0, mlfScalar(1.0), mlfScalar(149.0),

NULL); mclForNext(&iterator_0, &I); ) { /* * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, mlfScalar(1.0)), NULL),

NULL)); /* * siguiente=bmptrozoini(B,sentido,N1,N2,color); */ mlfAssign(&siguiente, mlfBmptrozoini(B, sentido, N1, N2,

color)); /* * temp=abs(actual-siguiente); */ mlfAssign(&temp, mlfAbs(mlfMinus(actual, siguiente))); /* * igual5(I)=sum(temp<5)/(tamano); */ mlfIndexAssign( &igual5, "(?)", I,

198

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(5.0)), NULL), tamano));

/* * igual10(I)=sum(temp<10)/(tamano); */ mlfIndexAssign( &igual10, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(10.0)), NULL),

tamano)); /* * igual15(I)=sum(temp<15)/(tamano); */ mlfIndexAssign( &igual15, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(15.0)), NULL),

tamano)); /* * igual20(I)=sum(temp<20)/(tamano); */ mlfIndexAssign( &igual20, "(?)", I, mlfMrdivide(mlfSum(mlfLt(temp, mlfScalar(20.0)), NULL),

tamano)); /* *

simil(I)=sum(sum(actual.*siguiente))/sqrt(sum(sum(actual.*actual))*sum(sum(siguiente.*siguiente)));

*/ mlfIndexAssign( &simil, "(?)", I, mlfMrdivide( mlfSum(mlfSum(mlfTimes(actual, siguiente), NULL), NULL), mlfSqrt( mlfMtimes( mlfSum(mlfSum(mlfTimes(actual, actual), NULL), NULL), mlfSum( mlfSum(mlfTimes(siguiente, siguiente), NULL),

NULL))))); /* * actual=siguiente; */ mlfAssign(&actual, siguiente);

199

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

/* * end */ } /* * end */ } /* * mediaigual5=mean2(igual5); */ mlfAssign(&mediaigual5, mlfMean2(igual5)); /* * stdigual5=std2(igual5); */ mlfAssign(&stdigual5, mlfStd2(igual5)); /* * mediaigual10=mean2(igual10); */ mlfAssign(&mediaigual10, mlfMean2(igual10)); /* * mediaigual15=mean2(igual15); */ mlfAssign(&mediaigual15, mlfMean2(igual15)); /* * mediaigual20=mean2(igual20); */ mlfAssign(&mediaigual20, mlfMean2(igual20)); /* * mediasimil=mean2(simil); */ mlfAssign(&mediasimil, mlfMean2(simil)); /* * stdsimil=std2(simil); */ mlfAssign(&stdsimil, mlfStd2(simil)); /* * minigual5 =min(igual5); */ mlfAssign(&minigual5, mlfMin(NULL, igual5, NULL, NULL)); /* * minigual10 =min(igual10); */ mlfAssign(&minigual10, mlfMin(NULL, igual10, NULL, NULL)); /* * minigual15 =min(igual15); */ mlfAssign(&minigual15, mlfMin(NULL, igual15, NULL, NULL)); /* * minigual20 =min(igual20);

200

Proyecto fin de carrera Gonzalo Leandro Bravo

*/ mlfAssign(&minigual20, mlfMin(NULL, igual20, NULL, NULL)); /* * minsimil=min(simil); */ mlfAssign(&minsimil, mlfMin(NULL, simil, NULL, NULL)); /* * cinco=mediaigual10-mediaigual5; */ mlfAssign(&cinco, mlfMinus(mediaigual10, mediaigual5)); /* * diez=mediaigual15-mediaigual10; */ mlfAssign(&diez, mlfMinus(mediaigual15, mediaigual10)); /* * quince=mediaigual20-mediaigual15; */ mlfAssign(&quince, mlfMinus(mediaigual20, mediaigual15)); /* * diferencia=[cinco, diez, quince]; */ mlfAssign(&diferencia, mlfHorzcat(cinco, diez, quince, NULL)); /* * %si stdigual5>0.03 utilizo simil pq la imagen no es buena, cambia

demasiado, comparo con 5 pq es el más variable * if stdigual5>0.03 */ if (mlfTobool(mlfGt(stdigual5, mlfScalar(0.03)))) { /* * tipovig='simil'; */ mlfAssign(&tipovig, mxCreateString("simil")); /* * umbral=(10000*(minsimil-(mediasimil-minsimil))); */ mlfAssign( &umbral, mlfMtimes( mlfScalar(10000.0), mlfMinus(minsimil, mlfMinus(mediasimil, minsimil)))); /* * valor=15; */ mlfAssign(&valor, mlfScalar(15.0)); /* * else */ } else { /* * tipovig='igual';

201

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

*/ mlfAssign(&tipovig, mxCreateString("igual")); /* * a=max(find(diferencia>=0.005)); */ mlfAssign( &a, mlfMax( NULL, mlfFind(NULL, NULL, mlfGe(diferencia, mlfScalar(0.005))), NULL, NULL)); /* * if a==1 */ if (mlfTobool(mlfEq(a, mlfScalar(1.0)))) { /* * valor=10; */ mlfAssign(&valor, mlfScalar(10.0)); /* * umbral=(10000*(minigual10-(mediaigual10-minigual10))); */ mlfAssign( &umbral, mlfMtimes( mlfScalar(10000.0), mlfMinus(minigual10, mlfMinus(mediaigual10,

minigual10)))); /* * else */ } else { /* * if a==2 */ if (mlfTobool(mlfEq(a, mlfScalar(2.0)))) { /* * valor=15; */ mlfAssign(&valor, mlfScalar(15.0)); /* * umbral=(10000*(minigual15-(mediaigual15-minigual15))); */ mlfAssign( &umbral, mlfMtimes( mlfScalar(10000.0), mlfMinus(minigual15, mlfMinus(mediaigual15,

minigual15))));

202

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * else */ } else { /* * valor=20; */ mlfAssign(&valor, mlfScalar(20.0)); /* * umbral=(10000*(minigual20-(mediaigual20-minigual20))); */ mlfAssign( &umbral, mlfMtimes( mlfScalar(10000.0), mlfMinus(minigual20, mlfMinus(mediaigual20,

minigual20)))); /* * end */ } /* * end */ } /* * end */ } /* * %realizo esta operación para conseguir que umbral sea un número

entero * umbral2=0; */ mlfAssign(&umbral2, mlfScalar(0.0)); /* * while umbral>0 */ while (mlfTobool(mlfGt(umbral, mlfScalar(0.0)))) { /* * umbral2=umbral2+1; */ mlfAssign(&umbral2, mlfPlus(umbral2, mlfScalar(1.0))); /* * umbral=umbral-1; */ mlfAssign(&umbral, mlfMinus(umbral, mlfScalar(1.0))); /* * end */

203

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

} /* * fid=fopen('camara.txt','wt'); */ mlfAssign( &fid, mlfFopen( NULL, NULL, mxCreateString("camara.txt"),

mxCreateString("wt"), NULL)); /* * if (fid==-1) */ if (mlfTobool(mlfEq(fid, mlfScalar(-1.0)))) { /* * error(['Error abriendo camara.txt para escribir.']); */ mlfError( mlfHorzcat( mxCreateString("Error abriendo camara.txt para escribir."),

NULL)); /* * end; */ } /* * * fprintf(fid,'%s\n',imagen); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%s\\n"),

imagen, NULL)); /* * fprintf(fid,'%i\n',N); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"), N,

NULL)); /* * fprintf(fid,'%s\n',tipovig); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%s\\n"),

tipovig, NULL)); /* * fprintf(fid,'%s\n',sentido); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%s\\n"),

sentido, NULL)); /* * fprintf(fid,'%i\n',umbral2); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"),

umbral2, NULL));

204

Proyecto fin de carrera Gonzalo Leandro Bravo

/* * fprintf(fid,'%i\n',valor); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"), valor,

NULL)); /* * fprintf(fid,'%i\n',N1); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"), N1,

NULL)); /* * fprintf(fid,'%i\n',N2); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"), N2,

NULL)); /* * fprintf(fid,'%i\n',color); */ mclAssignAns(&ans, mlfFprintf(fid, mxCreateString("%i\\n"), color,

NULL)); /* * * fclose(fid); */ mclAssignAns(&ans, mlfFclose(fid)); /* * fprintf(1,'La inicialización a finalizado correctamente, puede

ejecutar el programa de vigilancia\n'); */ mclAssignAns( &ans, mlfFprintf( mlfScalar(1.0), mxCreateString( "La inicializaci\363n a finalizado correctamente" ", puede ejecutar el programa de vigilancia\\n"), NULL)); mxDestroyArray(A); mxDestroyArray(Azul); mxDestroyArray(B); mxDestroyArray(I); mxDestroyArray(N); mxDestroyArray(N1); mxDestroyArray(N2); mxDestroyArray(Rojo); mxDestroyArray(Verde); mxDestroyArray(a); mxDestroyArray(actual); mxDestroyArray(ans); mxDestroyArray(azul);

205

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mxDestroyArray(azulmedia); mxDestroyArray(azulvar); mxDestroyArray(cinco); mxDestroyArray(color); mxDestroyArray(colorvec); mxDestroyArray(diez); mxDestroyArray(diferencia); mxDestroyArray(dos); mxDestroyArray(fid); mxDestroyArray(igual10); mxDestroyArray(igual15); mxDestroyArray(igual20); mxDestroyArray(igual5); mxDestroyArray(imagen); mxDestroyArray(mediaigual10); mxDestroyArray(mediaigual15); mxDestroyArray(mediaigual20); mxDestroyArray(mediaigual5); mxDestroyArray(mediasimil); mxDestroyArray(minigual10); mxDestroyArray(minigual15); mxDestroyArray(minigual20); mxDestroyArray(minigual5); mxDestroyArray(minsimil); mxDestroyArray(quince); mxDestroyArray(rojo); mxDestroyArray(rojomedia); mxDestroyArray(rojovar); mxDestroyArray(sentido); mxDestroyArray(siguiente); mxDestroyArray(simil); mxDestroyArray(stdigual5); mxDestroyArray(stdsimil); mxDestroyArray(tamano); mxDestroyArray(temp); mxDestroyArray(tipovig); mxDestroyArray(tres); mxDestroyArray(umbral); mxDestroyArray(umbral2); mxDestroyArray(uno); mxDestroyArray(valor); mxDestroyArray(verde); mxDestroyArray(verdemedia); mxDestroyArray(verdevar); /* * * * *

206

Proyecto fin de carrera Gonzalo Leandro Bravo

* %El tiempo de ejecuciion se pierde en abrir el fichero bmp pues aunque analice el mismo trozo se tarda mucho mas

* %cuando el fichero es de mayor tamaño */ } /* * The function "mlfConfigurar" contains the normal interface for the * "configurar" M-function from file * "D:\escuela\Matlab\work\funcionaC\inicial\configurar.m" (lines 1-

140). This * function processes any input arguments and passes them to the

implementation * version of the function, appearing above. */ void mlfConfigurar(void) { mlfEnterNewContext(0, 0); Mconfigurar(); mlfRestorePreviousContext(0, 0); } /* * The function "mlxConfigurar" contains the feval interface for the * "configurar" M-function from file * "D:\escuela\Matlab\work\funcionaC\inicial\configurar.m" (lines 1-

140). The * feval function calls the implementation version of configurar through

this * function. This function processes any input arguments and passes them

to the * implementation version of the function, appearing above. */ void mlxConfigurar(int nlhs, mxArray * plhs[], int nrhs, mxArray *

prhs[]) { if (nlhs > 0) { mlfError( mxCreateString( "Run-time Error: File: configurar Line: 1 Column:" " 0 The function \"configurar\" was called with m" "ore than the declared number of outputs (0)")); } if (nrhs > 0) { mlfError( mxCreateString( "Run-time Error: File: configurar Line: 1 Column" ": 0 The function \"configurar\" was called with" " more than the declared number of inputs (0)")); } mlfEnterNewContext(0, 0); Mconfigurar();

207

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

mlfRestorePreviousContext(0, 0); } 6.5.2. configurar_main.c /* * MATLAB Compiler: 2.0 * Date: Mon Nov 12 11:40:54 2001 * Arguments: "-m" "configurar" */ #ifndef MLF_V2 #define MLF_V2 1 #endif #include "matlab.h" #include "dimensiones.h" #include "std2.h" #include "mean2.h" #include "lecconfigurar.h" #include "bmptrozoini.h" #include "bmpinicial.h" #include "bmpallini.h" #include "configurar.h" static mlfFunctionTableEntry function_table[8] = { { "dimensiones", mlxDimensiones, 1, 2 }, { "std2", mlxStd2, 1, 1 }, { "mean2", mlxMean2, 1, 1 }, { "lecconfigurar", mlxLecconfigurar, 0, 5 }, { "bmptrozoini", mlxBmptrozoini, 5, 1 }, { "bmpinicial", mlxBmpinicial, 1, 3 }, { "bmpallini", mlxBmpallini, 2, 1 }, { "configurar", mlxConfigurar, 0, 0 } }; /* * The function "main" is a Compiler-generated main wrapper, suitable

for * building a stand-alone application. It initializes a function table for use * by the feval function, and then calls the function "mlxConfigurar".

Finally, * it clears the feval table and exits. */ int main(int argc, const char * * argv) { mxArray * varargin = mclInitialize(NULL);

208

Proyecto fin de carrera Gonzalo Leandro Bravo

mlfEnterNewContext(0, 0); mlfFunctionTableSetup(8, function_table); mlfAssign(&varargin, mclCreateCellFromStrings(argc - 1, argv + 1)); mlfFeval( mclAnsVarargout(), mlxConfigurar, mlfIndexRef(varargin, "{?}", mlfCreateColonIndex()), NULL); mxDestroyArray(varargin); mlfFunctionTableTakedown(8, function_table); mlfRestorePreviousContext(0, 0); return 0; }

6.6. VideoCapX.ocx CapAbortESCKey property Returns/sets flag indicating will ESC key stop capturing process. Syntax object.CapAbortESCKey [ = Boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True or False Settings This flag is TRUE by default. Data Type Boolean CapAbortLeftMouse property Returns/sets flag indicating will left mouse click stop streaming capture. Syntax object.CapAbortLeftMouse [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Settings Remarks The default value for this property is FALSE. Data Type Boolean CapAbortRightKey property Returns/sets flag indicating will right mouse click stop streaming

capture.

209

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

Syntax object.CapAbortRightMouse [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Settings Remarks The default value for this property is FALSE. Data Type Boolean CapTimeLimitEnabled property Returns/sets flag indicating will CapTimeLimit property be used during

capture. Syntax object.CapTimeLimitEnabled [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Settings Remarks The default value for this property is FALSE. If this value is TRUE video capture will stop after CapTimeLimit

seconds. Data Type Boolean CaptureAudio property Returns/sets flag indicating will video capture include audio. Syntax object.CaptureAudio [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Settings Remarks The default value is TRUE. If this value is FALSE, captured video will have no sound. Data Type Boolean HitOKToCapture property Returns/sets user initiated capture flag. Syntax

210

Proyecto fin de carrera Gonzalo Leandro Bravo

object.HitOKToCapture [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Remarks The default value is FALSE. If this value is TRUE, VideoCapX displays

a dialog box prompting the user to initiate capture. Data Type Boolean PreviewScale property Returns/sets flag indicating does preview image scale to fit whole control

size. Syntax object.PreviewScale [ = boolean ] The syntax has these parts: Part Description object An object expression that evaluates to a VideoCapX object. boolean True / False Remarks The default value is TRUE. If this is FALSE, image in preview window

will be exact size as captured, and if it is TRUE, image will stretch to fit control size on screen.

Data Type Boolean Connected property The Connected property connects / disconnects a capture window to a

capture driver. Syntax VideoCapX.Connected = True ‘Connect driver VideoCapX.Connected = False ‘Disconnect driver Remarks Connecting a capture driver to a capture window automatically

disconnects any previously connected capture driver. Preview property The Preview property enables or disables preview mode. In preview

mode, frames are transferred from the capture hardware to system memory and then displayed in the capture window using GDI functions.

Syntax VideoCapX.Preview = True VideoCapX.Preview = False Remarks

211

Captación, análisis y tratamiento de imágenes BMP orientados a la videovigilancia.

The preview mode uses substantial CPU resources. Applications can disable preview or lower the preview rate when another application has the focus. Enabling preview mode automatically disables overlay mode.

ShowVideoFormatDlg() method The ShowVideoFormatDlg method displays a dialog box in which the

user can select the video format. The Video Format dialog box might be used to select image dimensions, bit depth, and hardware compression options.

Syntax ShowVideoFormatDlg() Return value Returns TRUE if successful or FALSE otherwise. Remarks The Video Display dialog box is unique for each capture driver. Some

capture drivers might not support a Video Display dialog box. Applications can determine if the capture driver supports this message by checking the DriverHasVideoFormatDlg property.

ShowVideoSourceDlg() method The ShowVideoSourceDlg method displays a dialog box in which the

user can control the video source. The Video Source dialog box might contain controls that select input sources; alter the hue, contrast, brightness of the image; and modify the video quality before digitizing the images into the frame buffer.

Syntax ShowVideoSourceDlg() Return value Returns TRUE if successful or FALSE otherwise. Remarks The Video Display dialog box is unique for each capture driver. Some

capture drivers might not support a Video Display dialog box. Applications can determine if the capture driver supports this message by checking the DriverHasVideoSourceDlg property.

CopyFrame() method The CopyFrame macro copies the contents of the video frame buffer and

associated palette to the clipboard. Syntax CopyFrame() Return value Returns TRUE if successful or FALSE otherwise. SaveFrame() method The SaveFrame method saves current video frame into BMP file. Syntax SaveFrame(filename As String) Return value

212

Proyecto fin de carrera Gonzalo Leandro Bravo

213

Returns TRUE if successful or FALSE otherwise. Remarks If the capture driver supplies frames in a compressed format, this call

attempts to decompress the frame before writing the file. Existen otros métodos y procedimientos que puediran ser de ayuda en

caso de pretender ampliar, mejorar o modificar este programa que se encuentran disponibles en la ayuda de esta librería.