Anda di halaman 1dari 96

Objetivos e Inters Septiembre 2013

INGENIERA DE TELECOMUNICACIN
rea de Teora de la Seal y Comunicaciones Departamento de Ingeniera Electrnica
PORTADA

E.T.S.I. U.S.

DETECCIN DE ANUNCIOS DE TELEVISIN MEDIANTE SOFTWARE

PROYECTO FIN DE CARRERA


Autor | Director Daniel Jess Martnez Campos | Jos Ramn Cerquides Bueno II

Agradecimientos:
Con la presentacin del presente proyecto final de carrera no solo se acaba un proyecto, sino que se termina una de las etapas ms duras y largas de mi vida. Llegado a este punto hay que mirar atrs y debo reconocer con humildad que debo dar las gracias a muchas personas. Empezar dando las gracias a mis compaeros de carrera: a los que empezaron y se quedaron y a los que se fueron, y a los que estuvieron en mi vida pero ahora estn ausentes. Especialmente agradecido estoy con mis compaeros, profesores y amigos de Mxico, los cuales me aportaron mucho tanto en lo acadmico como en lo personal. No tengo palabras para agradecer el apoyo, el cario y el amor que me ha brindado mi guapsima novia Carmen, sin cuya ayuda no habra podido entregar a tiempo este proyecto. Tengo mucho que agradecer a mis compaeros, excompaeros, jefes y amigos de trabajo de CATEC y SolarMEMS porque son unos grandsimos profesionales y mejores personas. Tambin estoy especialmente agradecido a Jos Ramn Cerquides, tutor de este proyecto, por confiar en m para la realizacin del mismo y por haberme dado todo tipo de facilidades para presentarlo. Pese a que a veces pareca que me ponan zancadillas y piedras en el camino tambin estoy agradecido a la comunidad de profesores de la ETSI, especialmente a los profesores de los primeros cursos, como Alberto Casado o Antonio Gonzlez. Pero todo lo anterior carecera de sentido sin el apoyo incondicional de mis padres a los cuales les debo todo, por lo que nunca les estar lo suficientemente agradecido, as como a mi familia en general que siempre me ha brindado su cario y apoyo. Muchas gracias a todos, de corazn.

Contenido ndice
PORTADA .................................................................................................................................................... 0 Agradecimientos: .................................................................................................................................... 1 ndice ............................................................................................................................................................ 0 Lista de Figuras ........................................................................................................................................ 1 1. 2. OBJETIVOS E INTERS ................................................................................................................ 1 ESTADO DEL ARTE ....................................................................................................................... 2 2.1. 2.2. 2.3. 3. 3.1. 3.2. DESARROLLO HISTRICO ................................................................................................. 2 ENUMERACIN DE TCNICAS ........................................................................................ 3 OTRAS TECNOLOGAS......................................................................................................... 7 INTRODUCCIN ..................................................................................................................... 8 TEORA.................................................................................................................................... 12 Conversin a Escala de Grises.............................................................................. 12 Clculo de la Media ................................................................................................... 13 Determinacin del Valor Umbral........................................................................ 13 Clculo de la Frecuencia de Muestreo .............................................................. 14 Arquitectura del Hardware ................................................................................... 17 Ordenador ................................................................................................................ 17 Tarjeta de Televisin DVB - USB .................................................................... 18 Arquitectura del Software ..................................................................................... 19 Sistema Operativo ................................................................................................ 19 DirectX 11 SDK ....................................................................................................... 20 Breve Descripcin del Sistema ............................................................................ 21 Aplicaciones ................................................................................................................. 22 Algoritmos .................................................................................................................... 23 Algoritmo de generacin de huellas ............................................................. 23 Algoritmo de deteccin de anuncios ............................................................ 25 Generacin de Huellas............................................................................................. 27

MEMORIA DESCRIPTIVA ........................................................................................................... 8

3.2.1. 3.2.2. 3.2.3. 3.2.4. 3.3. 3.3.1. 3.3.1.1. 3.3.1.2. 3.3.2. 3.3.2.1. 3.3.2.2. 3.4. 3.4.1. 3.4.2. 3.4.3. 3.4.3.1. 3.4.3.2. 3.5. 3.5.1.

ARQUITECTURA DEL SISTEMA.................................................................................... 17

DESCRIPCIN DEL SISTEMA ......................................................................................... 21

MANUAL DE USUARIO ..................................................................................................... 27

II

Contenido
3.5.2. 3.5.3. 3.5.3.1. 3.5.3.2. 4. 4.1. Deteccin de Anuncios ............................................................................................ 29 Paso a paso ................................................................................................................... 30 Generacin de huellas ......................................................................................... 30 Deteccin de anuncios ........................................................................................ 32

PRUEBAS, RESULTADOS Y CONCLUSIONES................................................................... 36 PRUEBAS Y RESULTADOS .............................................................................................. 36 Configuracin previa a la realizacin de las pruebas ................................ 36 Pruebas .......................................................................................................................... 36 Pruebas de deteccin de anuncios ................................................................ 36 Pruebas de degradado ........................................................................................ 38 4.1.1. 4.1.2. 4.1.2.1. 4.1.2.2. 4.2.

Conclusiones......................................................................................................................... 41

5.

BIBLIOGRAFA ............................................................................................................................. 45

ANEXO: CDIGO FUENTE ................................................................................................................. 46

III

Lista de Figuras

Lista de Figuras
Figura 1: Ejemplo de cambio de plano ......................................................................................................... 8 Figura 2: Estructura de pxeles en una secuencia de vdeo......................................................................... 12 Figura 3: Falso cambio de plano ................................................................................................................. 14 Figura 4: Esquema de generacin de una huella ........................................................................................ 15 Figura 5: Ordenador ................................................................................................................................... 17 Figura 6: Dispositivo USB sintonizador ....................................................................................................... 18 Figura 7: Sistema operativo ........................................................................................................................ 19 Figura 8: DirectX ......................................................................................................................................... 20 Figura 9: Visual Studio Express Edition ....................................................................................................... 21 Figura 10: Esquema del algoritmo de generacin de huellas ..................................................................... 24 Figura 11: Esquema del algoritmo de deteccin de huellas ....................................................................... 26 Figura 12: Programa de generacin de huellas .......................................................................................... 27 Figura 13: Programa de deteccin de anuncios ......................................................................................... 29 Figura 14: Seleccin del archivo de huellas ................................................................................................ 30 Figura 15: Archivo de salida de huellas ...................................................................................................... 31 Figura 16: Seleccin de fuente de vdeo ..................................................................................................... 32 Figura 17: Seleccin del archivo de huellas ................................................................................................ 33 Figura 18: Seleccin del archivo de anuncios ............................................................................................. 34 Figura 19: Salida del archivo de anuncios .................................................................................................. 34 Figura 20: Seleccin de la fuente de vdeo ................................................................................................. 35 Figura 21: Probabilidades de deteccin de anuncios y de falso cambio de plano ...................................... 37 Figura 22: Frecuencia de ocurrencia de las huellas para distintas calidades de vdeo ............................... 39 Figura 23: Probabilidad de error de deteccin de anuncio en funcin de la calidad de vdeo.................... 40 Figura 24: Huella de 12 bits frente a 48 bits ............................................................................................... 41 Figura 25: Histograma de escala de grises para determinacin de umbral de negro ................................ 43

IV

Objetivos e Inters

1. OBJETIVOS E INTERS
La publicidad es una forma de dar a conocer un producto, sus caractersticas y funcionamiento a la gente [4]. Los anuncios de televisin han sido hasta el momento el sistema publicitario ms potente y extendido, jugando un papel importante en las vidas de las personas. Para las empresas comerciales son instrumentos esenciales de marketing para llamar la atencin sobre sus productos y aumentar sus ventas [1]. Los anuncios son una gran fuente de ingresos para los operadores por lo que los anunciantes son muy celosos sobre el impacto de los anuncios y se preocupan de que su difusin sea la requerida mediante la realizacin de un seguimiento estadstico de los mismos [4]. Esto determina la presencia de empresas a las que los anunciantes acuden para verificar que sus anuncios de televisin son realmente emitidos segn lo contratado. En la actualidad, para realizar dicha verificacin se utilizan a grupos de individuos que completan una serie de encuestas. Sera deseable transferir esta tarea a un sistema informtico [1]. La deteccin automtica de los anuncios de televisin es un conjunto de tcnicas computacionales que permiten detectar automticamente los anuncios de una secuencia de vdeo de televisin [2]. Un sistema informtico podra analizar el flujo de imgenes de la televisin y grabar con precisin el tiempo y fecha de emisin, as como el identificador de canal. Algunas de las posibles aplicaciones requieren slo la deteccin de anuncios, como tal, mientras que en otras tambin se requiere el reconocimiento del anuncio en particular [1]. La deteccin automtica de anuncios de televisin minimiza la intervencin humana y los errores debido a esta, as como el coste que supone el seguimiento de los anuncios [4]. Es posible que las empresas tambin pretendan detectar automticamente lo que sus competidores estn haciendo. Las empresas de marketing pueden estar interesadas en relacionar las caractersticas medibles de los diferentes anuncios a su xito en el mercado [1]. Aunque es un tema que sigue siendo en gran medida del dominio de la investigacin, todos estos son objetivos de inters potencial para los productores y agencias de publicidad, posiblemente debido a esto existe una fuerte participacin de la industria, incluyendo a empresas como Philips o Google, as como la existencia de muchas patentes [2][1].

-1-

Estado del Arte

2. ESTADO DEL ARTE


2.1. DESARROLLO HISTRICO La primera mencin de la posibilidad de realizar una deteccin automtica de anuncios televisivos apareci en las patentes registradas en los Estados Unidos de Amrica por parte de Novak en 1988, Blum en 1992 y Nafeh en 1994. Las patentes de Novak y Blum se encuentran caracterizadas por la tecnologa analgica. Ambas se basan en el hecho de que existen algunos planos de separacin entre dos anuncios, imgenes que por lo general estn en negro y que son por lo tanto fciles de detectar. Esta deteccin se hace mediante la comparacin de los valores de los pxeles de la imagen. Por su parte, Nafeh utiliza una red neuronal para aprender y clasificar caractersticas de las funciones de audio y video. Esta es la primera contribucin que hace explcitamente uso de mtodos de aprendizaje de mquinas. Desde este trabajo, el nmero de patentes sobre el tema ha crecido considerablemente, mientras que el nmero de publicaciones cientficas sigue siendo bastante modesto. Sin embargo, estas patentes no muestran resultados sobre la eficacia de sus tcnicas de deteccin por lo que no est claro si las tcnicas propuestas son realmente eficaces. El nmero de trabajos acadmicos sobre el tema ha comenzado a ser realmente importante a partir de 1997 y el trabajo seminal de Lienhart [2].

-2-

Estado del Arte

2.2.

ENUMERACIN DE TCNICAS

Existe un cierto grupo de trabajos relacionados con la deteccin de anuncios de televisin. Aunque bsicamente el objetivo fundamental es comn, existen diferentes variantes entre los distintos trabajos, de tal modo que mientras algunos trabajos solo buscan delimitar el bloque de anuncios, otros tienen como finalidad la deteccin de los propios anuncios. Existen, adems, trabajos en los que la deteccin se realiza en tiempo real, mientras que en otros casos el anlisis se realiza sobre grabaciones. Esto va a influir de forma directa en la complejidad y velocidad de los algoritmos utilizados. En base a lo anterior, podemos dividir los trabajos entre aquellos que analizan las caractersticas propias de los anuncios y aquellos otros que se basan en un aprendizaje de los mismos. A continuacin se van a presentar una serie de estrategias que pretenden realizar la deteccin de anuncios defendidas por ciertos autores. 1. La deteccin del comienzo de los anuncios se puede realizar mediante la bsqueda de los planos monocromticos o negros que se encuentran al comienzo de los anuncios, siendo este un problema relativamente sencillo de procesamiento de seal. Sin embargo, las escenas que presentan colores oscuros hacen que sea difcil, por lo que se han propuesto varias tcnicas para resolver este problema: establecer un umbral medio, utilizar la varianza de la luminancia de pixel o hacer uso de la entropa del histograma de luminancia. Por otra parte algunos autores han notado que el logotipo del canal no estuvo presente durante los comerciales. La deteccin del logotipo puede ser un indicador interesante pero es, por desgracia, una difcil tarea: podemos encontrarnos con logotipos semi-transparentes, color dinmico, movimiento, etc. Adems, la presencia del logotipo no siempre es sistemtica en los programas, lo que resulta en falsos positivos. Se puede analizar tambin la tasa de actividad, puesto que una alta tasa de actividad puede ser indicativa de que estamos en presencia de un anuncio. Esto se debe a que una de las formas en que los anunciantes intentan captar la atencin de los espectadores es mediante la introduccin de mucho movimiento.

-3-

Estado del Arte

Otra caracterstica propia de los bloques de anuncios es la duracin de los mismos. Se puede ver, segn el pas, que de media entre cada bloque de anuncios hay una duracin de 20,9 minutos, mientras que el propio bloque de anuncios presenta una duracin de 3,7 minutos. Tambin se puede hacer una medida de los bordes de la zona de imagen de la pantalla mediante tcnicas de deteccin de bordes y de la longitud de los vectores de movimiento. Esta observacin tambin da lugar a muchas falsas alarmas: las pelculas de accin, clips, trailers, etc. Otras caractersticas tambin se pueden utilizar: la presencia de texto por un mtodo de deteccin de texto. Desgraciadamente, este es un proceso costoso y de igual modo pueden producirse muchas falsas alarmas (trailers, noticias, televisin, etc.) [2].

2. Debido al hecho de que cada tipo de programa tiene sus caractersticas particulares, por ejemplo: dibujos animados, pelculas, noticias, series de televisin, deportes, etc.; es muy difcil, y quizs imposible, llegar a una solucin que funcione para todos los tipos de programa. Por lo tanto, se decide dividir el proyecto en dos partes [7]: a. En la primera parte nos ocupamos de los tipos de programas que visualizan la mayora de los espectadores: series de televisin (no animadas) y pelculas. Con el fin de detectar bloques comerciales, se realiz la deteccin de cortes duros (cambios de planos) y la deteccin de texto en el segmento de vdeo. Asumimos que, en series de televisin y pelculas, los cortes duros y el texto rara vez aparecen; al contrario de lo que pasa en los anuncios, en los que aparecen con frecuencia. La integracin de estas dos herramientas nos puede proporcionar un algoritmo eficiente que pueda detectar bloques comerciales de una manera fiable. b. En la segunda parte del proyecto tratamos de resolver el problema que plantea la deteccin de anuncios durante la emisin de dibujos animados y deportes. Usando la deteccin de histograma para cada tipo de programa, se detecta el bloque comercial fuera del programa de televisin.

-4-

Estado del Arte

3. Hay dos categoras principales entre los mtodos utilizados para detectar los comerciales: a. Deteccin basada en caractersticas: se basa en analizar las caractersticas generales de los comerciales para detectar su presencia (planos de color negro, silencios, las variaciones en el sonido, la ausencia del logo de la emisora, etc.). b. Deteccin basada en reconocimiento: pretende realizar la deteccin de los anuncios por la comparacin con anuncios que previamente ha aprendido [3]. 4. El productor de anuncios tiene que atraer la atencin de los espectadores, los cuales no suelen estar tan interesados en los anuncios como en el contenido que estn visualizando (serie, pelcula, etc.) y tienden a cambiar de canal durante la duracin del anuncio o tomar un descanso para hacer otra cosa. Por lo tanto el productor de anuncios utiliza ms cantidad de cortes y slo colores especficos para el anuncio para destacar los productos y as atraer la atencin del espectador. El concepto de frecuencia de corte, que se define como la tasa de cambio de escenas en cada bloque, puede ser utilizado para encontrar un corte publicitario. La frecuencia de los cortes presentes en el comercial es alta en comparacin con la de las series en general. Por lo tanto la zona en la que la frecuencia de corte sea mayor, puede ser identificada como un corte publicitario [4]. 5. El proceso de deteccin se realiza en dos fases diferentes: En primer lugar, los programas de televisin grabados pasan a travs del detector de cambio de plano. Los resultados del detector de cambio de plano se utilizan para calcular los cortes y cortes fuertes por minuto, que representan la frecuencia de cambio de plano. Se utilizan estas dos caractersticas para etiquetar a los candidatos de los lmites de las pausas publicitarias. En la etapa de refinamiento de la frontera, los resultados del discriminador de la voz, la deteccin de escenas de vdeo y la deteccin de texto se utilizan para caracterizar mejor los anuncios y los programas. Los

-5-

Estado del Arte

lmites exactos son, a continuacin, refinados basndose en las caractersticas as obtenidas. Despus del refinamiento de contorno, eliminamos los valores extremos de algunas observaciones [5]. 6. Realiza una divisin de caractersticas tcnicas, por una parte las que son directamente medibles y por otra las que son medibles de una forma indirecta [1]. Las caractersticas medibles de forma directa son: La duracin temporal del bloque completo de anuncios y de un solo anuncio. Dos anuncios consecutivos estn separados por un pequeo corte de 5-12 planos negros. El volumen del audio aumenta al comienzo del anuncio y se reduce al final del mismo.

Las caractersticas medidas de forma indirecta: Un observador humano percibe los anuncios animados y con mucho movimiento. Esto se refleja en una alta frecuencia de cortes y por rpidos cambios del contenido del color. Los comerciales a menudo muestran imgenes estticas, especialmente al final de los mismos, presentando el producto, la empresa, etc.

-6-

Estado del Arte

2.3.

OTRAS TECNOLOGAS

Como se ha presentado anteriormente, existen un nmero apreciable de estudios cientficos y patentes que trataban el tema de deteccin automtica de anuncios de televisin, en cambio, la mayora de estos trabajos no dejan claro si las tcnicas propuestas son realmente eficaces [2]. Como productos terminados podemos destacar Comskip que es un detector comercial mpeg libre. Es una aplicacin de consola de Windows que lee un archivo MPEG y analiza el contenido en base a una gran cantidad de parmetros configurables. Tras el anlisis se genera un archivo en varios formatos posibles que contiene la ubicacin de los anuncios publicitarios en el interior del archivo mpeg. Desde la aparicin de XP Media Center 2005, se ha incluido la herramienta llamada DVRMS", que presenta muchas herramientas para analizar archivos grabados con Media Center presentando funciones como cortar, editar, comprimir, etc. Pero lo que es realmente destacable es la funcin Skip Feature Comercial. Esto es exactamente lo que su nombre sugiere: una funcin para analizar los programas de televisin grabados y que de forma automtica se salta los bloques comerciales mientras ests viendo la grabacin. Por otra parte el programa de deteccin automtica de anuncios ms avanzado disponible al pblico en general se denomina ShowAnalyzer. Segn su creador con una adecuada configuracin se puede obtener un porcentaje de deteccin del 100%, tambin es cierto que el mismo autor aclara que la configuracin de la aplicacin no es para pusilnimes. A un nivel hardware, ya hay televisores que incluyen un DVR incorporado de serie (como el LG 60PY2DR) [3].

-7-

Memoria Descriptiva

3. MEMORIA DESCRIPTIVA
3.1. INTRODUCCIN

En el estado del arte se ha sealado que los anuncios de la mayora de los pases presentan una serie de caractersticas bien definidas, tanto en el aspecto sonoro como en el visual. En el presente proyecto solo se aborda la deteccin de anuncios desde el plano visual. Desde el plano visual los bloques de anuncios presentan una estructura bien definida. Al inicio de un bloque de anuncios, tras un programa televisivo cualquiera, se proyectan una serie de fotogramas completamente negros, tras los cuales tiene comienzo el anuncio. En la aplicacin se hace uso de esta caracterstica para detectar el posible comienzo de un anuncio.

Figura 1: Ejemplo de cambio de plano

La aplicacin desarrollada hace uso de los cambios de plano. Se define un cambio de plano como la transicin entre dos fotogramas de vdeo consecutivos, siendo el primer fotograma un plano negro y el siguiente plano el primero de un posible anuncio.

-8-

Memoria Descriptiva

El primer anlisis que se realiza va enfocado a la bsqueda del comienzo del anuncio. Esto es fcil de conseguir realizando una comparacin entre el valor de los pxeles monocromticos de la imagen que se est analizando y un valor umbral que idealmente sera cero, pero que en la prctica habr que determinar. En diferentes ordenadores y para diferentes fuentes de vdeo, un mismo plano de una misma secuencia de vdeo si es transformada a escala de grises, para un mismo pixel toma un valor distinto. Este hecho afecta, de forma directa, al valor umbral que en principio permite distinguir entre un cambio de plano y una imagen oscura que pueda aparecer en un programa. El riesgo reside en que se detecte un falso cambio de plano. Pese a todo, no hay que preocuparse mientras que esto tengan lugar sobre el programa de generacin de huellas y no en el de deteccin de anuncios, puesto que el archivo de generacin de huellas es revisado antes de ser utilizado y borrado los falsos cambios de plano. Para solucionar el problema de los falsos cambios de plano, o al menos minimizarlo, se har uso de la aplicacin PFC Setup Cambio Plano, cuyo funcionamiento explicaremos en detalle ms adelante, bastando ahora con saber que dicha aplicacin se encarga de buscar un valor umbral adecuado para cada ordenador. A posteriori tambin cabe la posibilidad de eliminar a mano estos falsos anuncios de la lista de candidatos si ello fuese necesario. En caso de que se est ejecutando la aplicacin de generacin de huellas o de deteccin de anuncios, la huella ser almacenada en la base de datos o ser comparada con las huellas del registro de huellas de la base de datos con el fin de encontrar otra secuencia binaria equivalente, lo cual sera una seal de que se ha detectado un anuncio. No obstante, y como se detallar ms adelante, el proceso no es infalible y se pueden generar falsas detecciones. Para disminuir la probabilidad de error en las falsas detecciones se puede aumentar el nmero de bits de la huella binaria. Para la generacin de la huella, el proceso que se sigue es siempre el mismo: se empieza por capturar la imagen de la fuente de vdeo para, posteriormente, realizar una fuerte compresin de la imagen hasta 3x4 pxeles y transformar la imagen obtenida, punto por punto, a escala de grises. Una imagen RGB est formada por pxeles que a su vez guardan la informacin de color de los canales RGB y la luminancia del canal Y, siendo este ltimo valor un offset que no se tendr en cuenta en la obtencin de la imagen en escala de grises.

-9-

Memoria Descriptiva

Se realiza una comparacin de cada pixel con su consecutivo y del ltimo con el primero, esta comparacin se implementa como una resta: si el resultado es mayor que cero, se guarda el resultado en un vector binario en la posicin correspondiente al bit analizado un 1; en caso contrario, se guarda un 0. Es fcil comprobar que la probabilidad de error es menor cuanto mayor sea el nmero de elementos del vector binario huella, pero a cambio el programa se puede volver ms lento aumentando la probabilidad de cometer un error en el muestreo. En el captulo de conclusiones se explica en detalle este asunto. Durante la ejecucin, los programas estn continuamente buscando cambios de planos, y cuando se produce uno, se mide el tiempo transcurrido desde que ste ocurre hasta el siguiente muestreo. Esta segunda imagen es a la cual se le aplican los algoritmos y se le calcula la huella. De lo anterior se deduce que solo existe una oportunidad para capturar la imagen y presentarla. Se podra optar por otras estrategias, como hacer secuencias de fotogramas desde que se detecta el cambio de plano, pero de esta forma se aumentara la tasa de falsas detecciones, as como los tiempos de procesamiento, por lo que la denominacin tiempo real empezara a desvirtuarse. Se debe poner el mximo empeo en la precisin del muestreo, de tal manera que, idealmente, el tiempo de estabilizacin de la imagen debe ser un valor lo ms constante posible. El ojo humano tiene una velocidad de respuesta a un estmulo luminoso de, aproximadamente 30 Hz. Realizando un anlisis conservador, se va a recibir un nuevo plano cada 1/30 seg = 33 mseg (PAL es 25 fps y NTSC 30 fps). Para no perder ningn fotograma la frecuencia de captura debe ser mayor de 30 fps (tm < 33 mseg o 40 msg). El temporizador har todo lo posible por lanzar una excepcin cada N mseg, pero es posible que tarde un poco ms, o incluso un poco menos, por lo que aparece una incertidumbre asociada al temporizador. Al mismo tiempo. Se ha podido comprobar que, al programar la frecuencia del temporizador, cuanto mayor sea sta, menor es la precisin; y, por tanto, mayor la incertidumbre. De todo lo anterior, se desprende que se debe llegar a un compromiso entre la frecuencia de muestreo y la incertidumbre. Dado lo crtico de la eleccin de la frecuencia de muestreo para un adecuado funcionamiento de las aplicaciones de deteccin y generacin de huellas, se ha creado la aplicacin PFC Setup Cambio Plano que es capaz de determinar la frecuencia ptima.

-10-

Memoria Descriptiva

El programa PFC Setup Cambio Plano realiza una serie de capturas de una secuencia de vdeo, al final de cada captura, guarda el valor real de los tiempos transcurridos entre las capturas y se muestra una lista con los valores que facilita la eleccin de la frecuencia de muestreo en funcin de la mquina con la que se est trabajando.

-11-

Memoria Descriptiva
3.2. TEORA 3.2.1. Conversin a Escala de Grises Cada imagen capturada de una fuente de vdeo es almacenada en la memoria como un archivo de mapa de bits. Dichos archivos estn formados por pxeles. Un pixel no es ms que una representacin, en forma de clase o estructura, que guarda la informacin de color y luminosidad de cada punto de la imagen. Cada pixel se dice que presenta cuatro canales: RGB e Y. Los canales RGB son para almacenar la informacin de color, mientras que el canal Y aporta la informacin de luminosidad del pixel; aunque, a efectos prcticos, no es ms que un offset para los valores RGB.

Figura 2: Estructura de pxeles en una secuencia de vdeo

-12-

Memoria Descriptiva

El canal R almacena un valor de 0 255 que representa un cierto valor de intensidad del color rojo de todo el rango posible, esto es equivalente para el canal G (verde) y B (azul). Para realizar la conversin de un pxel de color a escala de grises, normalmente se aplica la siguiente frmula: ColorGris = Pero en la aplicacin no se modifica cada pxel de forma individual, sino que se aplica una matriz de transformacin de color sobre la imagen completa.

3.2.2. Clculo de la Media Para saber si un determinado plano es completamente negro, lo que idealmente se puede hacer es medir el valor de cada pxel de forma individual y comprobar que toman el valor 0. Pero, en la realidad, en una secuencia de vdeo incluso los planos ms negros no son completamente negros. Para salvar este problema, se calcula el valor medio de la imagen y se compara con un cierto valor umbral de la siguiente manera: ada una imagen de tamano en p eles ,

Por tanto su valor medio viene dado como

3.2.3. Determinacin del Valor Umbral Anteriormente hemos hablado del valor umbral como herramienta til para diferenciar las imgenes en negro de las que no lo son; sin embargo, no hemos precisado de qu forma se determina este umbral. Con tal fin se ha desarrollado la aplicacin PFC Setup Cambio Plano, la cual se encarga de determinar este valor umbral para una cierta fuente de vdeo. Puesto que depende fundamentalmente de la fuente de vdeo y de los filtros de color de la mquina sobre el que se desarrolla la aplicacin.

-13-

Memoria Descriptiva

Para determinar el valor umbral de negro en el cambio de plano, la aplicacin PFC Setup Cambio Plano realiza una serie de capturas de la fuente de vdeo y calcula para cada imagen el histograma de la misma, guardando el resultado en un histograma general. Finalmente se hace uso de este histograma para determinar el valor ms adecuado de cambio de plano.

Figura 3: Falso cambio de plano

3.2.4. Clculo de la Frecuencia de Muestreo Como se ha mencionado anteriormente la eleccin de una adecuada frecuencia de muestreo es fundamental para el buen funcionamiento de la aplicacin. Adems, se considera que se trabaja sobre una mquina lo suficientemente potente, lo cual es un requisito indispensable.

-14-

Memoria Descriptiva

Clculo de la huella:

Figura 4: Esquema de generacin de una huella

iempo de muestreo ,

iempo de frame ,

Se hace evidente que, para que la huella pueda ser reconocida con posterioridad, ha debido de crearse cumpliendo la siguiente relacin:

La frecuencia de muestreo es configurable desde el timer, que es el que produce los eventos que tienen asociado el cdigo de captura de las imgenes.

-15-

Memoria Descriptiva

Pero la frecuencia de muestreo, por desgracia, no presenta una frecuencia constante: por una parte est el tiempo de procesamiento del cdigo asociado a la captura de la imagen; y, por otra, el propio timer presenta una incertidumbre .

Ahora surge la pregunta de qu valor asignarle al timer para intentar maximizar el valor de la frecuencia sin que afecte demasiado a la incertidumbre. De nuevo, para calcular este valor se hace uso de la aplicacin PFC Setup Cambio Plano. Esta aplicacin realiza capturas y medir los retrasos entre las mismas. En cada iteracin la aplicacin guarda el resultado del retraso. Tras terminar de reproducir la secuencia de vdeo, se comparan todos los tiempos totales y las incertidumbres, y se toma una eleccin sobre el valor ms adecuado.

-16-

Memoria Descriptiva

3.3.

ARQUITECTURA DEL SISTEMA 3.3.1. Arquitectura del Hardware 3.3.1.1. Ordenador

Es el sistema sobre el que se van a ejecutar los programas software que se han realizado. Es un elemento crtico del proyecto, puesto que se requiere tiempo real en el procesamiento del programa de deteccin. Existen varias caractersticas del ordenador que son clave: la velocidad del microprocesador y el nmero de ncleos. La memoria no es un problema en su tamao, pero s en la velocidad de carga de los datos. El equipo utilizado es un Intel Core 2 Duo CPU P7350 de la familia Penryn a 2 GHz. En cualquier caso, la aplicacin PFC Setup Cambio Plano se encarga de determinar si un equipo tiene la potencia necesaria para poder ejecutar, con las mnimas garantas, la aplicacin de deteccin de anuncios. El que la CPU est constituida por dos ncleos presenta una gran ventaja en la aplicacin puesto que uno de los ncleos ejecuta la interfaz de usuario y el otro ncleo realiza las tareas de procesamiento de datos.

Figura 5: Ordenador

-17-

Memoria Descriptiva

3.3.1.2.

Tarjeta de Televisin DVB - USB

Para la captura de la seal de televisin se ha utilizado el sintonizador USB AVerTV Volar HD Pro de la empresa AVerMedia por ser uno de los dispositivos ms utilizados por el pblico en general. En cualquier caso, los programas realizados son de propsito general y se pueden utilizar con cualquier otro tipo de tarjeta. AVerTV Volar HD Pro es el sintonizador en formato USB de AVerMedia. Este modelo incluye conector de antena integrada, lo que le ofrece al usuario mayor estabilidad en su sistema de conexin. En su packaging se puede encontrar la Antena Portatil "High Gain", con la que podr obtener una mayor recepcin de seal en la sintonizacin de canales de TDT.

Figura 6: Dispositivo USB sintonizador

-18-

Memoria Descriptiva

3.3.2. Arquitectura del Software 3.3.2.1. Sistema Operativo

El sistema operativo es un programa que se encarga de gestionar una multitud de tareas, como puede ser la gestin de los recursos hardware, proveer servicios a los programas de aplicacin, acceso a memoria, etc. El sistema operativo seleccionado es el Windows Vista Home Premium con la actualizacin Service Pack 2. Se ha elegido este sistema operativo porque permite la instalacin del sintonizador de televisin Avermedia as como la de los programas creados en el entorno de desarrollo Visual Studio de Microsoft, creados en el lenguaje Visual C++ .Net. Tambin es imprescindible que sea compatible con DirectX y en concreto con el objeto MSVidCtl que proporciona todo lo necesario para el desarrollo de aplicaciones de televisin tanto digitales como analgicas para el lenguaje C++, C#, Visual Basic y .Net en general, adems de MFC. Otro motivo igualmente importante para seleccionar un sistema operativo Windows es que condiciona tanto el sintonizador de televisin que se puede utilizar, como el entorno de desarrollo de las aplicaciones y el lenguaje sobre el que se escriben las propias aplicaciones. Esto no es trivial debido a la escasa cantidad de ejemplos y cdigos que existen para la sintonizacin de canales de televisin DVB y para la captura de imgenes. Por todo ello, se hace necesario implementar la aplicacin en el lenguaje en el que exista una mayor documentacin y en este caso el lenguaje es C++ para plataforma Windows.

Figura 7: Sistema operativo

-19-

Memoria Descriptiva
3.3.2.2. DirectX 11 SDK

DirectX permite universalizar las aplicaciones bajo plataformas Windows de manera que podra utilizarse otro sintonizador de televisin DVB sin ningn problema. Se trata de una coleccin de APIs desarrolladas para facilitar las complejas tareas relacionadas con multimedia, especialmente programacin de juegos y vdeo, en la plataforma Microsoft Windows. Consta de las siguientes APIs: Direct3D: utilizado para el procesamiento y la programacin de grficos en tres dimensiones (una de las caractersticas ms usadas de DirectX). Direct Graphics: para dibujar imgenes en dos dimensiones (planas), y para representar imgenes en tres dimensiones. DirectInput: para procesar datos del teclado, mouse, joystick y otros controles para juegos. DirectPlay: para comunicaciones en red. DirectSound: para la reproduccin y grabacin de sonidos de ondas. DirectMusic: para la reproduccin de pistas musicales compuestas con DirectMusic Producer. DirectShow: para reproducir audio y vdeo con transparencia de red. DirectSetup: para la instalacin de componentes DirectX. DirectCompute: lenguaje e instrucciones especiales para el manejo de cientos o miles de hilos de procesamiento, especial para procesadores de ncleos masivos.

A pesar de ser desarrollado exclusivamente para la plataforma Windows, se est desarrollando una implementacin de cdigo abierto de su API para sistemas Unix (en particular Linux) y X Window System por el proyecto WineHQ, orientada a la ejecucin de juegos desarrollados para Windows bajo sistemas Unix.

Figura 8: DirectX

-20-

Memoria Descriptiva

3.4.

DESCRIPCIN DEL SISTEMA 3.4.1. Breve Descripcin del Sistema

Para la realizacin completa del proyecto, se han desarrollado tres aplicaciones diferentes aunque complementarias, estas son: PFC Genera Huellas, PFC Detecta Anuncios y PFC Setup Cambio Plano. Todas estas aplicaciones han sido desarrolladas en Visual C++ Express Edition 2008. Uno de los motivos principales para utilizar este entorno de desarrollo es que se trata de uno de los hermanos pequeos de Visual Studio 2008, un potente entorno de desarrollo utilizado en la mayora de empresas y centros tecnolgicos para la realizacin de aplicaciones de usuario. Por otra parte, al tratarse de una Express Edition, es una herramienta totalmente gratuita pese a su enorme potencia.

Figura 9: Visual Studio Express Edition

El lenguaje utilizado para la realizacin del proyecto ha sido C++ .Net. En una versin anterior se realiz sobre C++ bajo MFC, pero el mejor desempeo, sencillez y nivel de documentacin para .Net, ha hecho que se opte por esta nueva tecnologa.

-21-

Memoria Descriptiva

3.4.2. Aplicaciones Se han desarrollado un total de tres aplicaciones las cuales mencionamos a continuacin:

PFC Genera Huellas: La aplicacin PFC Genera Huellas tiene por fin la generacin de un archivo de texto con un formato bien definido en el que se almacenan las huellas de los diferentes anuncios que la aplicacin va generando. PFC Detecta Anuncios: Esta aplicacin recibe, entre otros, un archivo de entrada en el que se encuentran las huellas de todos los anuncios. Cuando el programa comienza, inicia un temporizador que ser lanzado a intervalos de tiempo constantes, por ejemplo 30 ms. Cada vez que el temporizador genera un evento, ejecuta el cdigo que se encarga de capturar la imagen, procesarla y generar las huellas para, posteriormente, ser comparada en la base de datos. En caso de que la aplicacin haya detectado un anuncio, este es guardado en el archivo de salida junto a la hora del mismo. PFC Setup Cambio Plano: Esta aplicacin sirve para determinar un valor adecuado para una serie de parmetros configurables de las dos aplicaciones anteriores. o Filtro de negro: Este parmetro permite determinar un valor umbral para distinguir un valor medio de negro de un plano, como un cambio de plano, frente a un posible plano oscuro, pero que no necesariamente es un cambio de plano. o Frecuencia de muestreo: Una frecuencia demasiado alta har que el timer no funcione adecuadamente, aumentando su incertidumbre; pero una frecuencia demasiado baja har que el timer sea excesivamente lento.

-22-

Memoria Descriptiva

3.4.3. Algoritmos 3.4.3.1. Algoritmo de generacin de huellas

El algoritmo principal de la aplicacin de generacin de huellas se ejecutar cada un nmero de milisegundos a determinar, siendo este constante (como se ha visto con anterioridad existe una pequea incertidumbre). El cdigo que implementa el algoritmo forma parte de un evento asociado a un timer, de manera que es el propio timer el que genera las interrupciones peridicamente a un intervalo de tiempo que es configurable, tal y como se ha comentado anteriormente. Lo primero que se hace en el algoritmo es capturar la imagen, comprimirla y convertirla a escala de grises. Una vez realizada esta operacin, se calcula el valor medio de los pxeles de la imagen para comparar este valor con el valor umbral filtro de negro y, de este modo, determinar si se trata de un cambio de plano. En caso de tratarse de un cambio de plano, se pone a nivel alto una bandera y se guarda la hora del sistema. En caso de no ser un cambio de plano, se comprueba si el frame actual es el primer frame tras el ltimo cambio de plano (bandera a nivel alto). En caso afirmativo, se calcula el tiempo transcurrido desde el ltimo plano negro. Es generada una huella a partir de la imagen actual y guarda la huella en la lista de huellas para ser almacenada en el archivo de salida al final de la aplicacin.

-23-

Memoria Descriptiva

Figura 10: Esquema del algoritmo de generacin de huellas

-24-

Memoria Descriptiva

3.4.3.2.

Algoritmo de deteccin de anuncios

Anlogamente al caso anterior, el algoritmo principal de la aplicacin de deteccin de anuncios se ejecutar cada un nmero de milisegundos a determinar, siendo este constante (con una pequea incertidumbre). El cdigo que implementa el algoritmo forma parte de un evento asociado a un timer, de manera que es el propio timer el que genera las interrupciones peridicamente con un intervalo de tiempo que es configurable tal y como se ha comentado anteriormente. Lo primero que se hace en el algoritmo es capturar la imagen, comprimirla y convertirla a escala de grises. Una vez realizada esta operacin se calcula el valor medio de los pxeles de la imagen para comparar este valor con el valor umbral filtro de negro, y de este modo determinar si se trata de un cambio de plano. En caso de tratarse de un cambio de plano, se pone a nivel alto una bandera y se guarda la hora del sistema. En caso de no ser un cambio de plano, se comprueba si el frame actual es el primer frame tras el ltimo cambio de plano (bandera a nivel alto). En caso afirmativo se calcula el tiempo transcurrido desde el ltimo plano negro y si se ha superado el tiempo de estabilizacin de la imagen se contina. Es generada una huella a partir de la imagen actual y se busca su anloga en una lista de huellas previamente cargada en memoria desde el archivo que fue generado mediante la aplicacin de Generacin de huellas. Finalmente, en caso de que la huella sea encontrada, el nombre del anuncio, la fecha, la hora y otras caractersticas configurables son guardadas en una lista de objetos creada especficamente para guardar este tipo de objetos. Tambin se muestra un mensaje en la aplicacin de usuario, para que este sepa que se ha encontrado un anuncio.

-25-

Memoria Descriptiva

Figura 11: Esquema del algoritmo de deteccin de huellas

-26-

Memoria Descriptiva

3.5.

MANUAL DE USUARIO 3.5.1. Generacin de Huellas

Se presenta una imagen del interfaz de usuario de la aplicacin Generacin de uellas. La aplicacin de generacin de uellas tiene por objetivo, por una parte, la deteccin de cambios de plano; y, por otra, muestrear con precisin un plano tras el cambio de plano, generar su huella correspondiente y guardar el resultado convenientemente en el archivo de salida.

Figura 12: Programa de generacin de huellas

A continuacin se describe cada uno de los elementos de la aplicacin: 1. Ttulo de la aplicacin: Por defecto, ser: Generacin de huellas. 2. Filtro de negro: El filtro de negro es una entrada de valor configurable. Permite configurar este valor desde el comienzo de la aplicacin hasta que se pulse el botn comenzar, en este momento quedar deshabilitado. Su funcin es establecer el umbral del color de negro para la deteccin de los cambios de plano.

-27-

Memoria Descriptiva

3. Comenzar: Este botn da acceso al comienzo de la aplicacin de generacin de huellas. Tras ser pulsado, van apareciendo una serie de dilogos para seleccionar los archivos necesarios para generar las huellas de los anuncios y guardar el resultado en un archivo de salida. 4. Detener: Este botn se debe pulsar cuando se crea conveniente salir de la aplicacin, siendo imprescindible ser pulsado una vez al final de la sesin de generacin de huellas. 5. Salida de vdeo: Esta zona es un control ActiveX que permite visualizar la salida de vdeo, ya sea de televisin, vdeo, DVD o cualquier otra fuente compatible. 6. Salida de texto: Aqu se muestra toda la informacin y eventos que se generan durante la ejecucin de la aplicacin. Cada vez que detecta un candidato a anuncio muestra la informacin por pantalla.

-28-

Memoria Descriptiva

3.5.2. Deteccin de Anuncios Como se puede comprobar, la interfaz de usuario de la aplicacin etecta anuncios es idntica a la de Generacin de uellas. Esta aplicacin analiza la secuencia de vdeo y detecta los cambios de plano. Una vez detectados stos, toma el cambio de plano como referencia temporal para muestrear con precisin el plano candidato. Posteriormente, a este plano se le calcula la huella y se compara con las lista de huellas. En caso se encontrarse una huella idntica, se muestra un mensaje a travs de la salida de texto y se produce una nueva entrada en el fichero de salida.

Figura 13: Programa de deteccin de anuncios

-29-

Memoria Descriptiva

3.5.3. Paso a paso 3.5.3.1. Generacin de huellas

Lo primero que hay que configurar es el valor del filtro de negro. Este valor se puede obtener haciendo uso de la aplicacin SETUP o mediante prueba y error hasta que se encuentre un valor adecuado. Una vez configurado este parmetro, se puede pulsar el botn Comenzar. Como se ha comentado anteriormente, al pulsar el botn van a aparecer por pantalla una serie de dilogos que permiten seleccionar los archivos necesarios en la ejecucin de la aplicacin.

1. Seleccin del archivo de huellas

Figura 14: Seleccin del archivo de huellas

-30-

Memoria Descriptiva

El archivo de huellas es el que va a almacenar las huellas de todos los anuncios que la aplicacin de generacin de huellas detecte como candidatos. Al final de la ejecucin, es necesario abrir este archivo para borrar aquellas huellas que sean falsas y para proporcionar un nombre reconocible al anuncio. Se presenta un ejemplo de un archivo de huellas.

Figura 15: Archivo de salida de huellas

En la primera columna se guarda la huella como una representacin de una secuencia binaria, en la segunda columna se encuentra el nombre del archivo, siendo este valor configurable segn las preferencias del usuario. En la tercera columna se presenta el nmero del anuncio.

2. Seleccin de fuente de vdeo El dilogo de seleccin de fuente de vdeo permite seleccionar un archivo de vdeo que ser objeto de anlisis por parte de la aplicacin.

-31-

Memoria Descriptiva

Figura 16: Seleccin de fuente de vdeo

3.5.3.2.

Deteccin de anuncios

Los pasos a seguir para la ejecucin de la aplicacin de deteccin de anuncios son similares a los pasos a seguir para la aplicacin de generacin de huellas. Lo primero que hay que configurar es el valor del filtro de negro. Este valor se puede obtener haciendo uso de la aplicacin PFC Setup Cambio Plano. Tras haber configurado este parmetro, se puede pulsar el botn comenzar. Como se ha comentado anteriormente, al pulsar el botn van a aparecer por pantalla una serie de dilogos que permiten seleccionar los archivos necesarios en la ejecucin de la aplicacin.

-32-

Memoria Descriptiva

1. Seleccin del archivo de huellas

Figura 17: Seleccin del archivo de huellas

El archivo de huellas almacena las huellas de todos los anuncios que estn registrados. Por lo tanto debemos de seleccionar el archivo que previamente se ha creado en la aplicacin de generacin de huellas, adems de configurar de forma idntica el filtro de negro.

-33-

Memoria Descriptiva

2. Seleccin del archivo de anuncios

Figura 18: Seleccin del archivo de anuncios

El archivo de anuncios guardar una lnea por cada anuncio encontrado, almacenando en la misma informacin til como la fecha, la hora, etc.

Figura 19: Salida del archivo de anuncios

Como se puede apreciar en la primera columna de cada fila, se guarda el nombre del anuncio, en la segunda la fecha y en la tercera la hora exacta de la captura del anuncio.

-34-

Memoria Descriptiva

3. Seleccin de la fuente de vdeo

Figura 20: Seleccin de la fuente de vdeo

La ltima ventada de dilogo solicita seleccionar un archivo de vdeo como fuente de vdeo para la aplicacin.

-35-

Pruebas, Resultados y Conclusiones

4. PRUEBAS, RESULTADOS Y CONCLUSIONES


4.1. PRUEBAS Y RESULTADOS 4.1.1. Configuracin previa a la realizacin de las pruebas El objetivo de las pruebas de deteccin es medir el rendimiento bajo unas condiciones de trabajo normales. Aunque la calidad del vdeo a analizar es baja, el equipo sobre el que se trabaja debe tener una potencia adecuada, as como estar correctamente configurada la aplicacin de acuerdo a las caractersticas tcnicas de este equipo. Para ayudar a realizar esta configuracin, se ha desarrollado la aplicacin PFC Setup Cambio Plano, la cual determina, para una determinada fuente de vdeo, tanto su umbral de negro en los cambios de plano como la frecuencia de muestreo. Si la frecuencia de muestreo supera los 40 ms no existe garanta en la deteccin de los anuncios; aunque si la desviacin es pequea, la aplicacin puede funcionar correctamente, incluso con un muy alto rendimiento. Adems de todo lo anterior, el equipo debe tener cerrada todas las aplicaciones y procesos que no sean imprescindibles para el sistema operativo o para el funcionamiento de la propia aplicacin. Por ltimo, en el gestor de tareas de Windows se le debe asignar la mxima prioridad a la aplicacin. 4.1.2. Pruebas Se han realizado dos tipos de pruebas: el primer tipo pretende demostrar o medir la fiabilidad de la aplicacin bajo un uso normal con un nivel de calidad de imagen bajo medio; en el segundo tipo de pruebas se va un paso ms all y se busca el lmite de funcionalidad del algoritmo.

4.1.2.1.

Pruebas de deteccin de anuncios

Para la realizacin de las pruebas se han utilizado tres secuencias de vdeo con anuncios de televisin reales. La calidad de imagen de estos vdeos expresada a partir del bitrate es de 180, 190 y 250 Kbps respectivamente. El bitrate se calcula como el cociente entre el peso en Kb del vdeo y la duracin en segundos del mismo.

-36-

Pruebas, Resultados y Conclusiones

A cada vdeo es necesario obtenerle su valor umbral de cambio de plano, para lo que se utiliza, como ya se ha mencionado anteriormente, la aplicacin PFC Setup Cambio Plano. Una vez obtenido este parmetro, se introduce en la aplicacin de generacin de huellas junto con la frecuencia de muestreo (que debe ser menor de 40 ms) y se comienza el proceso. Una vez terminado este proceso, se obtiene un archivo de salida que debe ser editado para eliminar los falsos cambios de plano y para asignar nombres a los anuncios. Tras terminar de editar el archivo de generacin de huellas se procede a lanzar la aplicacin PFC Deteccin Anuncios y se deja ejecutar la aplicacin. Al finalizar la aplicacin, se genera un archivo de salida en el que se ha guardado en cada lnea un posible anuncio detectado. En caso de haber detectado un cambio de plano, pero no encontrar la huella en la base de datos, se guarda la cadena para poder ser analizada con posterioridad. Tras realizarse el anlisis correspondiente a los datos anteriormente comentados, se obtienen los siguientes resultados:
Vdeos La Sexta 1 La Sexta 2 Mejores anuncios Totales Anuncios 26 27 13 66 Detectados 26 27 13 66 Falsos deteccin 0 0 0 0 Cambios detectados 26 27 13 66 Falsos cambios 7 4 3 14

1,2 1 0,8 0,6 0,4 0,2 0 La Sexta 1 La Sexta 2 Mejores anuncios Probabilidad de detectar anuncio correcto Probabilidad falso cambio de plano

Figura 21: Probabilidades de deteccin de anuncios y de falso cambio de plano

-37-

Pruebas, Resultados y Conclusiones

Se puede observar que las pruebas han sido un xito hasta este punto puesto que se ha obtenido una probabilidad de xito del 100%.

Probabilidad de detectar un cambio de plano correcto Probabilidad de detectar un cambio de plano falso Probabilidad de detectar un anuncio correctamente Probabilidad de detectar un falso anuncio

100,00%

21,21%

100,00%

0,00%

4.1.2.2.

Pruebas de degradado

Con esta prueba se va a realizar una medida del rendimiento del algoritmo. La prueba es similar a la anterior, pero en este caso solo se va a utilizar una secuencia de vdeo, pero esta secuencia va a ser reconvertida a diferentes niveles de calidad, desde 200 kbps hasta 10 Kbps. En este caso los errores no fueron nulos, empezaron a aumentar conforme se disminua la calidad de vdeo. Para analizar los errores se realiz una aplicacin denominada PFC Distancia entre Huellas que facilita herramientas para comparar conjuntos de huellas generadas a partir de anuncios con huellas originales y medir la distancia entre ellas, definida como el nmero de bits distintos entre ambas. Al final se han generado una serie de grficas para representar estos resultados. El primer tipo de grfica representa la frecuencia de ocurrencia de cada distancia entre la huella capturada y la original para todas las calidades de vdeo.

-38-

Pruebas, Resultados y Conclusiones

Figura 22: Frecuencia de ocurrencia de las huellas para distintas calidades de vdeo

-39-

Pruebas, Resultados y Conclusiones

El segundo tipo de grfica muestra al igual que en la prueba anterior la probabilidad de error, pero frente a las diferentes velocidades o bitrate.

Figura 23: Probabilidad de error de deteccin de anuncio en funcin de la calidad de vdeo

-40-

Pruebas, Resultados y Conclusiones

4.2.

Conclusiones

A continuacin, se presentan una serie de conclusiones a las que se ha llegado tanto a travs del proceso de desarrollo del software como a travs de las pruebas realizadas al algoritmo. Si se analizan los resultados de las pruebas, se llega a la conclusin de que el algoritmo presenta un rendimiento muy alto. Considerando que la calidad de los vdeos analizados, entendida como su bitrate, est comprendida entre los 180 y los 250 Kbps, mientras que la calidad de vdeo de televisin bajo el estndar DVB-T es como mnimo de 5 Mbps, se hace patente la potencia del algoritmo. Otra conclusin a la que se ha llegado, fruto de las primeras pruebas de deteccin realizadas, es que caracterizar los frames con un nmero de 12 bits por huella es insuficiente cuando el nmero de anuncios es lo suficientemente grande. Aunque a priori esta afirmacin pueda parecer descabellada, puesto que con 12 bits se pueden generar 212 = 4096 huellas que presenta una probabilidad de ocurrencia para una determinada huella de Ph = = 0.02 %. Pero hay que tener en cuenta que algunos anuncios (no todos), presentan una franja negra en la parte superior de la imagen y otra equivalente en la parte inferior de la imagen. Esto implica que solo la zona central de la imagen contiene informacin que permita diferenciar dos imgenes distintas. Esta zona est representada en la huella por solo 4, pudindose generar 24 =16 huellas, presentando una Ph = = 6,25 %. La solucin a este problema es aumentar el nmero de huellas de 12 bits a 48.

Figura 24: Huella de 12 bits frente a 48 bits

-41-

Pruebas, Resultados y Conclusiones

Si se considera que, tanto h como w deben ser nmeros enteros y que h/w=0.75, la huella ms pequea mayor que h1 que presenta unos valores de h y w que son nmeros enteros es la huella de 48 bits. Se podra pensar que un aumento tan considerable en el nmero de bits por huella tendra como consecuencia un tiempo de procesamiento mayor de cada captura. Lo cierto es que para aumentar el nmero de bits hay que suavizar el escalado que se realiza sobre la imagen, siendo esta operacin computacionalmente mucho ms pesada. Finalmente, se puede comprobar que la aplicacin no sufre retraso alguno, pero a cambio aumenta considerablemente el rendimiento y la robustez de la aplicacin. Por otra parte, se ha podido constatar a lo largo del desarrollo del proyecto dos puntos de especial relevancia para el buen funcionamiento de la aplicacin: El primer punto es el relativo a la eleccin del umbral de negro de los cambios de plano. El segundo punto es la eleccin de una correcta frecuencia de muestreo.

Para intentar solucionar o paliar ambos problemas se ha desarrollado la aplicacin PFC Setup Cambio Plano. Aunque la aplicacin genera soluciones de compromiso para ambos problemas, la forma de abordar el problema es completamente diferente para cada caso. Para la seleccin del umbral de negro de cambio de plano la aplicacin captura una serie de secuencias de vdeo de la fuente que se quiere analizar. Posteriormente se realiza un histograma de escala de grises (0 - 255) de los diferentes planos capturados, siendo el histograma lo que proporciona la aplicacin al usuario. Para tomar una decisin, se tiene en cuenta que los valores ms prximos al negro son a su vez los nmeros ms prximos al cero en el histograma.

-42-

Pruebas, Resultados y Conclusiones

Figura 25: Histograma de escala de grises para determinacin de umbral de negro

Al analizar el histograma se aprecian 3 o 4 valores de color significativos entre los valores ms pequeos de color (no se debe tomar como un valor significativo un valor con baja frecuencia que pueda valer cero, aunque sea el valor mnimo de color). Se toma el mnimo valor significativo. Se ha podido comprobar experimentalmente que es recomendable sumarle 4 puntos ms a este valor, como factor de seguridad. Siendo este el valor umbral buscado Vh. Si se sigue este protocolo no se corre el riesgo de perder ningn cambio de plano, aunque s de detectar un falso cambio de plano, pero como ya se ha explicado a lo largo del presente proyecto eso no representa un problema de gravedad. El otro problema recurrente y quizs de mayor importancia es el relativo a la frecuencia de muestreo. Como ya se ha comentado para tener una tasa de deteccin de anuncios del 100 % es imprescindible que la aplicacin muestree la fuente de vdeo a una tasa no inferior a 25 frames por segundo o lo que es lo mismo una captura cada menos de 40 ms. Por otra parte conviene que la frecuencia de muestreo se ajuste lo ms posible a la velocidad real de procesamiento del equipo utilizado, de tal modo que si el ordenador es ms potente se pueden realizar capturas ms rpidamente y a la inversa, si no es tan potente no conviene subir demasiado la frecuencia, puesto que aunque la mitad de las veces realice las capturas en tiempo la otra mitad restante no va a poder realizarlas a tiempo pudiendo dejar de capturas frames importantes.

-43-

Pruebas, Resultados y Conclusiones

En cualquier caso si el ordenador tarda un poco ms de 40 ms en realizar las capturas, pero no mucho ms, el rendimiento seguir siendo muy alto, eventualmente incluso del 100 % de probabilidad de xito en la deteccin de los anuncios.

-44-

Bibliografa

5. BIBLIOGRAFA
[1] R. LIENHART, C. KUHMNCH y W. EFFELSBERG. On the Detection and Recognition of Television Commercials. En Proc. IEEE Conf. Multimedia Computing and System. Ottawa, Canada. Jun 1997.Pag. 509 516. [2] SHANOO. Automatic Detection of TV Commercials Technology. Allabtworld. 28 Junio 2011. [3] ILYA VEDRASHKO. Automatic Commercial Skipping. Blog Advertising Lab. 18 Febrero 2007. [4] SWATI D. BENDALE y BIJAL.J.TALATI. T.V. Commercial detection in serial videos. International journal of computer engineering & technology (IJCET). Volumen 4, Asunto 3, May-June (2013). Tamilnadu, India. Pag. 86-92. [5] JUN-CHENG CHEN, JEN-HAO YEH, WEI-TA-CHU, JIN-HAU KUO y JA-LING WU. Improvement of Commercial Boundary Detection Using Audiovisual Features. Lecture Notes in Computer Science, vol. 3767, pp. 776786, 2005, Jeju, Korea. [6] SATTERWHITE, B and MARQUES, O. Automatic detection of TV commercials. Potentials, IEEE (Volume:23 , Issue: 2 ), pp 9 - 12. April-May 2004. [7] IDAN MIEXELS and BARAK SERVATKA. Automatic Detection of TV Commercials. Israel Institute of Technology, The Vision and Image Sciences Laboratory, 2004. [8] http://msdn.microsoft.com [9] http://www.codeproject.com

-45-

Anexo

ANEXO: CDIGO FUENTE

-46-

Anexo

Clase GeneraBD

-47-

Anexo
GeneraBD.h
#pragma once #include #include #include #include #include using using using using using "Huellas.h" "Procesador.h" "Reproductor.h" "Rendimiento.h" "GeneraHuellas.h" System::Drawing; System::Threading; System::Windows::Forms; System; System::ComponentModel;

namespace namespace namespace namespace namespace

ref class GeneraBD { public: delegate void SetTextDelegate(String ^ Texto); GeneraBD(void); GeneraBD(ListBox ^ SalidaTexto); GeneraBD(ListBox ^ SalidaTexto, AxMSVidCtlLib::AxMSVidCtl ^ TV); Thread ^ HiloPrincipal; ListBox ^ SalidaTexto; Reproductor ^ TV; Procesador ^ PDI; GeneraHuellas ^ ArchivoHuellas; Huellas ^ HuellaActual; Huellas ^ HuellaAnterior; int ValorMedio; int FiltroLP; bool Cambio; float Fps; int NumTics; bool CambioPlano(Bitmap ^ ImagenBN); void ProcesamientoImagen(); //Aqu es dnde entra void PasarTexto(String ^ Cadena); //en accin el hilo };

-48-

Anexo
GeneraBD.cpp
#include "StdAfx.h" #include "GeneraBD.h" GeneraBD::GeneraBD(void) { Cambio = false; Fps = 0; HiloPrincipal = gcnew Thread( gcnew ThreadStart(this,&GeneraBD::ProcesamientoImagen)); } GeneraBD::GeneraBD(System::Windows::Forms::ListBox ^SalidaTexto) { Cambio = false; Fps = 0; HiloPrincipal = gcnew Thread( gcnew ThreadStart(this,&GeneraBD::ProcesamientoImagen)); this->SalidaTexto = SalidaTexto; } GeneraBD::GeneraBD(System::Windows::Forms::ListBox ^SalidaTexto, AxMSVidCtlLib::AxMSVidCtl ^TV) { Cambio = false; Fps = 0; NumTics = 1; this->SalidaTexto = SalidaTexto; this->TV = gcnew Reproductor(TV); this->PDI = gcnew Procesador(); this->ArchivoHuellas = gcnew GeneraHuellas(); this->HuellaAnterior = gcnew Huellas(); this->HuellaActual = gcnew Huellas(); } bool GeneraBD::CambioPlano(Bitmap ^ ImagenBN) { int Media; int i,j,ind; ind = 0; ValorMedio = 0; Cambio = false; for(j=0; j<ImagenBN->Height; j++) { for(i=0;i<ImagenBN->Width;i++) { Media = Media + (int) ( 0.3 * ImagenBN->GetPixel( i,j).R + 0.59 * ImagenBN->GetPixel( i,j).G + 0.11 * ImagenBN->GetPixel(i,j).B); ind++; } }

-49-

Anexo
Media = Media/(ImagenBN->Height * ImagenBN->Width); ValorMedio = Media; if(Media<FiltroLP) { Cambio = true; }else{ Cambio = false; } return Cambio; } void GeneraBD::ProcesamientoImagen() { while(true) { //Monitor::Enter; //this->TV->CapturaImagen(); //Monitor::Exit; this->PasarTexto("Hola"); } } void GeneraBD::PasarTexto(System::String ^Cadena) { GeneraBD::SetTextDelegate ^ Delegado; if(this->SalidaTexto->InvokeRequired) { Delegado = gcnew SetTextDelegate(this, &GeneraBD::PasarTexto); this->SalidaTexto->Invoke(Delegado, gcnew array<Object^> { Cadena }); }else{ this->SalidaTexto->Items->Clear(); this->SalidaTexto->Items->Add("Hola"); } }

-50-

Anexo

Clase Reproductor

-51-

Anexo
Reproductor.h
#pragma once using namespace System::Drawing; using namespace System::Windows::Forms; using namespace AxMSVidCtlLib; //using namespace System::Windows::Forms; /* * La clase reproductor al ser creada referencia el componente de Form * TV. * De esta manera todos los mtodos de Reproductor puede acceder a TV * y facilita * la captura y procesado de las imgenes del vdeo reproducido */ ref class Reproductor { public: AxMSVidCtlLib::AxMSVidCtl ^Video; OpenFileDialog ^Explorador; Image ^ ImagenCapturada; Image ^ ImagenAnterior; Image ^ ImagenComprimida; Image ^ SalidaImagen; Reproductor(AxMSVidCtlLib::AxMSVidCtl ^ TV); Image ^ CapturaImagen(); void Reproduce(); void Parar(); Image ^ ComprimeImagen(Image ^ Origen); Image ^ ComprimeImagen(Image ^ Origen,int ModoCompresion); Image ^ ExpandeImagen(); bool NuevaImagen(Image ^ Nueva, Image ^ Anterior); };

-52-

Anexo
Reproductor.cpp
#include "StdAfx.h" #include "Reproductor.h"

Reproductor::Reproductor(AxMSVidCtlLib::AxMSVidCtl ^TV) { ImagenAnterior = gcnew Bitmap(1,1); Video = gcnew AxMSVidCtlLib::AxMSVidCtl(); Video = TV; } Image ^ Reproductor::CapturaImagen() { ::stdole::IPictureDisp ^pPictureDisp; pPictureDisp = Video->VideoRendererActive->Capture(); ImagenCapturada = Microsoft::VisualBasic::Compatibility:: VB6::Support::IPictureDispToImage(pPictureDisp); return ImagenCapturada; } Image ^ Reproductor::ComprimeImagen(Image ^ Origen) { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; this->SalidaImagen = Origen; Auxiliar = gcnew Bitmap(4,3); Tapiz = Graphics::FromImage(Auxiliar); Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::HighQualityBicubic; Tapiz->DrawImage(Origen,0,0,4,3); ImagenComprimida = (Image ^)(Auxiliar); return (Image ^)gcnew Bitmap(Auxiliar); } Image ^ Reproductor::ExpandeImagen() { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; Auxiliar = gcnew Bitmap(SalidaImagen->Width, SalidaImagen->Height); Tapiz = Graphics::FromImage(Auxiliar); Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::High; Tapiz->DrawImage(ImagenComprimida,0,0, SalidaImagen->Width,SalidaImagen->Height); return (Image ^)gcnew Bitmap(Auxiliar); }

-53-

Anexo
Image ^ Reproductor::ComprimeImagen(Image ^ Origen, int ModoCompresion) { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; Auxiliar = gcnew Bitmap(4,3); Tapiz = Graphics::FromImage(Auxiliar); switch(ModoCompresion) { case 0: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Bicubic; break; case 1: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Bilinear; break; case 2: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Default; break; case 3: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::High; break; case 4: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::HighQualityBicubic; break; case 5: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::HighQualityBilinear; break; case 6: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Default; break; case 7: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Low; break; case 8: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::NearestNeighbor; break; default: Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::Default; break; } Tapiz->DrawImage(Origen,0,0,4,3); Salida = (Image ^)Auxiliar; return Salida; }

-54-

Anexo
void Reproductor::Reproduce() { Explorador = gcnew OpenFileDialog(); Explorador->Title = "Seleccin de fuente de vdeo"; Explorador->ShowDialog(); Video->View(Explorador->FileName); Video->Build(); Video->Run(); } void Reproductor::Parar() { Video->Stop(); } bool Reproductor::NuevaImagen(System::Drawing::Image ^ Nueva, System::Drawing::Image ^ Anterior) { return Image::Equals(Nueva,Anterior); }

-55-

Anexo

Clase Procesador

-56-

Anexo

Procesador.h
#pragma once using namespace System::Drawing; using namespace System::Drawing::Imaging; using namespace System::Windows::Forms; ref class Procesador { public: ImageAttributes ^ AtributosImagen; ColorMatrix ^ MatrizColor; Image ^ ImagenComprimida; Image ^ ImagenBase; Bitmap ^ ImagenBN; int AnchoImgComp; int AltoImgComp; int ValorMedio; Procesador(void); Procesador(Image ^ Origen); Image ^ ComprimeImagen(); Image ^ ComprimeImagen(Image ^ Origen); Image ^ ExpandeImagen(); Bitmap ^ ConvierteBN(); };

-57-

Anexo
Procesador.cpp
#include "StdAfx.h" #include "Procesador.h" Procesador::Procesador(void) { this->AnchoImgComp = 4; this->AltoImgComp = 3; MatrizColor = gcnew ColorMatrix(); MatrizColor->Matrix00=0.11f; MatrizColor->Matrix01=0.11f; MatrizColor->Matrix02=0.11f; MatrizColor->Matrix10=0.59f; MatrizColor->Matrix11=0.59f; MatrizColor->Matrix12=0.59f; MatrizColor->Matrix20=0.3f; MatrizColor->Matrix21=0.3f; MatrizColor->Matrix22=0.3f; MatrizColor->Matrix33=1.0f; MatrizColor->Matrix44=1.0f; AtributosImagen = gcnew ImageAttributes(); AtributosImagen->SetColorMatrix(MatrizColor); } Procesador::Procesador(Image ^ Origen) { this->ImagenBase = Origen; this->AnchoImgComp = 4; this->AltoImgComp = 3; MatrizColor = gcnew ColorMatrix(); MatrizColor->Matrix00=0.11f; MatrizColor->Matrix01=0.11f; MatrizColor->Matrix02=0.11f; MatrizColor->Matrix10=0.59f; MatrizColor->Matrix11=0.59f; MatrizColor->Matrix12=0.59f; MatrizColor->Matrix20=0.3f; MatrizColor->Matrix21=0.3f; MatrizColor->Matrix22=0.3f; MatrizColor->Matrix33=1.0f; MatrizColor->Matrix44=1.0f; AtributosImagen = gcnew ImageAttributes(); AtributosImagen->SetColorMatrix(MatrizColor); } Image ^ Procesador::ComprimeImagen(Image ^ Origen) { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; Auxiliar = gcnew Bitmap(this->AnchoImgComp,this->AltoImgComp); Tapiz = Graphics::FromImage(Auxiliar); Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::HighQualityBicubic;

-58-

Anexo
Tapiz->DrawImage(Origen,0,0,this->AnchoImgComp, this->AltoImgComp); ImagenComprimida = (Image ^)(Auxiliar); return (Image ^)gcnew Bitmap(Auxiliar); } Image ^ Procesador::ComprimeImagen() { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; Auxiliar = gcnew Bitmap(this->AnchoImgComp,this->AltoImgComp); Tapiz = Graphics::FromImage(Auxiliar); Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::HighQualityBicubic; Tapiz->DrawImage(ImagenBase,0,0,this->AnchoImgComp, this->AltoImgComp); ImagenComprimida = (Image ^)(Auxiliar); return (Image ^)gcnew Bitmap(Auxiliar); } Image ^ Procesador::ExpandeImagen() { Graphics ^ Tapiz; Image ^ Salida; Bitmap ^ Auxiliar; Auxiliar = gcnew Bitmap(ImagenBase->Width,ImagenBase->Height); Tapiz = Graphics::FromImage(Auxiliar); Tapiz->InterpolationMode = System::Drawing::Drawing2D:: InterpolationMode::High; Tapiz->DrawImage(ImagenComprimida,0,0, ImagenBase->Width,ImagenBase->Height); return (Image ^)gcnew Bitmap(Auxiliar); } Bitmap ^ Procesador::ConvierteBN() { Graphics ^ Tapiz; ImagenBN = gcnew Bitmap( ImagenComprimida->Width,ImagenComprimida->Height); Tapiz = Graphics::FromImage(ImagenBN); Tapiz->DrawImage(ImagenComprimida, Rectangle(0,0,ImagenComprimida->Width, ImagenComprimida->Height),0,0, ImagenComprimida->Width,ImagenComprimida->Height, GraphicsUnit::Pixel,AtributosImagen); return ImagenBN; }

-59-

Anexo

Clase Genera Huellas

-60-

Anexo
GeneraHuellas.h
pragma once #include "Huellas.h" using namespace System; using namespace System::IO; using namespace System::Collections::Generic; ref class GeneraHuellas { public: OpenFileDialog ^ Explorador; StreamWriter ^ FicheroEscritura; StreamReader ^ FicheroLectura; GeneraHuellas(void); void CrearArchivo(); void AbrirArchivo(); void Aadir(Huellas ^ Nueva); void GuardarTodo(); void LeerArchivoCompleto(); String ^ ExtraeBits(String ^ Huella); String ^ ExtraeBits(Huellas ^ Huella); bool BuscaHuella(Huellas ^ Huella); List<Huellas ^> ^ Lista; List<String ^> ^ ListaCadenas; };

-61-

Anexo
GeneraHuellas.cpp
#include "StdAfx.h" #include "GeneraHuellas.h" GeneraHuellas::GeneraHuellas(void) { Lista = gcnew List<Huellas ^>(); ListaCadenas = gcnew List<String ^>(); Explorador = gcnew OpenFileDialog(); } void GeneraHuellas::AbrirArchivo() { Explorador->Filter = "txt files (*.txt)|*.txt"; Explorador->ShowDialog(); if(File::Exists(Explorador->FileName)) { FicheroLectura = gcnew StreamReader(Explorador->FileName); }else{ File::Create(Explorador->InitialDirectory+"Huellas2.txt"); } } void GeneraHuellas::CrearArchivo() { Explorador->Filter = "txt files (*.txt)|*.txt"; Explorador->ShowDialog(); if(File::Exists(Explorador->FileName)) { FicheroEscritura = gcnew StreamWriter( Explorador->FileName); }else{ File::Create(Explorador->InitialDirectory+"Huellas2.txt"); } FicheroEscritura->WriteLine( "Cadena binaria"+"\t"+"Nombre del anuncio\t"+ "Nmero de anuncio"); } void GeneraHuellas::Aadir(Huellas ^ Nueva) { Lista->Add(Nueva); }

-62-

Anexo
void GeneraHuellas::GuardarTodo() { int i,j; String ^ Linea; for(j=0;j<Lista->Count;j++) { for(i=0;i<Lista[j]->HuellaBinaria->Length;i++) { Linea = Linea->Concat( Linea,System::Convert::ToDecimal( Lista[j]->HuellaBinaria->Get(i))); } FicheroEscritura->WriteLine( Linea+"\t\t"+"Anuncio\t\t\t"+j); Linea = Linea->Remove(0); } FicheroEscritura->Close(); } void GeneraHuellas::LeerArchivoCompleto() { String ^ Linea, ^a; Huellas ^ Huella; array<String ^,1> ^ charSeparators; charSeparators = gcnew array<String ^,1>(1); charSeparators[0] = gcnew String("\t"); FicheroLectura->ReadLine(); //Quitamos la primera lnea del //archivo que contiene los campos while(!FicheroLectura->EndOfStream) { Linea = FicheroLectura->ReadLine(); a = ExtraeBits(Linea); Huella = gcnew Huellas(a); Huella->CadenaHuella = a; Huella->Anuncio = Linea->Split( charSeparators, System::StringSplitOptions:: RemoveEmptyEntries)[1]; Huella->NumeroAnuncio = Convert::ToInt32( Linea->Split(charSeparators, System::StringSplitOptions:: RemoveEmptyEntries)[2]); Lista->Add(Huella); ListaCadenas->Add(a); } FicheroLectura->Close(); } String ^ GeneraHuellas::ExtraeBits(System::String ^Huella) { String ^ Bits; Bits = gcnew String(""); Bits = Huella->Substring(0,12); return Bits; }

-63-

Anexo
String ^ GeneraHuellas::ExtraeBits(Huellas ^ Huella) { int i; String ^ cadena; cadena = gcnew String(""); for(i=0;i<Huella->HuellaBinaria->Length;i++) { cadena = cadena + String:: Concat(Convert::ToInt16(Huella->HuellaBinaria->Get(i))); } return cadena; } bool GeneraHuellas::BuscaHuella(Huellas ^ Huella) { bool Encontrado; BitArray ^ Xor, ^ A, ^ B; List<Huellas ^> ^ CopiaLista; array<bool> ^ Convierte; int i,b; b = 0; Encontrado = false; Convierte = gcnew array<bool>(12); CopiaLista = gcnew List<Huellas ^>(); CopiaLista = Lista; for(i=0; i < CopiaLista->Count; i++) { Xor = CopiaLista[i]->HuellaBinaria->Xor( Huella->HuellaBinaria); Xor->CopyTo(Convierte,0); b = Convierte->LastIndexOf(Convierte,true); if(b<0) { Encontrado = true; Huella->NumeroAnuncio = i; } } return Encontrado; }

-64-

Anexo

Clase Huellas

-65-

Anexo
Huellas.h
#pragma once #include "procesador.h" using using using using using namespace namespace namespace namespace namespace System; System::Collections; System::Drawing; System::Drawing::Imaging; System::Windows::Forms;

ref class Huellas : public Procesador { public: BitArray ^ HuellaBinaria; Procesador ^ Huella; String ^ CadenaHuella; int NumeroBits; String ^ Anuncio; int NumeroAnuncio; DateTime ^ FechaHora; //Bitmap ^ aux; Huellas(void); Huellas(Procesador ^ Huella); Huellas(String ^ Huella); BitArray ^ Genera(); BitArray ^ Genera(String ^ Huella); BitArray ^ Genera(Procesador ^ Huella); BitArray ^ Huellas::Genera(array<Color> ^ ListaPixelBN); array<Color> ^ GeneraListaBN(Bitmap ^ ImagenBN); bool ComparaPixel(Color ^ Actual, Color ^ Siguiente); bool Huellas::ComparaHuellas( BitArray ^ Huella1,BitArray ^ Huella2); String ^ ExtraeBits(Huellas ^Huella); };

-66-

Anexo
Huellas.cpp
#include "StdAfx.h" #include "Huellas.h" Huellas::Huellas(void) { this->NumeroBits = 12; HuellaBinaria = gcnew BitArray(NumeroBits); this->Huella = gcnew Procesador(); } Huellas::Huellas(Procesador ^ Huella) { NumeroBits = Huella->AltoImgComp*Huella->AnchoImgComp; HuellaBinaria = gcnew BitArray(NumeroBits); this->FechaHora = gcnew DateTime(); this->Huella = Huella; this->AltoImgComp = Huella->AltoImgComp; this->AnchoImgComp = Huella->AnchoImgComp; this->AtributosImagen = Huella->AtributosImagen; this->ImagenBase = Huella->ImagenBase; this->ImagenBN = Huella->ImagenBN; this->ImagenComprimida = Huella->ImagenComprimida; } Huellas::Huellas(String ^ Huella) { NumeroBits = Huella->Length; HuellaBinaria = Genera(Huella); } BitArray ^ Huellas::Genera() { int i,j,ind; BitArray ^ Aux; array<Color> ^ ListaPixelBN; ListaPixelBN = gcnew array<Color>(16); Aux = gcnew BitArray(16); ind = 0; for(j=0; j<Huella->AltoImgComp; j++) { for(i=0;i<Huella->AnchoImgComp;i++) { if(j ==Huella->AltoImgComp-1 && i == Huella->AnchoImgComp-1) { HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel(0,0))); }else{ if(j == Huella->AltoImgComp - 1)

-67-

Anexo
{ HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel(i+1,j))); }else{ if(i == Huella->AnchoImgComp - 1) { HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel(0,j+1))); }else{ HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel( i+1,j))); } } } ind ++; } } return Aux; } BitArray ^ Huellas::Genera(System::String ^Huella) { int i,c; bool a; BitArray ^ Aux; Aux = gcnew BitArray(Huella->Length); for(i=0; i<Huella->Length; i++) { c = Convert::ToInt32(Huella->Substring(i,1)); a = Convert::ToBoolean(c); Aux->Set(i,a); } return Aux; } BitArray ^ Huellas::Genera(array<Color> ^ ListaPixelBN) { int i,j,ind; BitArray ^ Aux; Aux = gcnew BitArray(NumeroBits); ind = 0; for(j=0; j<Huella->AltoImgComp; j++) { for(i=0;i<Huella->AnchoImgComp;i++) { if(j == Huella->AltoImgComp-1 && i == Huella->AnchoImgComp-1) {

-68-

Anexo
HuellaBinaria->Set(ind,ComparaPixel( (Color ^)ListaPixelBN->GetValue(ind), (Color ^)ListaPixelBN->GetValue(0))); }else{ HuellaBinaria->Set(ind,ComparaPixel( (Color ^)ListaPixelBN->GetValue(ind), (Color ^)ListaPixelBN->GetValue(ind+1))); } ind ++; } } return Aux; } BitArray ^ Huellas::Genera(Procesador ^ Huella) { int i,j,ind; BitArray ^ Aux; Aux = gcnew BitArray(NumeroBits); ind = 0; for(j=0; j<Huella->AltoImgComp; j++) { for(i=0;i<Huella->AnchoImgComp;i++) { if(j ==Huella->AltoImgComp-1 && i == Huella->AnchoImgComp-1) { HuellaBinaria->Set(ind,ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel(0,0))); }else{ if(j == Huella->AltoImgComp - 1) { HuellaBinaria->Set(ind,ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel(i+1,j))); }else{ if(i == Huella->AnchoImgComp - 1) { HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN-GetPixel(0,j+1))); }else{ HuellaBinaria->Set(ind, ComparaPixel( Huella->ImagenBN->GetPixel(i,j), Huella->ImagenBN->GetPixel( i+1,j))); } } } ind ++; } } return Aux; }

-69-

Anexo
bool Huellas::ComparaPixel(Color ^ Actual, Color ^ Siguiente) { bool resultado; int valor; valor = ( Siguiente->R*0.3+Siguiente->G*0.59+Siguiente->B*0.11) - ( Actual->R*0.3+Actual->G*0.59+Actual->B*0.11) ; if(valor > 0) { resultado = true; }else{ resultado = false; } return resultado; } bool Huellas::ComparaHuellas(BitArray ^ Huella1,BitArray ^ Huella2) { bool Resultado; array<bool> ^ Iguales = { true,true,true,true,true,true,true,true,true,true,true,true}; Resultado = false; if(Huella1->Xor(Huella2) == gcnew BitArray(Iguales)) { Resultado = true; }else{ Resultado = false; } return Resultado; } array<Color> ^ Huellas::GeneraListaBN( System::Drawing::Bitmap ^ImagenBN) { int i,j,ind; array<Color> ^ ListaPixelBN; ListaPixelBN = gcnew array<Color>(NumeroBits); ind = 0; for(j=0; j<Huella->AltoImgComp; j++) { for(i=0;i<Huella->AnchoImgComp;i++) { ListaPixelBN->SetValue(ImagenBN->GetPixel(i,j),ind); ind++; } } return ListaPixelBN; }

-70-

Anexo
String ^ Huellas::ExtraeBits(Huellas ^Huella) { int i; String ^ cadena; cadena = gcnew String(""); for(i=0;i<Huella->HuellaBinaria->Length;i++) { cadena = cadena + String::Concat( Convert::ToInt16(Huella->HuellaBinaria->Get(i))); } return cadena; }

-71-

Anexo

Clase Detecta

-72-

Anexo
Detecta.h
#pragma once #include "GeneraBD.h" #include "Huellas.h" using namespace System::IO; using namespace System::Collections::Generic; ref class Detecta : public GeneraBD { public: Detecta(void); Detecta(System::Windows::Forms::ListBox ^SalidaTexto, AxMSVidCtlLib::AxMSVidCtl ^TV); void GuardarTodo(); void CrearArchivo(); void Aadir(Huellas ^ Anuncio); GeneraBD ^ BaseDatos; StreamWriter ^ Fichero; OpenFileDialog ^ Explorador; GeneraHuellas ^ ArchivoAnuncios; };

-73-

Anexo
Detecta.cpp
#include "StdAfx.h" #include "Detecta.h" Detecta::Detecta(void) { BaseDatos = gcnew GeneraBD(); this->HuellaAnterior = BaseDatos->HuellaAnterior; this->HuellaActual = BaseDatos->HuellaActual; this->PDI = BaseDatos->PDI; this->TV = BaseDatos->TV; this->ArchivoAnuncios = BaseDatos->ArchivoHuellas; } Detecta::Detecta(System::Windows::Forms::ListBox ^SalidaTexto, AxMSVidCtlLib::AxMSVidCtl ^TV) { BaseDatos = gcnew GeneraBD(SalidaTexto,TV); this->HuellaAnterior = BaseDatos->HuellaAnterior; this->HuellaActual = BaseDatos->HuellaActual; this->PDI = BaseDatos->PDI; this->TV = BaseDatos->TV; this->ArchivoAnuncios = gcnew GeneraHuellas(); this->Explorador = gcnew OpenFileDialog(); } void Detecta::CrearArchivo() { Explorador->Filter = "txt files (*.txt)|*.txt"; Explorador->ShowDialog(); if(File::Exists(Explorador->FileName)) { Fichero = gcnew StreamWriter(Explorador->FileName); } Fichero->WriteLine( "Nombre anuncio"+"\t\t"+"Fecha\t\t\t\t\t"+"Hora"); } void Detecta::GuardarTodo() { int i; for(i=0;i<ArchivoAnuncios->Lista->Count;i++) { Fichero->WriteLine( ArchivoAnuncios->Lista[i]->Anuncio+"\t\t"+ ArchivoAnuncios->Lista[i]->FechaHora->ToLongDateString( )+"\t\t"+ ArchivoAnuncios->Lista[i]->FechaHora->ToString( "hh:mm:ss.fff")); } Fichero->Close(); }

-74-

Anexo
void Detecta::Aadir(Huellas ^Anuncio) { ArchivoAnuncios->Aadir(Anuncio); }

-75-

Anexo

Clase PFC Detecta Anuncios

-76-

Anexo
(PFC Detecta Anuncios)Form1.h
#pragma once #include #include #include #include #include #include "Detecta.h" "GeneraBD.h" "Huellas.h" "Procesador.h" "Reproductor.h" "Rendimiento.h"

namespace PFCDetectaAnuncios { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Windows::Forms; using namespace System::Threading; /// /// /// /// /// /// /// /// /// /// /// /// <summary> Resumen de Form1 ADVERTENCIA: si cambia el nombre de esta clase, deber cambiar la propiedad 'Nombre de archivos de recursos' de la herramienta de compilacin de recursos administrados asociada con todos los archivos .resx de los que depende esta clase. De lo contrario, los diseadores no podrn interactuar correctamente con los recursos adaptados asociados con este formulario. </summary>

public ref class Form1 : public System::Windows::Forms::Form { public: bool CambioPlano; DateTime ^ t1; Detecta ^ Anuncios; Form1(void) { InitializeComponent(); // //TODO: agregar cdigo de constructor aqu // } protected: /// <summary> /// Limpiar los recursos que se estn utilizando. /// </summary> ~Form1() {

-77-

Anexo
if (components) { delete components; } } private: AxMSVidCtlLib::AxMSVidCtl^ SalidaVideo; private: System::Windows::Forms::ListBox^ SalidaTexto; protected: protected: private: System::Windows::Forms::NumericUpDown^ EntradaFiltro; private: System::Windows::Forms::Label^ label1; private: System::Windows::Forms::Button^ button1; private: System::Windows::Forms::Button^ button2; private: System::Windows::Forms::Timer^ Reloj; private: System::ComponentModel::IContainer^ components; private: /// <summary> /// Variable del diseador requerida. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Mtodo necesario para admitir el Diseador. /// No se puede modificar /// el contenido del mtodo con el editor de cdigo. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel ::Container()); System::ComponentModel:: ComponentResourceManager^ resources = ( gcnew System::ComponentModel:: ComponentResourceManager(Form1::typeid)); this->SalidaVideo = (gcnew AxMSVidCtlLib:: AxMSVidCtl()); this->SalidaTexto = (gcnew System:: Windows::Forms::ListBox()); this->EntradaFiltro = (gcnew System:: Windows::Forms::NumericUpDown()); this->label1 = (gcnew System:: Windows::Forms::Label()); this->button1 = (gcnew System:: Windows::Forms::Button()); this->button2 = (gcnew System:: Windows::Forms::Button()); this->Reloj = (gcnew System:: Windows::Forms::Timer(this->components)); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >( this->SalidaVideo))->BeginInit(); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >( this->EntradaFiltro))->BeginInit(); this->SuspendLayout();

-78-

Anexo
// // SalidaVideo // this->SalidaVideo->Location = System::Drawing:: Point(12, 12); this->SalidaVideo->Name = L"SalidaVideo"; this->SalidaVideo->OcxState = ( cli::safe_cast<System::Windows::Forms::AxHost:: State^ >(resources->GetObject( L"SalidaVideo.OcxState"))); this->SalidaVideo->Size = System::Drawing::Size( 352, 352); this->SalidaVideo->TabIndex = 0; // // SalidaTexto // this->SalidaTexto->FormattingEnabled = true; this->SalidaTexto->Location = System:: Drawing::Point(379, 113); this->SalidaTexto->Name = L"SalidaTexto"; this->SalidaTexto->Size = System::Drawing::Size( 303, 251); this->SalidaTexto->TabIndex = 1; // // EntradaFiltro // this->EntradaFiltro->Location = System:: Drawing::Point(379, 66); this->EntradaFiltro->Maximum = System::Decimal( gcnew cli::array< System::Int32 >(4) {50, 0, 0, 0}); this->EntradaFiltro->Name = L"EntradaFiltro"; this->EntradaFiltro->Size = System:: Drawing::Size(120, 20); this->EntradaFiltro->TabIndex = 2; this->EntradaFiltro->Value = System::Decimal( gcnew cli::array< System::Int32 >(4) {18, 0, 0, 0}); // // label1 // this->label1->AutoSize = true; this->label1->Font = ( gcnew System::Drawing::Font(L"Microsoft Sans Serif", 10, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0))); this->label1->Location = System::Drawing::Point( 376, 37); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(100, 17); this->label1->TabIndex = 3; this->label1->Text = L"Filtro de negro";

-79-

Anexo
// // button1 // this->button1->Location = System::Drawing::Point( 572, 27); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(110, 23); this->button1->TabIndex = 4; this->button1->Text = L"Comenzar"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler( this, &Form1::button1_Click); // // button2 // this->button2->Location = System::Drawing::Point( 572, 66); this->button2->Name = L"button2"; this->button2->Size = System::Drawing::Size(110, 23); this->button2->TabIndex = 5; this->button2->Text = L"Detener"; this->button2->UseVisualStyleBackColor = true; this->button2->Click += gcnew System::EventHandler( this, &Form1::button2_Click); // // Reloj // this->Reloj->Interval = 10; this->Reloj->Tick += gcnew System::EventHandler( this, &Form1::Reloj_Tick); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF( 6, 13); this->AutoScaleMode = System::Windows::Forms:: AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(694, 376); this->Controls->Add(this->button2); this->Controls->Add(this->button1); this->Controls->Add(this->label1); this->Controls->Add(this->EntradaFiltro); this->Controls->Add(this->SalidaTexto); this->Controls->Add(this->SalidaVideo); this->Name = L"Form1"; this->Text = L"Detecta anuncios"; (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->SalidaVideo))->EndInit(); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->EntradaFiltro))->EndInit(); this->ResumeLayout(false); this->PerformLayout(); }

-80-

Anexo
#pragma endregion private: System::Void button2_Click(System::Object^ System::EventArgs^ e) { /* * * * * * */

sender,

Se realiza una finalizacin de la aplicacin controlada: 1) Se detiene el Timer para que no se produzcan ms eventos del mismo 2) Se detiene el controlador de vdeo MSVidCtl 3) Se guardan los resultados obtenidos en el fichero de salida con los anuncios detectados Reloj->Stop(); Anuncios->TV->Parar(); Anuncios->GuardarTodo(); }

private: System::Void button1_Click(System::Object^ System::EventArgs^ e) { /* * * * * * * * * * * * * */

sender,

Se realiza la inicializacin de la aplicacin: 1) Se inicializan banderas de control y se configuran propiedades de interfaz 2) Se realiza la instancia de la clase principal Detecta 3) Se realiza la apertura del archivo con las huellas y se almacenan para un uso posterior 4) Se realiza la apertura del archivo donde sern guardados los anuncios detectados 5) Se inicia la reproduccin del vdeo por parte de MSVidCtl(la fuente de vdeo es solicitada al realizarse la llamada al constructor Detecta) 6) Se activan los eventos del Timer para comenzar a capturar frames CambioPlano = false; EntradaFiltro->ReadOnly = true; Anuncios = gcnew Detecta(SalidaTexto,SalidaVideo); Anuncios->BaseDatos->ArchivoHuellas->Explorador ->Title = "Seleccin del archivo de huellas"; Anuncios->BaseDatos->ArchivoHuellas->AbrirArchivo(); Anuncios->BaseDatos->ArchivoHuellas ->LeerArchivoCompleto(); Anuncios->Explorador->Title = "Seleccin del archivo de anuncios"; Anuncios->CrearArchivo(); Anuncios->FiltroLP = Convert:: ToInt16(EntradaFiltro->Value); Anuncios->TV->Reproduce(); Reloj->Start(); }

-81-

Anexo
private: System::Void Reloj_Tick(System::Object^ System::EventArgs^ e) { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ sender,

Se trata del evento asociado al Timer que se producir cada un nmero de milisegundos determinado por la propiedad Interval de la instancia Reloj: 1) Se captura la imagen, se comprime y se convierte a escala de grises 2) Se comprueba si el frame capturado pertenece a un cambio de plano 2.1)(true) Se guarda la hora actual del sistema, se activa la bandera cambio de plano y se limpia la salida de texto. 2.2)(false) Se comprueba si el frame actual es un frame cualquiera o el primer frame tras el ltimo cambio de plano. Es decir, el primer frame de vdeo, que es al que hay que calcularle la huella. 2.2.1)(true) Se calcula el tiempo transcurrido desde el primer cambio de plano y el primer frame de vdeo que no es cambio de plano. Esta operacin es realizada para sincronizar la captura del primer frame en la aplicacin de generacin de huellas y en deteccin de huellas. Si no se hiciese, dependiendo de cada ordenador, podra ocurrir que el tiempo de muestreo del frame fuese tan dispar que las huellas no fuesen iguales. Por defecto, se establece que se muestrea tanto en la aplicacin de generacin de huellas como en la de deteccin, 50 ms tras el primer cambio de plano. Se justificar este valor ms adelante. 2.2.1.1)(true) Han pasado ms de 50 ms y el plano actual no es un cambio de plano. a) La bandera CambioPlano se pone a false. b) Se genera una huella a partir de la captura actual. c) Busca la huella actual en la lista de huellas(ListaCadenas) 2.2.1.1.1)(true) Se ha detectado la huella y se conoce la posicin en la lista. a) Se limpia la salida de texto b) De la clase anuncios se prepara la HuellaActual y se guarda en la lista de anuncios detectados. c) Se imprimen por pantalla informacin referente al anuncio detectado

int i,delay; int EncuentraAnuncio; DateTime ^ t2; delay = -1; EncuentraAnuncio = -1; Anuncios->PDI->ComprimeImagen( Anuncios->TV->CapturaImagen()); Anuncios->PDI->ConvierteBN(); if(Anuncios->CambioPlano(Anuncios->PDI->ImagenBN)) {

-82-

Anexo
t1 = DateTime::Now; CambioPlano = true; SalidaTexto->Items->Clear(); }else{ /*Aqu tenemos que distinguir entre un frame cualquiera y el primer frame tras cambio de plano*/ if(CambioPlano==true) { t2 = DateTime::Now; delay = (TimeSpan(t1->Ticks t2->Ticks)).Milliseconds; if(Math::Abs(delay) > 50) { CambioPlano = false; Anuncios->HuellaActual = gcnew Huellas( Anuncios->PDI); Anuncios->HuellaActual->Genera(); SalidaTexto->Items->Add( "Nuevo posible anuncio: "+Anuncios ->HuellaActual->ExtraeBits(Anuncios ->HuellaActual)+" NO ENCONTRADO"); Anuncios->HuellaActual->CadenaHuella = Anuncios->HuellaActual->ExtraeBits( Anuncios->HuellaActual); EncuentraAnuncio = Anuncios->BaseDatos ->ArchivoHuellas->ListaCadenas ->LastIndexOf(Anuncios->HuellaActual ->CadenaHuella); if(EncuentraAnuncio>-1) { SalidaTexto->Items->Clear(); Anuncios->HuellaActual ->NumeroAnuncio = EncuentraAnuncio; Anuncios->HuellaActual->Anuncio = Anuncios->BaseDatos->ArchivoHuellas ->Lista[EncuentraAnuncio]->Anuncio; Anuncios->HuellaActual->FechaHora = DateTime::Now; Anuncios->Aadir(Anuncios ->HuellaActual); SalidaTexto->Items->Add( "Nuevo ANUNCIO DETECTADO: "); SalidaTexto->Items->Add( "Nmero de lnea en archivo huellas: "+EncuentraAnuncio); SalidaTexto->Items->Add(Anuncios ->HuellaActual->Anuncio); SalidaTexto->Items->Add("Tiempo transcurrido desde el final del cambio de plano: " + Math:: Abs(delay)+" ms");
} } } } } }; }

-83-

Anexo

Clase PFC Genera Huellas

-84-

Anexo

(PFC Genera Huellas)Form1.h


#pragma once #include #include #include #include #include "GeneraBD.h" "Huellas.h" "Procesador.h" "Reproductor.h" "Rendimiento.h"

namespace PFCGeneraHuellas { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Windows::Forms; using namespace System::Threading; /// /// /// /// /// /// /// /// /// /// /// <summary> Resumen de Form1 ADVERTENCIA: si cambia el nombre de esta clase, deber cambiar la propiedad 'Nombre de archivos de recursos' de la herramienta de compilacin de recursos administrados asociada con todos los archivos .resx de los que depende esta clase. De lo contrario, los diseadores no podrn interactuar correctamente con los recursos adaptados asociados con este formulario. </summary>

public ref class Form1 : public System::Windows::Forms::Form { public: bool CambioPlano; DateTime ^ t1; GeneraBD ^ BaseDatos; private: System::Windows::Forms::NumericUpDown^ EntradaFiltro; public: Form1(void) { InitializeComponent(); // //TODO: agregar cdigo de constructor aqu // } protected: /// <summary> /// Limpiar los recursos que se estn utilizando. /// </summary>

-85-

Anexo
~Form1() { if (components) { delete components; } } private: AxMSVidCtlLib::AxMSVidCtl^ SalidaVideo; protected: private: System::Windows::Forms::ListBox^ SalidaTexto; private: System::Windows::Forms::Button^ button1; private: System::Windows::Forms::Button^ button2; private: System::Windows::Forms::Label^ label1; private: System::Windows::Forms::Timer^ Reloj; private: System::ComponentModel::IContainer^ components; private: /// <summary> /// Variable del diseador requerida. /// </summary> #pragma region Windows Form Designer generated code /// <summary> /// Mtodo necesario para admitir el Diseador. No se puede /// modificar el contenido del mtodo con el editor de /// cdigo. /// </summary> void InitializeComponent(void) { this->components = (gcnew System::ComponentModel:: Container()); System::ComponentModel:: ComponentResourceManager^ resources = ( gcnew System::ComponentModel:: ComponentResourceManager(Form1::typeid)); this->SalidaVideo = (gcnew AxMSVidCtlLib:: AxMSVidCtl()); this->SalidaTexto = (gcnew System::Windows::Forms:: ListBox()); this->button1 = (gcnew System::Windows::Forms:: Button()); this->button2 = (gcnew System::Windows::Forms:: Button()); this->label1 = (gcnew System::Windows::Forms:: Label()); this->Reloj = (gcnew System::Windows::Forms:: Timer(this->components)); this->EntradaFiltro = (gcnew System::Windows::Forms:: NumericUpDown()); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->SalidaVideo)) ->BeginInit(); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->EntradaFiltro)) ->BeginInit(); this->SuspendLayout(); // // SalidaVideo //

-86-

Anexo
this->SalidaVideo->Location = System::Drawing:: Point(12, 12); this->SalidaVideo->Name = L"SalidaVideo"; this->SalidaVideo->OcxState = (cli:: safe_cast<System::Windows::Forms::AxHost:: State^ >(resources->GetObject( L"SalidaVideo.OcxState"))); this->SalidaVideo->Size = System::Drawing::Size( 333, 320); this->SalidaVideo->TabIndex = 0; // // SalidaTexto // this->SalidaTexto->FormattingEnabled = true; this->SalidaTexto->Location = System::Drawing:: Point(367, 81); this->SalidaTexto->Name = L"SalidaTexto"; this->SalidaTexto->Size = System::Drawing::Size( 322, 251); this->SalidaTexto->TabIndex = 1; // // button1 // this->button1->Location = System::Drawing::Point( 483, 29); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(100, 23); this->button1->TabIndex = 2; this->button1->Text = L"Comenzar"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler( this, &Form1::button1_Click); // // button2 // this->button2->Location = System::Drawing::Point( 589, 29); this->button2->Name = L"button2"; this->button2->Size = System::Drawing::Size(100, 23); this->button2->TabIndex = 3; this->button2->Text = L"Detener"; this->button2->UseVisualStyleBackColor = true; this->button2->Click += gcnew System::EventHandler( this, &Form1::button2_Click); // // label1 // this->label1->AutoSize = true; this->label1->Location = System::Drawing::Point( 364, 12); this->label1->Name = L"label1"; this->label1->Size = System::Drawing::Size(74, 13); this->label1->TabIndex = 5; this->label1->Text = L"Filtro de negro";

-87-

Anexo
// // Reloj // this->Reloj->Interval = 10; this->Reloj->Tick += gcnew System::EventHandler( this, &Form1::Reloj_Tick); // // EntradaFiltro // this->EntradaFiltro->Location = System::Drawing:: Point(364, 32); this->EntradaFiltro->Maximum = System::Decimal( gcnew cli::array< System::Int32 >(4) {50, 0, 0, 0}); this->EntradaFiltro->Name = L"EntradaFiltro"; this->EntradaFiltro->Size = System::Drawing::Size( 100, 20); this->EntradaFiltro->TabIndex = 6; this->EntradaFiltro->Value = System::Decimal( gcnew cli::array< System::Int32 >(4) {18, 0, 0, 0}); // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF( 6, 13); this->AutoScaleMode = System::Windows::Forms:: AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(701, 344); this->Controls->Add(this->EntradaFiltro); this->Controls->Add(this->label1); this->Controls->Add(this->button2); this->Controls->Add(this->button1); this->Controls->Add(this->SalidaTexto); this->Controls->Add(this->SalidaVideo); this->Name = L"Form1"; this->Text = L"Deteccin de anuncios"; (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->SalidaVideo)) ->EndInit(); (cli::safe_cast<System::ComponentModel:: ISupportInitialize^ >(this->EntradaFiltro)) ->EndInit(); this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion private: System::Void button1_Click(System::Object^ System::EventArgs^ e) { /* * * * * * * */ sender,

Se configura todo lo necesario para poder iniciar la aplicacin: 1) Se inicializan las banderas y propiedades correspondientes 2) Se realiza la instancia de la clase GeneraBD 3) Se guarda el valor que ha introducido el usuario en la variable FiltroLP de BaseDatos 4) Se inicia la reproduccin del vdeo 5) Se activa el Timer para que tengan lugar los eventos de reloj

-88-

Anexo
CambioPlano = false; EntradaFiltro->ReadOnly = true; BaseDatos = gcnew GeneraBD( SalidaTexto,SalidaVideo); BaseDatos->FiltroLP = Convert::ToInt16( EntradaFiltro->Value); BaseDatos->TV->Reproduce(); Reloj->Start(); } private: System::Void button2_Click(System::Object^ System::EventArgs^ e) { /* * * * * */ sender,

Se realiza una parada de la aplicacin de forma controlada y ordenada: 1) Se para el Timer para que no tengan lugar los eventos 2) Se para la salida de vdeo 3) Se guardan todas la huellas detectadas en el archivo de huellas Reloj->Stop(); BaseDatos->TV->Parar(); BaseDatos->ArchivoHuellas->GuardarTodo(); }

private: System::Void Reloj_Tick(System::Object^ System::EventArgs^ e) { /* * * * * * * * * * * * * * * * * * * * * * * * * *

sender,

Se trata del evento asociado al Timer que se producir cada un nmero de milisegundos determinado por la propiedad Interval de la instancia Reloj: 1) Se captura la imagen, se comprime y se convierte a escala de grises 2) Se comprueba si el frame capturado pertenece a un cambio de plano 2.1)(true) Se guarda la hora actual del sistema, se activa la bandera cambio de plano y se limpia la salida de texto. 2.2)(false) Se comprueba si el frame actual es un frame cualquiera o el primer frame tras el ltimo cambio de plano. Es decir, el primer frame de vdeo, que es al que hay que calcularle la huella. 2.2.1)(true) Se calcula el tiempo transcurrido desde el primer cambio de plano y el primer frame de vdeo que no es cambio de plano. Esta operacin es realizada para sincronizar la captura del primer frame en la aplicacin de generacin de huellas y en deteccin de huellas. Si no se hiciese, dependiendo de cada ordenador, podra ocurrir que el tiempo de muestreo del frame fuese tan dipar que las huellas no fuesen iguales. Por defecto, se establece que se muestrea tanto en la aplicacin de generacin de huellas como en la de deteccin, 50 ms tras el primer cambio de plano. Se justificar este valor ms adelante.

-89-

Anexo
* * * * * * * * * */ 2.2.1.1)(true) Han pasado ms de 50 ms y el plano actual no es un cambio de plano. a) La bandera CambioPlano se pone a false. b) Se genera una huella a partir de la captura actual. c) Guarda la huella actual en la lista de huellas(Lista) d) Se imprimen por pantalla informacin referente al anuncio detectado int i,delay; DateTime ^ t2; delay = -1; BaseDatos->PDI->ComprimeImagen(BaseDatos->TV ->CapturaImagen()); BaseDatos->PDI->ConvierteBN(); if(BaseDatos->CambioPlano(BaseDatos->PDI ->ImagenBN)) { t1 = DateTime::Now; CambioPlano = true; SalidaTexto->Items->Clear(); }else{ /*Aqu tenemos que distinguir entre un frame cualquiera y el primer frame tras cambio de plano*/ if(CambioPlano==true) { t2 = DateTime::Now; delay = (TimeSpan(t1->Ticks - t2 ->Ticks)).Milliseconds; if(Math::Abs(delay) > 50) { CambioPlano = false; BaseDatos->HuellaActual = gcnew Huellas( BaseDatos->PDI); BaseDatos->HuellaActual->Genera(); BaseDatos->ArchivoHuellas->Aadir( BaseDatos->HuellaActual); SalidaTexto->Items->Add( "Nuevo cambio de plano: "+BaseDatos ->ArchivoHuellas->ListaHuellas->Count); SalidaTexto->Items->Add( "Tiempo transcurrido desde el final del cambio de plano: " + Math:: Abs(delay)+" ms"); } } } } }; }

-90-

Anda mungkin juga menyukai