Professional Documents
Culture Documents
NDICE
Pg.
0. Introduccin. 4
1.Fase 1. Estudio del sistema de vigilancia, deteccin de movimiento. 1.1. Anlisis por similitud (Correlacin).
10 10
1.1.1. Descripcin de las funciones a utilizar. SIMILITUD DE FOTOGRAMAS. 1.1.2. Inicio de las simulaciones. 1.2. Anlisis por igualdad. 11 14 18
1.2.1. Descripcin de las funciones a utilizar. IGUALDAD DE FOTOGRAMAS. 1.2.2. Inicio de las simulaciones. 18 20
1.2.3. Conclusiones relativas al anlisis por similitud e igualdad. 23 1.3. Nuevos anlisis. Verificacin de conclusiones. 1.4. Simulacin en exteriores y ausencia de movimiento. 1.4.1. Revisin de las funciones a utilizar. 1.4.2. Inicio de las simulaciones. 1.4.2.1.Secuencia exterior. 1.4.2.2.Secuencia con movimiento aleatoreo. 1.4.2.3.Ausencia de movimiento. 1.5. CONCLUSIONES DE FASE 1. 25 27 27 32 32 36 37 41
2.2. Nuevo sistema de trabajo. Programacin adaptable a C para leer ficheros BMP. 2.3. Programa en Matlab. 44 46
2.3.1. Lectura de datos del sistema. 2.3.2. Cuerpo principal. 2.3.3. Lectura de ficheros BMP 2.3.3.1. Lectura de imagen completa BMP 2.3.3.2. Lectura de franja de imagen BMP 2.4. Programas en C. 2.5. Eficiencia. Anlisis de tiempos de realizacin. 2.6. Vigilancia de regiones rectangulares. 2.7. Inicializacin del sistema. 2.8. Inicializacin del sistema en Matlab. 2.8.1. configurar.m 2.8.2. Lectura fichero configurar. lecconfigurar.m 2.8.3. Lectura BMP en tres colores. bmpinicial.m 2.8.4. Resto de ficheros. 2.9. Inicializacin del sistema en C 2.10. Manual del programa de Vigilancia y Configuracin.
46 51 54 55 57 60 61 67 69 77 77 81 83 85 85 85
3. FASE 3. Programa de captacin de fotogramas. 3.1. Introduccin 3.2. Programacin en Visual BASIC 6.0. de Microsoft. 3.2.1. Cuerpo principal. frmMain 3.2.2.Guardar BMP en, frmguardar 3.2.3. Vigilar. frmvigilar 3.2.4. Vigilancia limitada. frmvigilarlimitada 3.2.5. Acerca de..., frmayuda 3.3. Manual Capturadora. 3.3.1. Menu Archivo. 3.3.2. Menu Vigilancia. 3.3.2.1. Vigilar. 3.3.2.2. Vigilancia limitada. 3.3.3. Menu CopiarImagen. 3.3.4. Menu Herramientas. .3.5. Menu Acerca de.
5. Conclusiones.
116
6. ANEXOS 6.1. Ayuda del comando fread 6.2. Ayuda del comando fseek 6.3. Ayuda del compilador de Matlab 6.4. Cdigos fuente en C de programa de vigilancia. 6.4.1. vigila.c 6.4.2. vigila_main.c 6.4.3. lectot.c 6.4.4. N1N2.c 6.4.5. bmpallrap.c 6.4.6. bmptrozorap.c 6.4.7. vigila.h 6.4.8. vigila_main.h 6.4.9. lectot.h 6.4.10. N1N2.h 6.4.11. bmpallrap.h 6.4.12. bmptrozorap.h 6.5. Cdigos fuente en C de programa de inicializacin. 6.5.1. configurar.c 6.5.2. configurar_main.c 6.6.VideoCapX.ocx
119 119 120 121 125 125 137 138 157 166 176 187 188 188 189 189 190 190 190 208 209
0. Introduccin.
Los complicados momentos que nos toca vivir plantean un permanente desafo tecnolgico en cuanto a la mejor manera de preservar la integridad fsica y patrimonial de su familia y de s mismo. Dado que un edificio de propiedad horizontal, normalmente es accedido por un sinnmero de transentes, resulta a menudo difcil 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 algn lugar es la base de la existencia de estos equipos, los cuales mantienen la seguridad en la entrada a comercios, oficinas, industrias, reas de almacn, reas de diseo, laboratorios, reas de desarrollo etc. Cada vez ms en alza, los sistemas de vigilancia por Circuito cerrado de TV (CCTV) resultan una de las mejores alternativas en su relacin costo - prestaciones, a la hora de dotar de seguridad a un edificio. Se pueden disponer tantas cmaras 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 cmaras captan con uno o ms monitores, ubicados frecuentemente en las oficinas de conserjera o vigilancia, e inclusive con la posibilidad de monitorear secuencialmente las mismas, esto es, una vista alternativa de cada cmara o una imagen de pantalla partida en dos o cuatro, segn sea necesario. Asimismo, es posible incorporar una video grabadora "Time Elapsed" de velocidad lenta, que permite registrar varias horas de imgenes en un simple video VHS de modo que tendremos registrados en cinta todos los ingresos y distintos movimientos acaecidos en el da. En los ltimos aos este tipo de sistemas de Video observacin 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.
Cuando la vigilancia o la seguridad requieren de una observacin totalmente discreta, el sistema de video inalmbrico, puede ir discretamente disfrazado en un extintor de fuego; en un libro de lectura; en un maletn; en el marco de un cuadro; o camuflado en un elemento personal. Cada sistema es diseado para generar cientos de imgenes de alta resolucin de unos metros de distancia hasta varios kilmetros cuando es usado en conjunto con un repetidor de video. La cmara ultra-miniatura con lentes de diferentes ngulos y ajuste automticos instantneos 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 cmaras ocultas de 1", cmaras que llegan a observar perfectamente hasta 3 Km de distancia en las condiciones ms adversas tanto de noche y da, fro o calor extremo, interiores y exteriores, color y blanco y negro, formatos NTSC y PAL, tambin observar a 360 desde su escritorio o domicilio a la distancia que requiera, observar en un solo monitor hasta 32 cmaras al mismo tiempo, grabar hasta por 3 meses los sucesos ocurridos, grabadoras digitales con capacidades de grabacin asombrosas que eliminan el uso de videocasetes todas estas y muchas ventajas ms que tienen el objetivo de ver todo lo que se quiera ver. Otra solucin 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 tcnicas en tratamiento de imagen estn permitiendo la creacin de nuevas aplicaciones diseadas exclusivamente para optimizar y facilitar los actuales sistemas de vigilancias con videocmaras. Todo lo que necesita es disponer de una cmara de vdeo, un ordenador y un software de observacin personal. Es en este punto donde vamos a intervenir realizando un estudio que nos resulte base para el posterior desarrollo de una aplicacin de videovigilancia automatizada con control por PC. En nuestro caso no vamos a utilizar una cmara de vigilancia ni vamos a procurar el anlisis de un nmero determinado de imgenes, nos limitaremos a comprobar que es lo que le ocurre a una imagen a nivel estadstico de pxel cuando comparamos secuencias correspondientes a la captacin de una cmara domstica.
Realizaremos un sistema automatizado de captacin de fotogramas (Visual BASIC) y un software de vigilancia (desarrollado en lenguaje Matlab y C). Al detectar un intruso, un sistema de vigilancia automatizado podra disparar la alarma, grabar la escena, enviar la foto del intruso por mail, avisarle en su busca o telfono, 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 seal de alarma el resto de utilidades no debe entenderse como una utopa. Ya estn 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, adems de todas los relacionados con la tecnologa digital que en los ltimos cinco aos se han ido aplicando son: Los sistemas convencionales basados en cmara y grabador necesitan almacenar imgenes las 24 horas del da. Con nuestro sistema slo se almacena cuando es realmente necesario, lo que redunda en un considerable ahorro en soportes de almacenamiento. Los sistemas convencionales slo miran y es necesario aadir complejos y costosos mecanismos adicionales para adoptar medidas complementarias. Con nuestro sistema slo se necesita para estar protegido una cmara, un ordenador personal y el software de control. Demostramos y aplicamos tcnicas de fotogramas por segmentos que nos proporcionan la misma eficacia de vigilancia que el anlisis 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. Anlisis de la imagen en tiempo real (10 fps) como valor predeterminado, pero pudiendo realizar un anlisis 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
menor
coste.
Sus mltiples aplicaciones y el reducido coste lo convierten en el sistema ms verstil, gracias al uso de componentes comerciales muy difundidos y de fcil y rpida sustitucin en caso de averas o modificacin de especificaciones.
Uno de las principales caractersticas de este sistema es el uso de franjas horizontales y verticales para realizar el control de imgenes. Como podemos comprobar en los siguiente ejemplos analizar pequeas regiones rectangulares sobre un plano plantea un muro infranqueable sobre la instancia observada.
Colocando una cmara donde marcamos con una equis podemos analizando slo una franja vertical detectar cualquier individuo que saliera de los ascensores.
En el caso de que deseemos impedir cualquier paso entre puertas nos bastara colocar una nueva franja para estar completamente seguros con este sistema. Evitndonos un anlisis completo de la imagen que s podramos ver en el monitor al ser advertidos de la intrusin.
Podramos incluso centrarnos en una de las puertas si ahora nuestro plano es horizontal, detectando el mnimo 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 continuacin, algunos objetivos se han cumplido, otros se han desechado por el camino por considerarlos inviables y los ms estn aun por investigar por algn compaero que desee como yo conocer y aportar algo ms al mundo de la seguridad. De una manera esquemtica indicamos a continuacin qu se va a encontrar el lector de este proyecto y cmo debe enfrentarse a las aplicaciones que se acompaan. 1. Tenemos que comprobar de entre una multitud de opciones cuales resultan ms eficaces a la hora de comparar imgenes y en qu circunstancias se van a utilizar. 2. Comprobado cuando podemos utilizar estos sistemas vemos cmo conseguir que sean rpidos y eficaces en cualquier situacin. 3. Concluimos que no podemos sacar generalidades y que debemos someter a nuestro sistema a un proceso de inicializacin. 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 adquisicin de imgenes BMP. 5. Enlazando ambos sistemas conseguimos un sistema de videovigilancia en tiempo real. Con el esquema que muestro a continuacin.
PROGRAMA DE VIDEOVIGILANCIA
NO EST INICIALIZADO?
SI MODIFICAR DATOS
NO
INICIALIZAR
SI SI NO OK?
SI TODO OK? NO
REVISAR EL SISTEMA
10
funciones
utilizar.
Son secuencias pequeas en tamao y duracin (15seg), de baja calidad, pero que nos han servido para empezar a trabajar. Por cada una de las secuencias tenemos 385 fotogramas de un tamao 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 ejecucin. Para lo cual utilizamos una funcin denominada generar.m: Que queda definida como:
function aux=generar(nombre,inicio,tamano) %salida=generar('nombre_fichero',foto_inicio,Nde 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 mayora de los casos con la imagen completa, sino con una franja de la misma creamos una funcin que tome el trozo que luego analizaremos. Esto es la idea originaria de este proyecto. Posteriormente comprobaremos que adems 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
A esta funcin la llamaremos cuando queramos analizar una parte de la imagen comprendida entre las lneas 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 funcin mostrar.m que nos muestra una franja blanca en la regin en la que estamos trabajando. La funcin 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 imgenes ya disponibles en memoria, adems el segundo de ellos slo lo utilizaremos para mostrar resultados de la prueba. Hay que aclarar que el anlisis de imgenes est poco desarrollado a nivel de lenguajes de programacin 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 anlisis parcial de imgenes.
12
Una vez determinado cmo podemos seleccionar una parte dentro del fotograma comenzamos ahora a analizar las secuencias de imgenes, es decir la relacin de cada una de ellas con las anteriores. En primer lugar hemos de crear una funcin que estudie la correlacin (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 correlacin 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+orde n,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
Algunos notas aclaratorias sobre el sistema utilizado en esta funcin 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 aadido en este punto para facilitar el sistema de trabajo y hacer ms 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 correlacin da un valor proporcional a la media y en imgenes muy uniformes el ms mnimo cambio es considerado como importante. -Para solucionar esto a partir de este punto utilizaremos una correlacin que no realice operaciones sobre la media, de esta manera el sistema funciona mejor, pero ahora la imagen debe cambiar ms para detectar un movimiento. -Parece bastante agradecido a cambios considerables en la distancia entre imgenes de correlacin. -Aunque pudiera resultar ilgico presentar en este proyecto aquello que no funciona, hemos de decir en nuestra defensa que en el mbito didctico es tan til conocer lo que podemos hacer como lo que no podemos hacer. Por lo que espero sirvan mis errores e intentos intiles para que no se vuelvan a cometer.
14
NOTA: El pico primero es porque se mueve la cmara al comenzar la grabacin. Esta imagen muestra la correlacin de los 385 fotogramas, hay que decir que la simulacin de estos 15 segundos se realiz en unos 60 segundos por lo que su posible utilizacin tal y como est planteado es inviable. Por otro lado y con respecto al estudio estadstico en el que nos centramos en esta primera fase queda suficientemente marcado la existencia de movimiento y en su ausencia mantiene un valor prximo 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 slo una franja vertical a la entrada del lateral izquierdo del pasillo correspondiente a las columnas 45 a 49 tendremos:
15
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 slo franjas funciona bien. A continuacin haremos lo mismo para otra secuencia de video que nos muestra un saln 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 tamaos.
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
En este 1.1.Anlisis por Similitud no hay clculo 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 comparacin la funcin 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 pequea.
17
funciones
utilizar.
Ahora en 1.2. Anlisis por Igualdad vamos a comprobar los valores exactos que existen entre fotogramas haciendo un XOR entre pixels. Esto ser un segundo mtodo para comparar imgenes, posteriormente veremos que cada uno de los sistemas planteados tienen sus pros y sus contras pero que segn las circunstancias de las cmaras ambos son tiles. Para hacer este clculo utilizamos un for anidado que nos enlentece tremendamente la simulacin. En esta primera fase esto no fue tenido en cuenta pues es en la fase 2 de este proyecto en el que realizaremos anlisis temporal buscando la mxima eficiencia. A partir de esta segunda fase trabajaremos con matrices que como comprobaremos acelera las simulaciones.
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
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 utilizacin obtenemos las siguientes conclusiones: -Tarda demasiado tiempo en comprobar la imagen completa y los resultados son incoherentes para orden 1, es decir imgenes consecutivas, por que los fotogramas son iguales cada tres. Esto es debido a que la calidad de video, el nmero de fotogramas es dependiente de medio utilizado para la captacin 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 anlisis en tiempo real a ms de 30 fotogramas por segundo resulta limitado por el sistema de captacin utilizado. -Las imgenes no son exactamente iguales nunca, inconveniente que no se presenta cuando utilizamos la correlacin, de hay la diferenciacin entre
19
ambas. Con este mtodo estamos midiendo cuan de iguales son las imgenes y con el anterior medimos cuan de similares son. -Aunque esto puede deberse a un posible defecto de la cmara ya que con la correlacin no daba problema, comprobaremos posteriormente que no es exactamente cierto. Para solucionar este problema y hacer til este sistema de deteccin de movimiento hemos de aadir 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 aadimos una fuerte dependencia entre el margen que hemos definido y el valor umbral que consideramos como de alarma. La calidad de la grabacin determina el margen a la hora de considerarlos iguales. Nosotros para las simulaciones hemos utilizado esta funcin con un margen de +-10, aunque posteriormente comprobamos que el umbral deba de ser inferior para conseguir los resultados deseados. En un principio esto parece un retroceso en las prestaciones pero tambin comprobamos que se redujo el valor mnimo alcanzado, por lo que en cualquier caso aseguramos la eficacia del mtodo.
20
Ahora la ausencia de movimiento no se mide tan prxima al cero, pero la intrusin da un valor de cambio prximo al 80%. En este paso la mala calidad del video no nos permitira 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 saln tendremos que la correlacin es:
21
Llegamos a las mismas conclusiones anteriores. Ms 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 resultara muy sensible al ruido.
22
Tal vez el anlisis de la imagen completa no sea la solucin, los resultados vemos que son mejores para franjas del fotograma.
En el anlisis por similitud el funcionamiento es mas eficiente y realizamos una correlacin 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 imgenes a correlar. Conclusiones:
23
-Ahora las imgenes que son cercanas y sin cambio, adems tienen un valor de correlacin muy prximo a la unidad (>0.98 e incluso 0.99). -Los cambios quedan sumamente marcados tanto en la cercana como ms 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 pequeos 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 pequeo. Tendremos dificultades para diferenciar en estos casos ruido de movimiento pero esto lo solucionamos posteriormente realizando un programa de inicializacin que determina para cada circunstancia de video un umbral determinado. Como parte positiva diremos que lo probado hasta estos momentos funciona con una pequea carga computacional y que adems lo hace bastante bien. Comprobamos incluso que funciona incluso con un cuadro 5x5, que es una cantidad muy pequea a analizar. Posteriormente se estudiarn medias y varianzas para sacar conclusiones sobre los valores que sirven de criterio en cada situacin 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 tomarn a la hora de realizar el sistema de inicializacin.
24
A continuacin trabajamos con nuevas secuencias de imgenes que se encuentran en 4 videos de 15 segundos de duracin y de mejor calidad y mayor tamao que los dos anteriores, ahora es una secuencia grabada con una cmara de video e introducida en el ordenador a travs de una capturadora de video proporcionada por el fabricante Avermedia junto con la tarjeta de televisin TVCapture 98 y convertidos en fotogramas posteriormente con el programa VirtualDub de libre distribucin en Internet. Ya se deja entrever en la presentacin que en este proyecto se intenta realizar un programa independiente de las caractersticas externas del sistema de vigilancia que se encuentre implantado. Por ello se decide actuar a nivel de imagen de TV, y tambin 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 comprobacin de viabilidad y funcionamiento es suficiente. Es posible que en el hipottico caso de un desarrollo posterior sea necesario trabajar con un nuevo dispositivo de captacin con un mayor nmero de entradas, aunque siempre buscaremos sistemas que se acojan a los estndares 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 sern 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 tamao 175 X 288 X 384, con lo que su estudio se hace ms lento y pesado al tener que realizar mltiples simulaciones por partes, haciendo de esta manera ms complicado sacar conclusiones. Ante este problema modificamos los programas para que mantengan en memoria el menor nmero posible de fotogramas. Este cambio de poltica en lo referente al sistema de lectura de archivos BMP lo tendremos que tomar o bien 25
en estos momentos o bien ms adelante, pero es absolutamente necesario en el momento en el que nos planteamos un sistema en tiempo real donde no se pueden almacenar imgenes 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 variacin en este caso hemos optado por analizar una lnea horizontal no al completo. Utilizaremos en primer lugar ejemplo1. Similitud
Notar que ahora la lnea horizontal no es de extremo a extremo, esto queda impuesto por determinaciones de la imagen. Se trata de un pasillo y slo nos interesa estudiar la transicin desde el fondo.
26
Vemos por un lado que es mucho ms rpida que en el caso de analizar la imagen completa, esto era de esperar, las imgenes estn en memoria y hemos de analizar un menor nmero de pixels. El valor medio ahora en ausencia de movimiento es: 0.999 (que es un buen valor), ahora el sistema de captacin 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 ntida. La falta de claridad es debida al proceso de conversin a blanco y negro, su traslado a fichero de texto y su posterior impresin. 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 anlisis dura demasiado tiempo (ms de 90 segundos). -Para analizar esta misma imagen y la misma franja bajo la puerta tenemos que los cambios son considerables y la funcin no la podemos utilizar. Slo 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 imgenes no parece una buena idea. Segn parece resulta ms 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 mtodos.
1.4. Simulacin en exteriores y ausencia de movimiento. 1.4.1. Revisin de las funciones a utilizar.
27
A continuacin trabajamos con secuencias de duracin variable (~1 minuto) y de igual calidad que los dos anteriores, las secuencias son grabadas con una cmara de video e introducidas en el ordenador a travs de una capturadora de video. Las nuevas funciones se denominan largo1.m y largo2.m y son equivalentes en funcin 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
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
Adems hemos aadido la posibilidad de analizar la imagen completa en la misma funcin 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
%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
end end
Las modificaciones realizadas nos obligan a cambiar tambin 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
end end
1.4.2.1.Secuencia exterior.
Comenzamos con la secuencia denominada calle1, en el que tenemos 965 fotogramas de un tamao 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. Anlisis por Similitud, 2 y 3 de manera que ahora tenga en memoria slo en fotograma actual y el anterior que son los dos que deseo comparar. Comenzamos analizando una lnea de la imagen de calle1 por similitud tambin en una pequea regin de la imagen.
32
Este video muestra una calle sobre la que pasa un vehculo en torno al fotograma 775. La imagen superior representa la activacin de la alarma. La alarma se produce, el cambio es significativo pero vemos, comprobando el video que el vehculo pasa realmente en torno al fotograma 740, lo detectamos un poco tarde. Esto puede deberse a que el vehculo es oscuro y al pasar a escala de grises pasa un poco inadvertido, pero eso no debera ser as. Debemos tener en cuenta que en imgenes 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 mnimo que alcanza 0.9249, vemos por otro lado que podamos solucionar el problema de la deteccin tarda aumentando el umbral que estaba colocado en 0.95. Parece que podramos poner el umbral de alarma cercano al 0.98, con lo aceleraramos la activacin. 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
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 mtodo slo es vlido con sistemas en los cuales el cambio sea significativamente grande en relacin con la zona a vigilar. Intentando solucionar este problema, ahora vamos a comprobar si podemos utilizar largo2, que realiza la comparacin XOR e intentar buscar un umbral que nos d resultados coherentes ya que parece que con el anlisis 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.
34
Afortunadamente funciona bastante bien. Detecta el vehculo en el momento preciso de llegar a la lnea (fotograma 743), la media en ausencia de movimiento es la unidad (magnifico) y el valor mnimo es 0.5317.
Afortunadamente funciona muy, muy bien. Detecta el vehculo en el momento preciso de llegar a la lnea (fotograma 739), la media en ausencia de movimiento es 0.9945 (magnifico) y el valor mnimo es 0.3268. Que nos da una diferencia sustancial de trabajo. Adems no resulta demasiado lento al tener el cuadro a analizar un tamao de 200 pixels.
Vamos ahora a comprobar que ocurre en caso de analizar la imagen completa. (+-5).
35
Vemos que es difcil de apreciar la entrada del coche, y aunque s aparece, el valor diferencial que nos da es pequeo. La media en ausencia de movimiento es 0.9561 y el mnimo 0.8818 y cuando aparece el coche tenemos un valor mnimo de 0.8742, que es una diferencia pequea. Parece una conclusin acertada que ninguno de esto mtodos es til en caso de anlisis de la imagen completa. Segn vemos en la grfica 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 apreciacin ser tenida en cuenta posteriormente.
36
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 mnimo es 0.9848, que es muy prximo a lo anterior y el valor medio incluso mayor 0.9848. Dejaremos este apartado porque parece una excepcin de lo que queremos hacer ya que es una imagen exterior con continuos movimientos lejanos, ajeno este situacin 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 tamao 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 extraar que tengamos valores con resultados engaosos.
37
Resultando
-La media en ausencia de movimiento es 0.9992 -El valor mnimo es 0.8543. Con largo2 (+-5), igualdad, resultados;
38
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 mnimo es 0.5485 que por un lado tiene una media lejana de uno, pero por otro lado la imagen de valor mnimo 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 mnimo.
39
Aumentaremos el umbral a 0.8. La media en ausencia de movimiento es 0.9892 y el valor mnimo 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.
Utilizando largo1.
40
En este caso la media en ausencia de movimiento es 0.9994 y el valor mnimo 0.9668. Como siempre la correlacin es buena en ausencia de movimiento, pero el pico de movimiento es menor.
41
-Un criterio de calidad de las imgenes es la varianza de los pixels. -Aparentemente la correlacin es ms rpida, aunque an queda por comprobar como funciona sustituyendo el bucle for por clculo con matrices.
Del anlisis de estos datos y de otras pruebas debera de salir el criterio para decidir los valores umbrales segn la situacin.
42
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
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 opcin 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 slo para analizar el sistema de vigilancia pero no para realizar un programa ejecutable.
2.2. Nuevo sistema de trabajo. Programacin adaptable a C para leer ficheros BMP.
A pesar de continuar trabajando con Matlab ahora la programacin que utilizamos debe cumplir una serie de requisitos para que se nos permita su posterior compilacin, para ello hemos optado por hacer la lectura del fichero BMP byte a byte, procurando en cada caso y segn el anlisis que furamos a realizar leer exclusivamente los bytes que nos son necesarios. Para hacer esto hay que tener en cuenta que una vez ledos los bytes iniciales de una imagen BMP y posicionados al principio de la imagen nos encontramos con una variacin 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
44
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, instruccin que acepta tanto Matlab como C, los datos tras la lectura estarn disponibles de la siguiente forma: Imagen= R41G41B41R42G42B42R43G43B43R44G44B44R45G45B45 R31G31B31R32G32B32R33G33B33R34G34B34R35G35B35R21G21B21R22 G22B22R23G23B23R24G24B24R25G25B25R11G11B11R12G12B12R13G13 B13R14G14B14R15G15B15
Por otro lado y buscando que el sistema se lo ms rpido posible slo realizaremos la lectura de uno de los tres colores que representan a la imagen BMP. Aado este sistema tan grfico pues la lectura de datos es uno de los principales problemas a la hora de conseguir que nuestro sistema resulta rpido y por lo tanto eficaz. Si se desea hacer un anlisis profundo sobre las especificaciones del formato BMP se recomienda revisar los cdigos de los programas de lecturas de tales imgenes donde se realiza paso a paso de una manera muy indicativa como debe de ser la cabecera que acompaa a estas imgenes.
45
imagen: Cadena de caracteres con el nombre del fichero sin extensin debe ir entre comillas. N: Numero de fotogramas que voy a analizar, posteriormente se anulara su valor. tipovig: Parmetro utilizado para decidir si se utiliza una funcin u otro para el anlisis del sistema. Esto se decide durante la inicializacin. Puede tomar dos valores:
46
'igual' concede un valor de igualdad y 'simil' utiliza correlacin. sentido: Indica el sentido Puede tomar tres valores: 'all' 'ver' 'hor' de la lnea de vigilancia.
umbral: valor en tanto por cien sobrepasado el cual se considera alarma. 0->Detecta cualquier cambio por mnimo que sea 100->La imagen permanece inmvil 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
47
En este caso se analiza la secuencia de imgenes comprendidas entre pasillo1 y pasillo300, utilizando el mtodo de similitud (correlacin), 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 mtodo de igualdad. Anotamos en este punto que en caso de anlisis vertical u horizontal una franja de 5 pixels de anchura suele ser suficiente. Para leer este fichero hemos desarrollado una funcin que nos comprueba que los valores son correctos en tipo y valor y que se encuentran segn 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
%--------------------------------------------------------------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
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
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 cdigo podra ser literalmente compilado en C. Adems se ha procurado que esta funcin resulte un filtro de parmetros para mi programa, es decir, ante cualquier anomala en el valor de los mismo no se para la ejecucin, sino que se toman unos valores por defecto. En lectot.m se llama a la funcin N1N2.m que devuelve las dimensiones de la imagen para poder comprobar que me encuentro dentro de los lmites. 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 dara error y se parara la ejecucin del programa. El cuerpo de esta funcin no se aade al ser igual que el de bmpallrap.m con valores de salida el tamao de la imagen, sin realizar la lectura de la imagen.
51
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 imgenes 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
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(su m(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(su m(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 funcin realiza una vigilancia limitada en el tiempo pues le indicamos el nmero de fotogramas que queremos analizar (N) y nos muestra
53
por pantalla y en el fichero intruso.txt aquellos instantes en los que ha habido cambio. En la fase de realizacin en tiempo real esta funcin ser modificada para realizar la vigilancia para un nmero ilimitado de fotogramas e ir borrando de memoria aquellos en los que no detecte cambio. De esta manera evitamos la saturacin 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 ms rpido que el de captacin (con un mximo de 30 fps) por lo que hacerlo esperar por ejemplo de segundo en caso de no encontrar un fotograma slo nos influye en la posibilidad de detectar un movimiento de segundo ms tarde, pero en ningn caso de no hacerlo.
54
Aunque en un principio el anlisis de una franja es suficiente para detectar cambios de movimientos, como se indic en la fase 1 de proyecto, se deja esta opcin 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 comprensin de las funciones de lectura.
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
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 end;
Bitmap BMP.');
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
return; end
Comienza el fichero con unas comprobaciones de parmetros de entrada y abriendo el fichero con la ayuda de fopen, posteriormente comenzamos la lectura byte a byte de las caractersticas de la imagen: Tamao, profundidad, nmero de bits, tipo de compresin, 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 inicializacin todo esto ser tenido en cuenta y se seleccionar el color de mayor variabilidad y de media ms centrada. Vamos a buscar el color que es ms fcil que nos d alarma. El vector de salida ser de este tipo: Si color = 0 (Rojo), Imagen=R41R42R43R44R45R31R32R33R34R35R21R22R23R24R25R11R12 R13R14R15 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 tamao uchar (1byte), de forma que lee uno salta dos, lee uno salta dos,...hasta completar el tamaa 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.
57
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 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');
Bitmap BMP.');
58
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 funcin es idntica y slo 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 tendramos a la salida, Imagen=R31R32R33R34R35R21R22R23R24R25
59
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 anlisis de tiempos de ejecucin 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 acompaa nos obliga a hacer una programacin muy similar a la que hubiramos utilizado de haber optado por realizar todo el proceso de simulacin en C. A pesar de ello y una vez conseguido realizar las funciones que deseamos sin acudir a la librera de imgenes que Matlab nos presenta realizamos la compilacin de estos ficheros utilizando el comando.
mcc m vigila
En el Anexo 6.3 se acompaa la ayuda de la instruccin 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.
De esta manera creamos unos ficheros.c que se acompaan como Anexo 6.4. Son;
60
Estos ficheros se acompaan como Anexo porque debido a su compilacin automtica la asignacin de nombre a las variables no es representativa y por lo tanto hace su anlisis demasiado complicado. Teniendo en cuenta que son traducciones de los programas en Matlab se recomienda su anlisis para comprender el funcionamiento del sistema. Con estos ficheros hemos conseguido una aplicacin que funciona y se acompaa al proyecto.
Imagen 1. (Imagen captada en tiempo real con videocmara domstica con ayuda del programa desarrollado en la fase 3, tamao 144x192).
61
Imagen 2. (Imagen captada en tiempo real con videocmara domstica con ayuda del programa desarrollado en la fase 3, tamao 288x384).
Como muestra de los resultados se acompaa una serie de tablas donde podemos ver los tiempos que se tarda en cada una de las posibles situaciones de simulacin. Las mediciones realizadas de tiempo han sido conseguidas con la ayuda de Matlab aplicando el comando cputime que nos permite conocer tiempo de ejecucin. Este comando da una precisin 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 aplicacin en s siempre ser ms rpida. 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
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 ejecucin.
Conceptos de inters. PEQ.- 144x192 GRA.- 288x384 simil.- Realiza la correlacin para comprobar como de similares con las imgenes. igual.- Comprueba byte a byte si con iguales a los anteriores con un valor de tolerancia.
Anlisis completo por simil Anlisis completo por igual T1 T2 T3 T1 T2 T3 0 0.05 7.47 0 0.06 7.75 0 0.05 7.76 0 0.05 8.22 0 0.20 33.10 0 0.22 39.55 0 0.20 35.61 0 0.16 28.89
Teniendo en cuenta que la simulacin corresponde a 15 segundos resulta imposible realizar con este sistema la vigilancia en las imgenes completas de mayor tamao. Por otro lado vemos que el problema que se nos plantea no tiene solucin pues el tiempo es empleado en leer las imgenes de memoria.
63
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 imgenes completas que alcancen un determinado tamao. Aunque en la fase 1 la realizacin de la vigilancia por similitud o por igualdad requeran un tiempo de simulacin diferentes, en esos momentos parece que el tiempo empleado en ambos casos es muy parecido.
Si ahora analizamos slo una franja vertical u horizontal de anchura 5 pixel tenemos los siguientes resultados. Utilizaremos nicamente el anlisis por similitud.
Anlisis horizont por simil T1 T2 T3 0 0 0.77 0 0 0.99 0 0.06 2.15 0 0.05 2.30
Anlisis vertical por simil T1 T2 T3 0 0 3.84 0 0 4.06 0 0.07 8.18 0 0.05 8.24
La primera conclusin es que los tiempo se reducen considerablemente y que en un principio la vigilancia sera posible. Decimos que en un principio porque este tiempo de ejecucin 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 adems de comprobar el cambio en las imgenes 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
Hay que destacar la diferencia existente entre la vigilancia horizontal y la vertical. Tardamos cuatro veces ms en hacer el anlisis 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 podramos modificarla. Si entramos en detalles sobre cmo 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 pxeles de una lnea. 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 mnimo medible de 0.05 En este caso ante los comandos ver con N1=2 y N2=3 tendramos que la imagen resultante en el vector de datos es. Imagen=R42R43R32R33R22R23R12R13
65
Pero para responder a la posible pregunta de qu es lo que retarda el sistema, si la lectura (T2=0) o la utilizacin del comando for planteamos una nueva forma para leer al que aadimos tambin 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 ms corto, en nuestro ejemplo entraramos en l slo cuatro veces y la imagen que tendramos quedara ordenada de la siguiente forma.
Imagen=R42R32R22R12R43R33R23R13 Que aparentemente debiera de ser ms rpido, 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 pxeles, para la imagen pequea (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 funcin 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 pequeos prximos muchas veces que hacer 66
pocas veces la lectura de datos muy separados en el fichero. El salto entre lectura relentiza el sistema.
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
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 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');
Bitmap
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
En este caso se devuelve una matriz y en la opcin de igual habra que modificar la opcin
a(I)=sum(abs(actual-siguiente)<valor)/(tamano);
por
a(I)=sum(sum(abs(actual-siguiente)<valor))/(tamano);
Esta opcin no est permitida en el ejecutable que se acompaa. Y se menciona como una posible mejora al sistema planteado.
69
Estos parmetros son aquellos que quedan ajenos a mi sistema de vigilancia y estn relacionados con la interrelacin 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 imgenes, el nmero 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 cmara. Como ya mencionamos anteriormente, un pasillo por ejemplo, se aconseja vigilar con solo una franja, pero una habitacin que no es de paso es preferible hacer el anlisis completo. En el cdigo de Matlab del programa de lectura se puede ver el formato que se debe especificar en este fichero. Un ejemplo sera: 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 anlisis 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 inicializacin rpido pues esta aplicacin slo debe aplicarse al comenzar a trabajar o bien cuando las condiciones de la cmara 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
Para ello abrimos las 150 imgenes 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 tamao Ancho X Largo. Realizamos la media y la varianza correspondiente a cada fotograma, esto se almacena en un vector. A continuacin 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 fotografa. 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 ms de estas condiciones y lo asignamos como color de nuestro sistema. Tipo de vigilancia, umbral y valor son tres parmetros 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 anlisis 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; anlisis por similitud y anlisis por igualdad para un margen de 5, 10, 15 y 20. En este caso no analizaremos valores para cada fotograma, sino para cada posible situacin de comparacin. Para las cuales calcularemos la media, la varianza y el valor mnimo.
71
Anlisis de la imagen total: Para una secuencia de tamao 144x192 tendremos; PRUEBA 1 0.5500 0.0344 0.5059 0.8708 0.0205 0.8368 0.9748 0.0057 0.9607 0.9923 0.0027 0.9856 0.9985 1.7778e-004 0.9981 PRUEBA 2 0.8967 0.0122 0.8748 0.9943 0.0033 0.9864 0.9989 0.0011 0.9956 0.9997 3.9597e-004 0.9985 0.9997 3.7907e-005 0.9996
mediaigual5 = stdeigual5 = minigual5 = mediaigual10 = stdeigual10 = minigual10 = mediaigual15 = stdeigual15 = minigual15 = mediaigual20 = stdeigual20 = minigual20 = mediasimil = stdsimil = minsimil = (Tabla 1)
Para una secuencia de tamao 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
Anlisis de la imagen HORIZONTAL: Para una secuencia de tamao 5x192 tendremos; PRUEBA 1 0.6141 0.0345 0.5391 0.8733 0.0238 0.8299 0.9655 0.0103 0.9375 0.9853 0.0057 0.9740 0.9991 1.8096e-004 0.9986 PRUEBA 2 0.9029 0.0195 0.8568 0.9931 0.0068 0.9722 0.9985 0.0026 0.9887 0.9995 0.0015 0.9948 0.9997 6.5709e-005 0.9995
mediaigual5 = stdeigual5 = minigual5 = mediaigual10 = stdeigual10 = minigual10 = mediaigual15 = stdeigual15 = minigual15 = mediaigual20 = stdeigual20 = minigual20 = mediasimil = Stdsimil = minsimil = (Tabla 3)
Para una secuencia de tamao 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
nlisis de la imagen VERTICAL: Para una secuencia de tamao 5x192 tendremos; PRUEBA 1 0.5661 0.0429 0.4889 0.8876 0.0271 0.8222 0.9875 0.0065 0.9694 0.9991 0.0014 0.9917 0.9989 1.6296e-004 0.9985 PRUEBA 2 0.9151 0.0127 0.8708 0.9997 6.9564e-004 0.9958 1 0 1 1 0 1 0.9996 3.0389e-005 0.9995
mediaigual5 = stdeigual5 = minigual5 = mediaigual10 = stdeigual10 = minigual10 = Mediaigual15 = stdeigual15 = minigual15 = Mediaigual20 = stdeigual20 = minigual20 = Mediasimil = Stdsimil = minsimil = (Tabla 5)
Para una secuencia de tamao 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
Como punto de partida podemos decir que nos interesa que la varianza sea mnima, es decir que tengamos una situacin de no alarma bastante definida. Observamos que la mxima varianza la obtenemos siempre para igual 5 y la mnima para simil. Esto nos puede llevar a pensar que en todos los casos la situacin de simil es la deseada. Los valores de las tablas indican que la media y el valor mnimo en el caso simil estn muy prximos entre s y muy prximos a la unidad, por lo que en estas situaciones el ms mnimo cambio nos dara una situacin de alarma indeseada. Concluimos pues que aunque desearamos utilizar siempre este sistema de deteccin, slo 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 anlisis por similitud toma un valor mnimo de la comparacin inferior a 0.999. Esto demuestra que la eleccin 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 decisin 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 ms pequea, pero tambin que nuestro margen sea el ms pequeo posible pues, por ejemplo, en caso de decidirnos por 20 es posible que muchas de las situaciones de cambio pasen inadvertidas.
75
5 IMAGEN PEQUEA a 10 10 0.0027 0.0046 a 15 15 4.1121e-004 8.1684e-004 a 20 5 0.0930 0.1518 IMAGEN GRANDE a 10 10 0.0027 0.0073 a 15 15 3.3559e-004 0.0011 a 20 (Tabla 7). Mejora del nivel medio.
0.0015
0.0050
3.4955e-004
9.8574e-004
0.1484
0.0879
0.0082
0.0023
0.0018
3.2159e-004
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 prximo, ampliaremos al siguiente margen siempre que el cambio nos resulte significativo, es decir, siempre que sea superior a 0.005. Segn la tabla de resultados Tabla 7 la situacin 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 acompaan en esta memoria, se considera la posibilidad de que la opcin optima sea igual 20, siempre con este mismo criterio de seleccin. Decidido qu tipo de vigilancia vamos a utilizar en cada caso, debemos ahora determinar un umbral para esta situacin, para ello utilizaremos el conocimiento que tenemos del valor mnimo y medio en cada situacin.
76
Se tomar para cada situacin seleccionada el valor mnimo menos la diferencia entre el valor medio menos el mnimo, o lo que es lo mismo, permitimos el doble de movimiento de lo que est considerado como no movimiento. La precisin 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.
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
%--------------------------------------------------------------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 indicara 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 pequeo %3 La variacin 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
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.*act ual))*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 ms 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
if a==2 valor=15; umbral=(10000*(minigual15-(mediaigual15-minigual15))); else valor=20; umbral=(10000*(minigual20-(mediaigual20-minigual20))); end end end %realizo esta operacin para conseguir que umbral sea un nmero 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 inicializacin 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 anlisis para poder ejecutar el programa de vigilancia.
80
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 anlisis ilimitado en el tiempo % %sentido: Indica el sentido de la lnea 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
%--------------------------------------------------------------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
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 %---------------------------------------------------------------
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
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 end;
Bitmap BMP.');
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
return; end
del
programa
de
Vigilancia
En primer lugar hemos de aclarar que no buscamos una aplicacin comercial, sino que se trata de una primera fase, fase de investigacin y realizacin simplificada de un sistema de vigilancia por comparacin de fotogramas haciendo uso de tratamiento digital de imagen.
85
Es muy importante tener en cuenta que en ninguno de estos casos se he procurado conseguir un interfaz con el usuario cmodo y fcil de manejar y que ambas aplicaciones son aplicaciones MS-DOS generadas con ayuda de Matlab. Durante la ejecucin de los programas de vigilancia y configuracin se han aadido mensajes suficientes para en caso de error guiar al usuario hacia la resolucin del mismo, adems para cualquier conocedor del lenguaje de programacin Matlab una lectura de los ficheros lectot.m (2.3.1.) y lecconfigurar.m (2.8.2.) le permitiran su correcto uso. Aun as haremos una serie de indicaciones que consideramos de inters y que es posible an no se hayan mencionado. Antes de ejecutar el programa de vigilancia deben existir en la misma carpeta la imagen1.bmp y el fichero de inicializacin camara.txt. Este fichero puede ser creado con ayuda de este programa de configuracin 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 funcin fgetl.m que retorna el contenido de una lnea 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 lnea 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 ejecucin del programa de captacin 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 inicializacin y finaliza. Hemos de tener en cuenta que el fichero camara.txt no desaparece al interrumpir la ejecucin ya que se considera que las cmaras a vigilar no cambian sus condiciones en el periodo estudiado. Por lo tanto hemos de tener la precaucin didctica de borrar dicho fichero cuando variemos la situacin de la imagen captada. Antes de inicializar hemos de acudir a la capturadora y aplicar los valores por defecto de la opcin vigilancia limitada (3.3.2.2.)
86
Para proceder a la inicializacin hemos de crear, esta vez obligatoriamente, con al ayuda del bloc de notas un fichero denominado indicaciones.txt con el nombre de las imgenes con el que la capturadora almacena los fotogramas, el nmero de fotogramas a analizar, el sistema empleado (all, ver o hor) y las franjas que deseamos en caso de ser anlisis vertical u horizontal. Se recomienda colocar N1 y N2 a 1 cuando el anlisis va a ser total. Si la inicializacin transcurre sin incidencias nos aparece un mensaje indicndonoslo y ahora podremos realizar la vigilancia. Al estar trabajando con programas MS-DOS todos los ficheros, programas e imgenes deben encontrarse en la misma direccin (carpeta). Una vez realizado todo este proceso podemos proceder como se indica en la fase 4 de realizacin en tiempo real a la ejecucin conjunta de ambos programas. Activando el de capturar en el modo vigilancia ilimitada y el de seguridad puesto simplemente en ejecucin. De una manera esquemtica ser:
87
COMENZAMOS SEGURIDADTPR
SI
EXISTE CAMARA.TXT?
SISTEMA ACTIVO
NO SI DETENER CAPTURAS
NO
OK?
INICIALIZAR
FIN EJECUCION
88
3.1. Introduccin
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 unin entre ambos. Para realizar la captura se utilizar a modo de versin 1.0. una videocmara domstica conectada al PC a travs 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 captacin de seal que utiliza la tarjeta de Avermedia. La solucin a este problema la encontramos en los controles ActiveX videocapx.ocx de Visual BASIC que permiten la sincrona y la captacin de datos utilizando funciones predefinidas. Esto conlleva otro problema, tener la necesidad de conseguir un relativo dominio de un lenguaje de programacin tan amplio como es Visual BASIC. Indicar tambin que aunque los lenguajes de programacin visuales son nuevos para el autor de este proyecto, me ha permitido aprender las posibilidades que actualmente se presenta con estos mtodos de programacin que permiten un interfaz con el usuario mucho ms grfico y verstil. Como en un principio se plantea este programa de captacin como independiente al de vigilancia decidimos continuar por este camino y desarrollar esta aplicacin de captacin de fotogramas en tiempo real.
89
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 cmara 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 captacin de imgenes, 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
End Sub Copia una imagen al portapapeles Private Sub mnuporta_Click() vcx.CopyFrame End Sub Desconecta la cmara 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 visualizacin 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
vcx.ShowVideoSourceDlg End Sub Private Sub Text1_Validate(Cancel As Boolean) vcx.CapFilename = Text1.Text End Sub Muestran los formularios principales del programa en relacin a la captacin de fotogramas. Private Sub mnuvigilar_Click() frmvigilar.Show End Sub Private Sub mnuvigilarlimitada_Click() frmVigilarlimitada.Visible = True End Sub
La opcin cancelar descarga el formulario solicitado, vuelve atrs Option Explicit Private Sub cmdcancelar_Click() Unload Me End Sub
93
Disponemos de la opcin de buscar la ruta que deseamos para almacenar nuestro fichero.bmp, por omisin esta es la de ejecucin 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
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 Declaracin 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
95
tiempo de captura como el nmero de fotogramas por segundo capturados. (Ver 3.3. Manual.5)
Definicin de variables a utilizar y caractersticas de las mismas. Option Explicit Dim i As Integer Dim z As Integer Dim nombre As String Dim archivo As String Controla que slo se active la lectura distinta del valor predeterminado 10 para nmero 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 slo se active la lectura distinta del valor predeterminado 15 para tiempo de captacin. 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 opcin de buscar la ruta que deseamos para almacenar nuestro fichero.bmp, por omisin esta es la de ejecucin del programa. Private Sub cmdruta_Click() dlg.Filter = " Archivos BMP (*.bmp)|*.bmp|Todos (*.*)|*.*" dlg.DefaultExt = ".bmp" dlg.FileName = "" dlg.ShowSave
96
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
Cuerpo del timer que guarda los fotogramas con diferentes nombre, para ello utiliza un contador, esta funcin 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
98
(Imagen Manual.1) Como se puede observar el interfaz con el usuario es idntico al empleado por Microsoft. En el men aparecen cinco opciones.
(Imagen Manual.2)
99
Nos permite desconectar la cmara sin necesidad de cerar el programa, con esta opcin la pantalla aparece en negro. Al iniciar el programa siempre comenzamos conectados.
3.3.2.1. Vigilar.
(Imagen Manual.4)
100
Nos da paso a una ventana que nos permite realizar por tiempo ilimitado captacin a 10 fotogramas por segundo. Esto est realizado expresamente para trabajar con el programa de vigilancia.
(Imagen Manual.5) Con esta pantalla podemos realizar capturas modificando tanto el tiempo de realizacin como el tiempo entre fotogramas. Se ha indicado como valores por omisin los necesarios para inicializar el sistema. Los valores de grabacin durante 15 segundos a 10 fotogramas por segundo sern tenidos en cuenta siempre que las opciones de Detener captura tras y Variar Fotogramas por segundo a aparezcan desmarcadas.
101
La tercera opcin que nos aparece en el men vigilancia no despliega ninguna nueva ventana, sino que interrumpe cualquier grabacin que est realizndose en ese momento, bien sea limitada o ilimitada.
(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
(Imagen Manual.8) Este men est integramente formado por opciones pertenecientes a comandos Actives. Encajar ventana nos permite cambiar el tamao de la imagen que vemos por la pantalla del ordenador, hay que tener en cuenta que los recursos requeridos aumentan proporcionalmente con el tamao de la pantalla. Esta opcin se deshabilita marcando nuevamente sobre ella. Formato video nos permite cambiar el tamao predefinido de la imagen, se recomienda utilzar o . Para que posteriormente estas imgenes se pueden abrir con el programa de vigilancia es necesario que est marcada la opcin 24 bit RGB
103
(Imagen Manual.9)
Entrada video, en esta ventana podemos cambiar la entrada de video, pudiendo escoger entre Tuner (TV), Composite(Cmara de video) y Svideo(Monitor). Aqu podemos tambin modificar las caractersticas luminosas de la imagen. Se acondeja dejarlas en el valor central en cada caso.
(Imagen Manual.10)
104
(Imagen Manual.12)
105
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
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(su m(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(su m(siguiente.*siguiente))); actual=siguiente; if a(I)<umbral fprintf(1,'Alarma en el fotograma %i\n',I); else
107
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
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
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
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 ejecucin por falta de imgenes\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
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 ejecucin por falta de imgenes\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
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
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
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
5. Conclusiones.
El programa cuyo cdigo aparece en el apartado anterior en lenguaje Matlab es la versin definitiva de este proyecto fin de carrera aunque se ha optado por no presentar el cdigo en C y el ejecutable por no considerar esta opcin de vigilancia y seguridad conjunta funcionalmente til. El sistema S funciona, pero se recomienda en caso de desear su utilizacin en un sistema de seguridad real la integracin de ambos en uno solo, para lo cual consideramos de debera utilizar como base el programa de captacin de Visual BASIC y aadirle el sistema de vigilancia teniendo en cuenta todo lo mostrado anteriormente. De esta manera conseguiramos aumentar la velocidad de anlisis al no tener que leer las imgenes de memoria. Llegados a este punto resumiremos todo lo que cualquier lector de este proyecto se ha encontrado en las pginas anteriores. Aunque no se ha conseguido una aplicacin completa de un sistema de vigilancia se ha realizado un estudio sobre anlisis de movimientos en la fase 1, estudio de tiempos de ejecucin y de acceso a ficheros bmp en la fase 2, se ofrecen los cdigos fuentes tanto en Matlab como en C del sistema de inicializacin y vigilancia y el cdigo fuente del programa de captacin de Visual BASIC. Adems de todo esto a este proyecto se acompaan cuatro ejecutables en disco adjunto: 1. -Sistema de comparacin de fotogramas por sistema ptimo para la deteccin de movimiento. 2. -Sistema de captacin en tiempo real de fotogramas a travs de cmara domstica. Existen versiones similares de este programa en Internet, pero estn destinados a capturar videos que podemos posteriormente convertir en fotogramas, no existe ningn programa que nos permita realizar lo que nosotros hemos conseguido: Capturar hasta 50 fotogramas por segundo en tiempo real. 3.- Sistema de inicializacin de la cmara para optimizacin de la vigilancia. 4.-Conjunto de funciones de matlab que ejecutados conjuntamente con el programa de captacin nos realiza tareas de vigilancia.
116
Por todo lo expuesto anteriormente podemos afirmar casi son absoluta certeza la posibilidad de idear un sistema de vigilancia que a travs de un PC controle y compruebe la existencia de movimiento en las imgenes analizando su contenido. El tiempo requerido en comprobar el movimiento, sin tener en cuenta la lectura en disco de los fotogramas bmp, es considerablemente pequeo y el sistema de anlisis por franjas efectivo. Como puntos en los que se pudiera realizar una continuacin en este proyecto ya se dej entrever de posibilidad de realizar una versin mejorada del sistema de captacin que incluyera comparacin de imgenes para de esta manera conseguir un sistema de vigilancia eficaz y un interfaz con el usuario grfico. Todo lo planteado nos lleva a considerar la posibilidad de analizar con xito el tratamiento de mltiples cmaras reduciendo el nmero de fotogramas en cada una de ellas. Aqu aparecera otro problema a solucionar, la necesidad de disponer de todas ellas en memoria simultneamente para poder procesarlas. Como posible solucin se podra plantear la modulacin en diferentes canales de cada una de las imgenes ofrecidas por las cmaras. A quien pudiera interesar continuar con lo que aqu he expuesto en forma de proyecto de fin de carrera quedara encantado en colaborar aportando mis conocimientos sobre el sistema desarrollado, puede ponerse en contacto conmigo a travs de la direccin de correos gleandro@worldonline.es. Aunque los sistemas de seguridad deberan ser innecesarios en algunas ocasiones nunca est de ms 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, stanos y
terrazas. Los vehculos estacionados en las cocheras debern estar cerrados , evitando dejar en su interior objetos de valor.
117
Abra la puerta de su vivienda recin cuando haya identificado al requirente por la mirilla. Los empleados de las empresas de servicios, correos, TV por cable, etc, debern acreditarse exhibiendo su credencial. Evite ingresar a los ascensores con personas extraas o que le resulten sospechosas. Evite que personas extraas ingresen o circulen por el edificio sin ser controladas. Evite que los nios viajen solos en los ascensores. Podran sufrir algn accidente. Cuando solicite encargos a domicilio, recbalos en la puerta del edificio. No abra cuando pretendan llevar un recado para un vecino. No coloque nombres, direcciones, o nmeros de telfono 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 telfono. Si sospecha que lo estn siguiendo camino a casa desvese de la direccin de su domicilio y solicite ayuda. Cuando llegue a su domicilio hgalo 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 algn 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 automvil, pase de largo si advierte la presencia de personas sospechosas en las proximidades del portn 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, jams 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 quin se encuentra al otro lado de la puerta. Muchas gracias por conseguir llegar hasta este punto de lectura. Gonzalo Leandro.
118
6. ANEXOS
The following platform dependent formats are also supported but they are not guaranteed to be the same size on all platforms. 'char' 'short' 'int' 'long' 'char*1' 'short' 'int' 'long' character, 8 bits (signed or unsigned). integer, 16 bits. integer, 32 bits. integer, 32 or 64 bits.
119
'unsigned short' unsigned integer, 16 bits. 'unsigned int' unsigned integer, 32 bits. 'unsigned long' unsigned integer, 32 bits or 64 bits. 'float' floating point, 32 bits.
The following formats map to an input stream of bits rather than bytes. 'bitN' 'ubitN' signed integer, N bits (1<=N<=64). 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.
120
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.
121
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 Mfiles. 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
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
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
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.1. vigila.c
/* * MATLAB Compiler: 2.0 * Date: Mon Nov 19 19:21:13 2001 * Arguments: "-m" "vigila" */ #include "vigila.h"
125
#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 imgenes 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
&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
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
mlfAssign(&siguiente, mlfBmpallrap(B, color)); /* * a(I)=sum(abs(actual-siguiente)<valor)/(tamano); */ mlfIndexAssign( &a, "(?)", I, mlfMrdivide( mlfSum( mlfLt(mlfAbs(mlfMinus(actual, siguiente)), NULL), tamano));
valor),
/* * 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
* 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
*/ 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
* 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
&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
*/ 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
/* * 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 tamao */ }
135
/* * 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
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
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
* % 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 lnea 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
*/ 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
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
*/ 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
/* * %-------------------------------------------------------------------* 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
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
*/ 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
/* * 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
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
* 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
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
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
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
* 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
} 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
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
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
* 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
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
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
* 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
&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
fid,
mlfScalar(1.0),
mxCreateString("uint"),
/* * bfReserved1=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved1, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * bfReserved2=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved2, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * bfOffBytes=fread(fid,1,'uint'); */ mlfAssign( &bfOffBytes, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * * biSize=fread(fid,1,'uint'); */ mlfAssign( &biSize, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("ushort"),
mxCreateString("ushort"),
mxCreateString("uint"),
mxCreateString("uint"),
/* * 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
} /* * * biWidth=fread(fid,1,'uint'); */ mlfAssign( &biWidth, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("ushort"),
mxCreateString("ushort"),
mxCreateString("uint"),
/* * if biCompression~=0 */ if (mlfTobool(mlfNe(biCompression, mlfScalar(0.0)))) { /* * error('No puede leer ficheros BMP comprimidos.'); */ mlfError(mxCreateString("No puede leer ficheros comprimidos.")); /* * end; */ }
BMP
162
/* * biSizeImage=fread(fid,1,'uint'); */ mlfAssign( &biSizeImage, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biXPels=fread(fid,1,'uint'); */ mlfAssign( &biXPels, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biYPels=fread(fid,1,'uint'); */ mlfAssign( &biYPels, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biClrUsed=fread(fid,1,'uint'); */ mlfAssign( &biClrUsed, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biClrImportant=fread(fid,1,'uint'); */ mlfAssign( &biClrImportant, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
/* * * * 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
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
/* * * */ 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
"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
* 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
*/ 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
* 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
* * bfSize=fread(fid,1,'uint'); */ mlfAssign( &bfSize, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * bfReserved1=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved1, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * bfReserved2=fread(fid,1,'ushort'); */ mlfAssign( &bfReserved2, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * bfOffBytes=fread(fid,1,'uint'); */ mlfAssign( &bfOffBytes, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * * biSize=fread(fid,1,'uint'); */ mlfAssign( &biSize, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("ushort"),
mxCreateString("ushort"),
mxCreateString("uint"),
mxCreateString("uint"),
/* * 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
/* * end; */ } /* * * biWidth=fread(fid,1,'uint'); */ mlfAssign( &biWidth, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("ushort"),
mxCreateString("ushort"),
mxCreateString("uint"),
/* * if biCompression~=0 */ if (mlfTobool(mlfNe(biCompression, mlfScalar(0.0)))) { /* * error('No puede leer ficheros BMP comprimidos.'); */ mlfError(mxCreateString("No puede leer ficheros comprimidos.")); /*
BMP
171
* end; */ } /* * biSizeImage=fread(fid,1,'uint'); */ mlfAssign( &biSizeImage, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biXPels=fread(fid,1,'uint'); */ mlfAssign( &biXPels, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biYPels=fread(fid,1,'uint'); */ mlfAssign( &biYPels, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biClrUsed=fread(fid,1,'uint'); */ mlfAssign( &biClrUsed, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biClrImportant=fread(fid,1,'uint'); */ mlfAssign( &biClrImportant, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("uint"),
172
* 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
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
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
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 184). 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
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
* 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
fid,
mlfScalar(2.0),
mxCreateString("uchar"),
/* * 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
mlfFread(NULL, NULL));
fid,
mlfScalar(1.0),
mxCreateString("uint"),
mxCreateString("uint"),
/* * 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), NULL)); /* * biHeight=fread(fid,1,'uint'); */ mlfAssign( &biHeight, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biPlanes=fread(fid,1,'ushort'); */ mlfAssign( &biPlanes, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("uint"),
mxCreateString("uint"),
mxCreateString("ushort"),
180
/* * biBitCount=fread(fid,1,'ushort'); */ mlfAssign( &biBitCount, mlfFread(NULL, fid, mlfScalar(1.0), NULL)); /* * biCompression=fread(fid,1,'uint'); */ mlfAssign( &biCompression, mlfFread(NULL, fid, mlfScalar(1.0), NULL));
mxCreateString("ushort"),
mxCreateString("uint"),
/* * 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
fid,
mlfScalar(1.0),
mxCreateString("uint"),
mxCreateString("uint"),
/* * * * 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
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
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
&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
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 184). 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 184). 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
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
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
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
#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
190
#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
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), NULL); mclForNext(&iterator_0, &I); ){ /* * B=[imagen, num2str(I+1)]; */ mlfAssign( &B, mlfHorzcat( imagen, mlfNum2str(mlfPlus(I, NULL)); /* * [Rojo,Verde,Azul]=bmpinicial(B); */
mlfScalar(149.0),
mlfScalar(1.0)),
NULL),
192
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
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
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 indicara 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 pequeo * %3 La variacin 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
* 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, NULL)); /* * siguiente=bmpallini(B,color); */ mlfAssign(&siguiente, mlfBmpallini(B, color));
mlfScalar(1.0)),
NULL),
196
/* * 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(s iguiente.*siguiente))); */ mlfIndexAssign( &simil, "(?)", I, mlfMrdivide(
197
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, 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,
mlfScalar(1.0)),
NULL),
198
mlfMrdivide(mlfSum(mlfLt(temp, tamano));
mlfScalar(5.0)),
NULL),
/* * 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(s iguiente.*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
/* * 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
*/ 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 ms 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
*/ 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
/* * 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 operacin para conseguir que umbral sea un nmero 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
} /* * 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
/* * 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 inicializacin 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
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
* %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 tamao */ } /* * The function "mlfConfigurar" contains the normal interface for the * "configurar" M-function from file * "D:\escuela\Matlab\work\funcionaC\inicial\configurar.m" (lines 1140). 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 1140). 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
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
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
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
210
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
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
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 mtodos 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 librera.
213