Académique Documents
Professionnel Documents
Culture Documents
interactivos en el arte
Emiliano Causa, Diego Alberti
ndice
Unidad
Introduccin
Unidad
Unidad
conos
Unidad
Causa, Emiliano
Sistemas interactivos en el arte / Emiliano Causa y Diego Javier Alberti. - 1a ed. Bernal: Universidad Virtual de Quilmes, 2014.
E-Book.
ISBN 978-987-3706-08-0
1. Arte. I. Alberti, Diego Javier II. Ttulo
CDD 708
conos
Leer con atencin
Para ampliar
Para reexionar
Propone un dilogo con el material a travs de preguntas, planteamiento de problemas, confrontaciones del tema con la
realidad, ejemplos o cuestionamientos que
alienten la autorreexin.
Texto aparte
Contiene citas de autor, pasajes que contextualicen el desarrollo temtico, estudio de
casos, notas periodsticas, comentarios para
formular aclaraciones o profundizaciones.
Pastilla
Incorpora informaciones breves, complementarias o aclaratorias de algn trmino o
frase del texto principal. El subrayado indica
los trminos a propsito de los cuales se incluye esa informacin asociada en el margen.
Cita
Se diferencia de la palabra del autor de la
Carpeta a travs de la insercin de comillas, para indicar claramente que se trata de
otra voz que ingresa al texto.
Ejemplo
Se utiliza para ilustrar una denicin o una
armacin del texto principal, con el objetivo
de que se puedan jar mejor los conceptos.
Cdigo
Incorpora al material un determminado
lenguaje de programacin.
Actividades
Son ejercicios, investigaciones, encuestas,
elaboracin de cuadros, grcos, resolucin de guas de estudio, etctera.
Audio
Fragmentos de discursos, entrevistas, registro oral del profesor explicando algn
tema, etctera.
Audiovisual
Videos, documentales, conferencias, fragmentos de pelculas, entrevistas, grabaciones, etctera.
Recurso web
Links a sitios o pginas web que resulten
una referencia dentro del campo disciplinario.
Lectura obligatoria
Textos completos, captulos de libros, artculos y papers que se encuentran digitalizados en el aula virtual.
Lectura recomendada
Bibliografa que no se considera obligatoria y a la que se puede recurrir para ampliar
o profundizar algn tema.
Lnea de tiempo
Se utiliza para comprender visualmente
una sucesin cronolgica de hechos.
ndice
Los autores
Introduccin
Objetivos del curso
7
8
8
Unidad 3
Unidad 1
Sistemas interactivos en el arte
1.1. Introduccin
9
1.2. Arquitectura de un sistema interactivo
10
1.2.1. Instalaciones interactivas
12
1.2.2. Hardware y software de los sistemas
interactivos en el arte: lo fsico y lo virtual 14
1.2.3. Los campos de accin: sensado,
reproduccin, generacin y control
15
1.2.4. Lenguajes de programacin y herramientas
de control
16
1.2.5. Taxonoma del software de los sistemas
interactivos en el arte
17
1.2.6. Sistemas operativos
25
1.2.7. Sistemas pticos de sensado de posicin
y silueta
25
1.2.8. Protocolos de comunicacin
31
1.2.9. Hardware de los sistemas interactivos:
sistemas de control y sensado fsico
33
Unidad 2
Imagen y sonido en tiempo real
2.1. Introduccin
2.2. La computadora personal como herramienta
2.3. Herramientas de software
2.3.1. Pure Data (PD)
2.3.2. Processing
2.4. Ejemplo de aplicacin
2.5. Generacin de imagen a partir de Processing y
datos por osc
35
35
38
38
40
41
Unidad 4
Deteccin de contenido e interfaces tangibles
4.1. Deteccin de Blobs
4.1.1. La librera BlobDetection
4.1.2. Un ejemplo con deteccin de Blobs
4.2. Sistema de deteccin de patrones para
la implementacin de una mesa reactiva
4.2.1. El protocolo TUIO
4.2.2. El funcionamiento del ejemplo
4.3. Breve comentario final
95
98
102
111
Referencias bibliogrfcas
113
81
83
84
53
Los autores
Emiliano Causa
Naci en La Plata (Argentina) en 1970. Artista multimedia e Ingeniero en Sistemas de Informacin (Universidad Tecnolgica Nacional). Integrante fundador del grupo Proyecto Biopus
(www.biopus.com.ar). Fue Coordinador del MediaLab del Centro Cultural de Espaa en Buenos Aires. Ha sido Coordinador de la Direccin de Investigacin y Posgrado en el rea de Artes
Multimediales del IUNA. Es profesor de Arte Multimedia e Informtica Aplicada en la Licenciatura de Artes Multimediales del IUNA. Profesor de Tecnologa Multimedia de la carrera de
Diseo Mutimedial de la Facultad de Bellas Artes de la Universidad Nacional de La Plata.
Dirige el Laboratorio de Experimentacin EmmeLab de la Facultad de Bellas Artes UNLP. Es profesor de Sistemas Dinmicos II de la Maestra en Artes Electrnicas de la UNTREF. Dicta el Taller de Investigacin y Realizacin de Objetos II en
la Especializacin de Teatro de Objetos del rea de Artes Dramticas del IUNA. Trabaja en investigaciones relacionadas con Bioarte, Realidad Aumentada y Arte Generativo. Fue docente de Informtica en las carreras de Composicin
Musical y Cine en la UNLP y de Inteligencia Artificial en Ingeniera de Sistemas en la UTN.
Actualmente trabaja en investigacin y dicta cursos de posgrado relacionados al arte interactivo y nuevas interfaces
(sensores y control de video y sonido en tiempo real). Se dedica al arte interactivo, al arte generativo, a la construccin
de instalaciones interactivas y a la aplicacin de la informtica al arte en general.
Diego Alberti
Estudi Diseo de Imagen y Sonido y Diseo Grfico (FADU, UBA). Realiz diversos cursos
de posgrado y talleres relacionados con arte y nuevas tecnologas. Actualmente produce
msica electrnica, videos, software y piezas de arte digital.
Expuso su obra en Museo Macro de Rosario, Museo Municipal de Bellas Artes Juan B. Castagnino de Rosario, Museo de Arte Contemporneo de Baha Blanca, Centro Cultural Recoleta,
Centro Cultural San Martn, Centro Cultural de Espaa en Buenos Aires, Museo Municipal de
Arte ngel Mara de Rosa de Junn, Espacio Fundacin Telefnica de Buenos Aires, Museo de
Arte Moderno de Mendoza, medialabPrado Madrid y FILE Festival de San Pablo.
Es docente de la materia Informtica Aplicada 2 Artes Multimediales en el Instituto Universitario Nacional de Arte y de
la materia Dibujo y Maqueta Ctedra Vitullo de la carrera de Diseo de Imagen y Sonido en Facultad de Arquitectura
Diseo y Urbanismo de la Universidad de Buenos Aires.
Dicta cursos sobre tecnologa y nuevos medios en diversas instituciones del pas: MBA/MAC de Baha Blanca, Universidad Nacional de Noreste, Centro Cultural de Espaa en Buenos Aires, Universidad de Palermo, Centro Cultural de
Espaa Chile, Centro Cultural Balmaceda Arte Joven, Valparaso, Chile.
Trabaja y reside en Buenos Aires, desarrolla diferentes proyectos artsticos relacionados con electrnica, nuevas tecnologas y software. Colabora con artistas como Carlos Trilnick, Gabriel Valansi, Marina de Caro, Juan Rey, Mariano
Giraud, Ernesto Romeo, Jorge Haro y otros.
Introduccin
En este mateiral desarrollaremos los aspectos fundacionales de lo que consideramos elemental a cualquier obra de
arte interactiva que utilice tecnologa. Nos referimos esencialmente al uso de software para lograr aplicaciones de
audio y sonido que permitan la generacin en tiempo real de espacios sinestsicos donde imagen y sonido se complementen de manera homognea.
Utilizaremos los dispositivos ms inmediatos con los que contamos en una computadora personal para realizar actividades donde la imagen y el sonido interacten de forma dinmica.
Recurriremos a cmaras de video para detectar presencia o actividad dentro de una escena y con ella producir sonido
y como contraparte veremos cmo analizar audio proveniente de un micrfono para generar o modificar una imagen.
Consideramos que este acercamiento por dems elemental esconde un alto nivel de complejidad producto del avance constante de la tecnologa puesta en juego y de la enorme cantidad de variables que aparecen involucradas en el
desarrollo de este tipo de aplicaciones; principalmente en lo relacionado a lo azaroso del mundo real y el comportamiento imprevisible de los individuos interactuantes. En ese sentido es que invitamos a los estudiantes a profundizar
cada uno de los temas abordados a partir de los conceptos fundamentales que aqu se presentan.
Esperamos que esta coleccin de recursos sirva como disparador para poder luego ahondar en la complejidad que el
tpico propone.
Los foros y la documentacin relacionada con las aplicaciones utilizadas son nuestras fuentes de informacin, es por
eso que recomendamos a los estudiantes consultar sistemticamente toda la informacin referida a los problemas
concretos en la web ya que es all donde la informacin permanece actualizada.
Esperamos que disfruten la lectura de este material y que consigan completar con xito las consignas y ejercicios que
aqu se presentan.
1.1. Introduccin
En esta unidad nos ubicaremos en el campo de la multimedia aplicada y focalizaremos en los sistemas interactivos en
tiempo real. Entendemos por tiempo real toda aquella actividad en donde el resultado del estmulo generado por
el espectador o interactor aparece reflejado en una consecuencia sinestsica ms o menos instantnea. Llamamos
sinestsico a todo aquel fenmeno donde se ven involucrados diferentes sentidos a la vez.
La ciberntica es una ciencia introducida en la dcada de 1940 por Norbert Wiener. Trata del estudio de los
sistemas autoregulados. La idea de interactividad est ntimamente relacionada con estos conceptos aunque de manera superadora. En general, lo que se espera de una obra interactiva es que de alguna manera
dialogue con el espectador y no sea solo una accin reactiva la que deviene frente al estmulo del pblico.
Por decirlo de otra forma, un sistema interactivo es capaz de percibir al pblico o ciertas acciones o particularidades
de este y generar una respuesta a travs de dispositivos y medios de representacin. Su caracterstica central se vincula con la capacidad de lograr inmediatez entre las acciones del pblico y la respuesta generada; lo que en nuestro
campo se llama tiempo-real. La generacin de esta respuesta a travs de medios de representacin (como el sonido
y la imagen) en tiempo real, solo es posible (salvo raras excepciones) por medio del procesamiento de la informacin
mediante computadoras y por ende, las tcnicas y herramientas para la produccin de sistemas interactivos est
fuertemente ligada a la informtica y a la electrnica.
Este material no intenta ser una definicin sobre el arte interactivo en trminos conceptuales, sino ms
bien una descripcin general de nuestro objeto de estudio, abordado desde un punto de vista tecnolgico.
El campo de estudio en el que pretendemos involucrarnos es en extremo extenso por la diversidad de recursos y herramientas con las que contamos para producir
nuestras obras y por la profundidad necesaria con la
cual debemos abordar el aprendizaje de estos temas
para lograr superar las barreras tcnicas que estos dispositivos o herramientas nos presentan. Si bien esto no
debiera ser motivo de conflicto sucede que, adems
de ser un campo extenso, este se expande de manera
exponencial conforme avanza el desarrollo tecnolgico tanto de las aplicaciones como de los dispositivos
informticos. Esto a su vez trae aparejada la aparicin
repentina de nuevos espacios de accin.
Es por esto que nos vemos obligados a tratar de lograr un enfoque metodolgico y adems conceptual respecto
de las disciplinas asociadas al uso de computadoras en el arte y los multimedios. Esta unidad en particular aparece
como una introduccin a este cambiante mundo de accin en el cual los conocimientos sobre los dispositivos y herramientas que lograremos aprender hoy, seguramente sern obsoletos el da de maana. De ah la importancia de
centrarnos en los conceptos fundamentales de esta disciplina.
10
Es importante aclarar que todos los sensores con los que trabajamos convierten de alguna u otra forma
una magnitud o parmetro del mundo fsico en una magnitud elctrica. Estos sensores se encuentran generalmente conectados a una interfaz digitalizadora, es decir, un dispositivo preparado para comunicar
esas seales elctricas producidas por el sensor en el lenguaje que la computadora puede comprender.
Esto es bsicamente un conversor analgico-digital. Nuestro estudio estar fuertemente inclinado a
los sistemas de captura de sonido y pticos ya que son los dispositivos ms inmediatos y que mayores
prestaciones ofrecen al intentar capturar informacin en tiempo real de una escena o un dispositivo de
interfaz tangible.
Como material central en su trabajo, Jim Campbell utiliza la idea de memoria, por ese motivo hace hincapi dentro de
su esquema en el tem Memory (invisible): memoria invisible.
La memoria es un componente fundamental de la computadora ya que permite que las operaciones puedan ser
realizadas. La otra parte que Campbell propone como relevante son los algoritmos. En nuestro caso, esos algoritmos
y esa memoria est mediatizada por softwares disponibles tanto como producto comercial o experimental o aquellos
que nosotros mismos podemos construir para desarrollar nuestras propias experiencias.
Por ltimo, el esquema seala un controlador de salida: es cualquier dispositivo capaz de recibir instrucciones desde
un ordenador y a su vez traducir esa informacin en seales que pueden controlar diversos artefactos electrnicos o
resultados concretos esperados por tal o cual dispositivo. Campbell menciona texto que se mueve, objetos motorizados, generadores de viento, etc. En general, nos limitaremos a artefactos capaces de producir sonido o imagen
(proyectores, pantallas, sistemas de sonido, etctera).
11
En resumen, en cualquier dispositivo tecnolgico multimedial podemos encontrar tres partes claramente definidas:
un subsistema de entrada de datos, un proceso ligado a operaciones informticas (de automatizacin de datos) y un
subsistema de salida que devuelve al medio el resultado del proceso sobre los elementos de entrada.
Texto Aparte
Residua es una instalacin interactiva performtica para personas con telfonos
celulares, cantante lrica y software. Fue estrenada en el Centro Cultural Recoleta
en noviembre de 2008, en el marco del Festival Tecnoescena. La instalacin prev
dos estados: un modo de instalacin autnoma y otro de performance en vivo.
Antes de ingresar a la sala, los espectadores son informados del funcionamiento:
ingresan a un espacio construido con hojas de papel blanco que, en un principio,
se conserva prstino. El pblico puede transitar por este espacio.
Una vez all son invitados a enviar un mensaje de texto a un nmero predeterminado. Los textos enviados al sistema aparecen proyectados en las paredes de la
escenografa; a su vez, un sintetizador de voz los canta. En ese momento se inicia
12
13
Por ltimo, controlar un motor mediante una interfaz de conversin DAC puede, muchas veces, estar estrictamente
ligada al campo de los problemas fsicos: clculos de corriente y potencia, estrs mecnico de los materiales, etctera.
14
15
Texto Aparte
Todos los softwares de hoy en da vinculados al multimedia y al arte y diseo en
general traen incluidos algn sistema de scripting (pequeas estructuras de cdigo
que se ejecutan en tiempo real, sin compilacin) que permite introducir secuencias
de cdigo que son ejecutadas por el mismo programa o por alguna mquina virtualizada dentro del mismo software (es el caso por ejemplo de Blender, el software
de 3D que permite reprogramarlo completamente utilizando el lenguaje Python).
Es por eso que no podemos afirmar que un lenguaje sea mejor que otro ya que
esto depende de las necesidades especficas de lo que se quiera realizar o de lo que
ya nos es dado por los sistemas existentes.
16
17
En la imagen anterior (1.4.) se muestra la interfaz grfica de Arkaos. Como puede verse, Arkaos se encuadra dentro de
la metfora de la consola, ya que su interfaz grfica est diseada como un conjunto de paneles en los que el usuario
puede organizar el material (los videos, animaciones, efectos, etc.) y decidir a qu eventos los asocia, como sucede
en el panel inferior en el que aparece un teclado (con disposicin de teclado de piano) en el que el usuario acomoda
los videos que ejecutar con cada tecla. Tambin se pueden ver varios controles grficos que imitan potencimetros
lineales que servirn para configurar parmetros de la reproduccin y de los efectos que se aplican durante la misma.
Texto Aparte
Pasamos entonces a una breve descripcin de cada una de estas herramientas:
Arkaos
<http://www.arkaos.net>
Versin Actual: Grand VJ.
Arkaos es un producto desarrollado en Blgica, que permite manipulacin de video en tiempo real, es decir que puede tomar diversos archivos de video (o material animado incluyendo composiciones de Quartz Composer del que hablaremos en el siguiente apartado, imgenes fijas y mscaras. Puede trabajar con
hasta ocho capas de video en simultneo. Posee posibilidad de comunicacin MIDI
(protocolo de comunicacin que ser descripto en los siguientes apartados) en dos
direcciones.
Resolume
<http://www.resolume.com/avenue/>
Versin Actual: 3.0
Resolume, desarrollado en Holanda, est ntegramente escrito en C++ utilizando
libreras OpenGL, esto quiere decir que posee un motor de imagen en tiempo real
de una excelente performance. Puede manejar capas de video en HD y adems
tiene integrado un completo reproductor de audio. Reproduce varios formatos,
cuenta con un Analizador de Audio integrado, est pensado para poder realizar
Video Mapping fcilmente. Soporta mltiples pantallas y adems posee la posibilidad de conectividad. En la nueva versin 3, el cdigo de Resolume fue reescrito
desde cero (from scratch). Sus desarrolladores aseguran que esta no es solo una
versin mejorada de la original sino que a su vez est pensada desde un nuevo
paradigma tecnolgico que tiene relacin con la posibilidad de que el software se
siga expandiendo en posibilidades conforme se vaya desarrollando y mejorando
las capacidades de los hardwares grficos.
VDMX
<http://vidvox.net/>
Versin actual: 5
Las prestaciones son aproximadamente similares a los dos softwares anteriores.
Una de las ventajas que tiene este, por sobre otros, es que permite la ejecucin
de varias acciones en paralelo en forma independiente en procesadores de varios
ncleos mediante una estrategia llamada multihilo (multi thread), con lo cual el
rendimiento en tiempo real se ve extremadamente mejorado. Adems, VDMX se
publicita como la opcin ms amiga de Quartz Composer.
18
Modul8
<http://www.modul8.ch/>
Versin actual: 2.6.4
Modul8 es el ms verstil de toda la lnea ya que fue diseado principalmente por
visualizadores, vjs y artistas visuales. Sus desarrolladores son Suizos. Modul8 integra todo un espacio escnico: mltiples pantallas, sonido y adems la posibilidad
de integrar sistemas de control de luces con estndar DMX (un protocolo de comunicacin para iluminacin escnica). Sus desarrolladores tambin crearon actualmente un software muy popular para diseo de mappings llamado MadMapper
(<www.madmapper.com>).
Abletons Live
<http://www.ableton.com/live-8>
Versin Actual: Ableton Live 8
Esta herramienta no pertenece en s al mundo del VJ sino que es su equivalente
musical. Live es en realidad una suite de programas, esto es un compilado de programas todos funcionando entre s para convertir la computadora en una estacin
de trabajo musical y performtico completa.
La principal virtud de Live es que puede, a la vez que reproduce secuencias de audio pregrabadas, ejecutar secuencias MIDI que controlan sintetizadores y samplers
virtuales que corren en el mismo sistema por medio del estndar VSTi.
Otra de las grandes virtudes que hicieron a Live tan popular es que cuenta con algoritmos de Time Stretching sofisticados muy valorados por los artistas provenientes del DJing o la msica electrnica. Live puede controlar y a la vez ser controlado
tanto por otros softwares como mediante el uso de controladores discretos que se
conectan al ordenador por USB.
Como se dijo anteriormente todas estas aplicaciones son cerradas, es decir que las
posibilidades de modificacin corren solo por cuenta de sus desarrolladores.
Tambin encontramos lenguajes de programacin para contenidos multimediales que nos permitirn construir nuestras propias herramientas con funciones particulares. Estos lenguajes de programacin permiten que el usuario defina (muchas veces desde cero) cmo se orquesta la reproduccin o generacin de los contenidos.
En estos sistemas impera la lgica del algoritmo bajo dos modalidades: la primera corresponde a los entornos visuales en los que el usuario configura una red de objetos que se comunican entre s procesando de diferentes formas la
informacin.
Este tipo de entornos de programacin se denominan visuales ya que la codificacin de la secuencia lgica de funcionamiento se realiza a travs de un entorno grfico donde las funciones estn representadas fundamentalmente
por objetos interconectables. Cada uno de estos objetos tiene una serie de conexiones preestablecidas que toma o
devuelve (segn sea el caso) tipos de datos especficos.
Cada objeto en cuestin est preparado para resolver una tarea muy concreta, lo que permite una gran flexibilidad de
interconexin con el resto de los objetos con el fin de conseguir una funcionalidad ms compleja.
19
20
Texto Aparte
Pasamos entonces a una breve descripcin de cada una de estas herramientas:
Max/MSP y Pure Data
<http://cycling74.com/whatismax/spanish/>
Versin Actual: Max 6
Desarrollado en el IRCAM (Institut de Recherche et Coordination Acoustique/Musique) por Miller Puckete este software para control, en principio, y generacin de
audio digital, despus, es central en las artes multimediales ya que fue lo que posibilit que muchos artistas pudiesen explorar tempranamente la creacin de entornos interactivos. Luego de que Cycling 74 comprara el proyecto max/MSP y lo
desarrollara como producto comercial, Puckete lanz a la comunidad de software
libre la versin libre del Pure Data. Max/MSP o Pure Data con entornos grficos en
los cuales uno puede desarrollar sintetizadores o estructuras de control complejas
para controlar aparatos MIDI de manera visual conectando objetos unos con otros.
Existen tambin aplicaciones visuales que permiten programar comportamientos
de manera grfica. De hecho, Max/MSP tiene su mdulo particular destinado al
manejo de imagen llamado Jitter (cuyo anlogo en el mundo Pure Data es GEM).
Este mdulo permite desarrollar todo tipo de proyectos donde lo central es la imagen en movimiento y el anlisis posterior de dicha imagen. Jitter puede ser utilizado tanto para resolver cuestiones de visin por computadora como para producir
de manera algortmica diferentes tipos de contenidos visuales, ya sea procesando
imagen prediseada o producindola de manera generativa.
De ms est decir que ambos mundos (el visual y el sonoro) pueden convivir en la
misma aplicacin con lo cual Max/MSP + jitter (o PD+Gem) pueden ser entornos
muy adecuados para resolver instalaciones en donde se requiere que el sonido y la
imagen funcionen de manera sincrnica.
VVVV
<http://vvvv.org/tiki-index.php>
Versin Actual: 40beta23
VVVV es un sintetizador de video en tiempo real e interaccin con interfaces fsicas.
Est solo disponible para Windows ya que su motor grfico est construido sobre
la librera DirectX propia de ese sistema operativo. Es 100% tiempo real (no tiene
modos build/run) y adems es software libre y recientemente Open Source.
Quartz Composer
<http://en.wikipedia.org/wiki/Quartz_Composer>
Versin Actual: 4 (para Mac OS 10.6 Snow Leopard)
Quartz Composer es un lenguaje de programacin visual basado en nodos provisto como parte del kit de desarrollo para el sistema operativo OSX. Es solo para Mac,
basado 100% en OpenGL y permite programar filtros de imagen. Adems, tiene
un objeto que permite introducir cdigo en lenguaje Javascript (de uso comn en
sitios de Internet) y otro que permite modelar Shaders (lenguaje de programacin
para el procesador grfico) utilizando el lenguaje GLSL.
21
Si bien el Massachusetts Institute of Technology (MIT) tiene una larga tradicin ligada a la produccin de sistemas y
lenguajes para la enseanza de la informtica en distintos niveles, no es hasta la aparicin de Processing que los artistas visuales o realizadores pudieron comenzar a desarrollar de manera prolija y sistemtica sus trabajos utilizando
cdigo de computadora. Processing es en principio un lenguaje de programacin diseado para poder bocetar de
manera rpida ideas visuales en un contexto informtico. Es libre de ser distribuido y adems es de cdigo abierto, es
decir, que cualquiera que est interesado puede acceder a su cdigo fuente para ver cmo est internamente programado. Esto permite adems optar por modificarlo o extenderlo segn una necesidad particular.
Processing (abreviado P5) es en gran medida el origen de una serie de desarrollos que se fueron desencadenando
bajo este concepto para acercar a artistas en general, herramientas que hasta ese momento estaban solo disponibles
para aquellos que tuviesen los conocimientos necesarios para poder adentrarse en la informtica y en la microelectrnica. La plataforma de hardware libre Arduino es otro ejemplo de ello.
Imagen 1.6. Sitio web de Processing
22
Un resumen de toda la funcionalidad de P5, explicada de forma sinttica y clara por sus creadores puede encontrarse en
<http://processing.org/learning/overview/>
El xito de P5 fue tal que el nmero de usuarios globales del sistema creci exponencialmente ao tras ao y an hoy
se mantiene la tendencia. En gran parte esto se debe al gran nmero de libreras que fueron apareciendo para sortear
diferentes problemas especficos de los usuarios de Processing.
Una librera es un paquete de software que se puede utilizar para resolver alguna cuestin especfica como comunicarse con una cmara web sin necesidad de saber especficamente nada sobre la cmara. Otras libreras estn destinadas a solucionar, por ejemplo, problemas de orden grfico, es decir, cmo se puede realizar una operacin de
procesamiento visual de manera rpida y prolija. Hay en este momento varios cientos de libreras avaladas por los desarrolladores de P5 que aceleran el proceso de creacin de software visual para entornos interactivos. Veremos varias
de ellas a lo largo de este material y analizaremos un caso particular creado exclusivamente para resolver el problema
de la captura de movimiento en una escena.
Algunas de las libreras ms utilizadas son minim para captura y anlisis de audio, BlobDetection para anlisis de contenido en la imagen y
Firmata para interactuar con un dispositivo Arduino.
<http://processing.org/reference/libraries/>
Texto Aparte
Varios proyectos tomaron la intencin original de Processing y dieron forma a nuevas maneras de acceder a la informtica de modo ms o menos sencillo. Arduino
es una plataforma de hardware libre por la cual se puede programar un microcontrolador de manera sencilla. Un microcontrolador es un dispositivo electrnico (un
chip) que tiene incluidas todas las partes de una computadora completa, es decir
un CPU, una memoria RAM para ejecutar los programas, una memoria ROM para almacenar el programa, una memoria Eprom que permite mantener los datos guardados luego de la interrupcin de la energa de alimentacin y entradas y salidas
digitales y analgicas. <www.arduino.cc>
23
Como referencia a otros lenguajes de programacin y entornos para la computacin grfica interactiva mencionaremos solo dos:
openFrameworks: aparece como una alternativa a Processing para aquellos realizadores que adems poseen un conocimiento ms avanzado en programacin o que ya hicieron sus primeros pasos en Processing y ahora sus aplicaciones requieren de mayor rendimiento o del uso de piezas de software no disponibles en Java (que es el lenguaje
original sobre el cual est escrito Processing).
openFrameworks es tambin de cdigo abierto y con una comunidad creciente muy efervescente que produce en
conjunto una cantidad de software increblemente alta, verstil y eclctica. Esto se realiza por medio de addons que
en definitiva seran el anlogo a las libreras de Processing.
La diferencia fundamental entre openFrameworks y P5 es que openFrameworks est escrito en lenguaje C++ y no
tiene un editor de cdigo asociado lo que hace el proceso de fabricacin de aplicaciones un poco menos directo que
en Processing.
Una vez superada esta primera instancia de puesta a
punto del entorno de trabajo, las aplicaciones generadas
suelen correr ms rpido que en Processing por ser C++
un lenguaje no interpretado. Esto significa que el cdigo de mquina generado es particular para el sistema
operativo en el cual se trabaja mientras que el cdigo de
mquina generado por Processing es interpretado por
una mquina virtual que es la que en definitiva interacta con el sistema operativo. Es por eso que el cdigo de
Processing es multiplataforma ya que ese mismo cdigo
es susceptible de ser ejecutado en cualquier ordenador
que tenga instalada una Java Virtual Machine.
24
El otro framework que se ha puesto de moda en estos ltimos tiempos es Cinder. Est tambin escrito en C++ y su
particularidad es que el core (ncleo), o sea, la rama central de cdigo, est prolijamente mantenida por su creador
Andrew Bell. Cinder aparece como un entorno de desarrollo de aplicaciones grficas pero orientado al segmento
profesional y se presenta como una librera de cdigo organizada de manera lgica e intuitiva al realizador grfico.
Andrew Bell
<http://drawnline.net/>
Cinder
<http://libcinder.org/>
25
Las tcnicas pueden ser aplicadas mediante la implementacin de sus algoritmos en algn lenguaje de programacin
como los anteriormente descritos, pero tambin existen herramientas de software que ya tienen resuelto el algoritmo y que solo deben ser puestos en funcionamiento para que brinden la informacin que deseamos obtener de la
escena.
Algunos ejemplos:
TSPS permite capturar la entrada de personas en la escena:
<http://opentsps.com/>
reactiVision es utilizado para resolver pantallas tctiles. Constituye una
parte importante del proyecto reacTable:
<http://reactivision.sourceforge.net/>
CCV est pensado para resolver sistemas de pantallas multitouch a gran
escala: <http://ccv.nuigroup.com/>
Los sistemas pticos de sensado de posicin y silueta han adquirido una gran relevancia en los sistemas interactivos,
dado que es un tipo de sensado ms sencillo y eficaz. Es, adems, menos costoso que el sensado por medios fsicos
de los mismos fenmenos.
En el arte interactivo vinculado a la multimedia escnica (instalaciones interactivas, performance, etc.), este tipo de
sensado es de gran utilidad ya que nos permite captar el movimiento del cuerpo mediante la utilizacin de cmaras
de bajo costo como lo son las cmaras web.
26
Este tipo de sistemas tambin ha habilitado la construccin de pantallas sensibles al tacto, multitacto (es decir, que
pueden captar varios dedos a la vez). Por un lado, en formato de pantallas de acrlico, retroproyectada, como las creadas por Jefferson Han que aprovechan un fenmeno ptico llamado Reflexin total interna frustrada. Este fenmeno
permite que se ilumine un acrlico en los cantos cuando se apoya un dedo sobre la superficie del acrlico, la yema del
dedo se iluminar, luego una cmara captar dicha luz e interpretar la posicin del dedo.
Imagen 1.10. Imagen del efecto de la Reflexin total interna frustrada
27
Imagen 1.11. Imagen de las pantallas sensibles al tacto multitacto hecha por Jefferson Han
Pantallas sensibles al tacto, multitouch en tela de lycra retroproyectada: estas pantallas permiten trabajar con mayores tamaos.
En este caso, se utiliza retroproyeccin para generar la imagen y
el sistema ptico capta la sombra que generan los dedos al hundir la tela.
28
29
Imagen 1.14. Anlisis de imagen realizado por el sistema de pantalla sensible al tacto con tela de Lycra
30
31
<http://es.wikipedia.org/wiki/MIDI>
32
En nuestro trabajo encontraremos que muchas veces se utilizan interfaces o dispositivos que responden a esta norma
como software que puede ser controlado a partir de este protocolo tanto desde un dispositivo interno como por otro
software. En este caso la capa fsica de conexin permanece virtualizada internamente en el sistema operativo.
Si bien la potencia y flexibilidad del protocolo MIDI es indiscutible, con el tiempo surgi la necesidad de mejorar ese
estndar de comunicacin pensando ya en la conexin de diferentes instrumentos musicales (fundamentalmente
software que corra en un ordenador) ampliando en principio la posibilidad de mensajes que se pueden enviar, su
largo de palabra (se refiere a cun grande es el rango de posibilidades que puede transmitir), la velocidad de transferencia y la implementacin de mensajes especficos creados por el usuario final. Como respuesta a esta demanda es
que surge el protocolo OSC.
OSC (opensoundcontrol) es un protocolo cuyo estndar fsico est basado en otro protocolo familiar a las computadoras que es TCP usado en las conexiones de red. OSC funciona sobre TCP utilizando paquetes en otro protocolo
denominado UDP. Este ltimo permite despachar mensajes desde un servidor y todos los clientes que escuchen a ese
servidor en un puerto determinado pueden recibir el mensaje.
Web de OSC
<http://opensoundcontrol.org/introduction-osc>
Los mensajes se establecen segn tipos de datos especficos: nmeros enteros, decimales, cadenas de caracteres o
arreglos que incluyen listas de algunos de ellos. El protocolo tambin prev que los mensajes lleven una especie de
encabezado que identifique el tipo de mensaje, de manera que quien lo reciba, conociendo de antemano la especificacin para ese tipo de mensaje, pueda entenderlo y utilizarlo en consecuencia.
Sobre OSC se desarrollaron protocolos especficos de la actividad audiovisual y de las interacciones en tiempo real entre dispositivos. Tal es
el caso del protocolo TUIO utilizado para implementar de manera estndar aplicaciones de interaccin multitouch. <http://www.tuio.org/>
33
328 bytes, una memoria de programa ROM (es decir, que no se borra al desconectarlo de la corriente) de 32KB, una
memoria eprom (que se puede autograbar y se mantiene luego del corte de energa) y diversos dispositivos como
una interfaz de comunicacin serial, generador de seales con modulacin del ancho de pulso (PWM) y lo ms importante, puertos de entrada y salida digitales y analgicos.
Estos puertos nos permiten conectar Arduino con casi cualquier otro dispositivo electrnico (generalmente por medio de algn otro circuito de interfaz) de manera de poder controlarlo remotamente tanto por medio de un software
precargado o utilizando el propio Arduino como interfaz entre un ordenador y el aparato que se requiera controlar.
Los puertos son adems bidireccionales de modo que podremos usarlos tanto como salida (si es que queremos controlar algo externo) o como entradas en el caso de que necesitemos utilizar sensores. Arduino (la comunidad y el proyecto en s) prev este tipo de usos por lo cual la extensa documentacin en su web hace en gran parte su existencia.
34
2.1. Introduccin
En esta unidad presentaremos los bloques fundamentales con los cuales producir una pequea aplicacin interactiva
que pueda generar imagen a partir del sonido. El hecho de poder vincular de manera creativa la imagen y el sonido
para producir un acontecimiento audiovisual interactivo original es central para nuestra disciplina. Consideramos, por
ese motivo, que intentar construir una aplicacin de este estilo es un buen punto de partida para comenzar a descubrir los detalles de las tecnologas involucradas en nuestro curso de manera progresiva.
Utilizaremos los programas Pure Data (PD) para la captura y anlisis de la seal sonora y Processing (P5) para crear un
motor visual que genere imagen a partir de ciertos parmetros. En la siguiente unidad explicaremos los pormenores
acerca de cmo vincular las dos aplicaciones para que funcionen de manera unitaria utilizando el protocolo OSC o MIDI.
Un ejemplo muy claro en este sentido es la obra Messa Di Vocce del colectivo artstico Flong
Fuente: <http://www.youtube.com/watch?v=STRMcmj-gHc>
35
En esos momentos, el tiempo de respuesta de las computadoras era sustancialmente ms rpido que el de la mente humana. La computadora poda resolver problemas
especficos de manera precisa y en tiempos mucho ms
cortos que los que tomara a un calculador humano. De
cualquier forma, es interesante tener en cuenta que cada
calculacin susceptible de ser llevada a cabo en la computadora poda tomar decenas de horas en resolverse.
A partir de la entrada de las computadoras en las casas
de los amateurs y aficionados a la computacin es que
tambin se dispara el desarrollo y el entusiasmo por
conseguir aplicaciones que resolvieran los problemas
e inquietudes de los nuevos propietarios de hardware:
el usuario general.
Esos softwares, producidos ya fuera de las universidades,
apuntaban a resolver tareas simples como llevar adelante la contabilidad hogarea, calcular fcilmente presupuestos para pequeos negocios, manipular texto, emular juegos de ingenio y organizar agendas de contactos.
Muy rpidamente las aguas se dividieron en dos grandes grupos: por un lado estaban quienes se juntaban a compartir sus programas de manera amistosa en clubes informticos y casas de computacin. Eran comunes las reuniones de
fin de semana donde se intercambiaban de manera impresa el cdigo escrito para tal o cual mquina y que cumpla
de forma ms o menos certera con alguna funcin particular.
Por otro lado, tambin estaban quienes sostenan que el trabajo efectuado en resolver e implementar tal o cual algoritmo deba ser tratado como un bien material sujeto a las leyes del mercado, es decir, susceptible de ser comercializado. Nace as el software privativo y la idea de software licenciado.
Por supuesto, ambas vertientes tienen sus particularidades.
36
Es nuestra intencin promover el uso de software libre en todo lo que sea posible puesto que nos parece relevante en
trminos educativos poder contar con la posibilidad de explorar cmo se programaron ciertas herramientas que utilizaremos a lo largo de este material. Tambin nos parece importante contar con la posibilidad de exponer y distribuir
nuestro trabajo de manera libre y cooperativa; sin mayores restricciones.
Es en ese sentido que nuestro recorrido estar centrado en dos aplicaciones, en un amplio sentido, fundacionales de
nuestra disciplina. Nos referimos a los softwares PD (Puredata) y Processing.
37
Fuente: www.puredata.info
Si bien PD permite generar, controlar y producir imagen en movimiento, ser nuestra herramienta preferida para todo
lo que tenga que ver con control y procesamiento de sonido ya que es all donde encontramos sus mayores virtudes.
38
Fuente: www.puredata.info
Una vez instalado, al iniciar, el programa PD nos ofrece la ventana de terminal. Esta ventana es nuestra puerta de comunicacin con el programa. Todos los lenguajes de programacin ofrecen algn medio de entrada y salida de datos.
En este caso, la consola de PD nos muestra informacin relacionada con el estado actual de la aplicacin y de nuestro
programa (de ahora en adelante patch).
39
2.3.2. Processing
Processing es a la vez un lenguaje de programacin (un API), un entorno y una comunidad de desarrollo de software.
El proyecto fue originado por dos estudiantes del MIT como proyecto de tesis. La propuesta era construir un sistema
informtico para que los alumnos o estudiantes de artes visuales, pudiesen, a la vez que aprenden a programar, construir imgenes de manera programtica.
La fascinacin de Casey Reas, uno de los mentores del proyecto, tena que ver con la posibilidad de aplicar procesos
algortmicos para la generacin de dibujos. Su intencin era la de generar dibujos automticamente.
Si bien esta idea est presente desde hace muchsimo tiempo, no fue hasta el lanzamiento de Processing que el recurso informtico se empez a usar de manera casi ubicua en el arte visual digital.
Processing no es el primer ejemplo de lenguaje para producir imgenes. DBN (Design by Numbers) es una aplicacin/lenguaje creado por
un docente del MIT, John Maedea, quien fue profesor de Reas y Fry. En
cierto sentido Processing puede ser considerado como la evolucin de
DBN, tal cual qued registrado en la ltima actualizacin del sitio en
2003. <http://dbn.media.mit.edu/>
En gran parte, el xito de Processing se debe al trabajo de Ben Fry (el otro integrante de la dupla) de perfil ms tcnico. Fue Fry quien logr desarrollar un sistema basado en java que permitiese escribir cdigo y ejecutarlo de manera
sencilla y limpia en cualquier computadora y por cualquier usuario sin conocimientos previos de programacin.
40
Actividad 1
A esta altura suponemos que el lector ya ha tenido alguna experiencia previa con
Processing. De verificarse lo contrario les proponemos la siguiente actividad que
consiste en instalar y ejecutar un primer programa a modo de hola mundo que
nos permite determinar si el programa ha sido correctamente instalado y si estamos
en condiciones de poder comenzar a trabajar. El programa hola mundo es un programa simple cuya nica funcin es imprimir en la consola o terminal la frase hola
mundo. Referirse a esta versin en espaol del tutorial oficial de Processing:
Tutorial en espaol: <http://www.arduteka.com/2012/12/introduccion-a-processing/>
Versin original (en Ingls): <http://processing.org/tutorials/gettingstarted/>
De aqu en ms centralizaremos todo nuestro trabajo en estas dos aplicaciones fundamentalmente porque se trata
de aplicaciones libres y han demostrado ser fiables para este tipo de actividades, tanto por el tiempo de maduracin
y desarrollo con el que cuentan ambas como adems por la inmensa comunidad de artistas y amateurs que producen
continuamente aplicaciones especficas en estos lenguajes. Como anticipamos, utilizaremos PD para todo lo relacionado con control de interfaces y sonido y Processing para el desarrollo de imagen interactiva.
Y all, desde el men desplegable input device seleccionaremos la entrada correspondiente (en este caso el micrfono
incorporado a una computadora porttil).
41
Imagen 2.5.
Una vez completado, aceptamos los cambios haciendo clic en apply y luego save all settings para guardar la configuracin.
El estado de funcionamiento del micrfono se puede verificar usando un patch de testeo incluido en el programa.
Este probador se encuentra ubicado en el men Media/test audio and midi.
Imagen 2.6.
El indicador audio input debera acusar la entrada de audio en el puerto especificado. Tal vez la caracterstica ms potente que tiene PD (como otros lenguajes de programacin visuales) es que la documentacin suele ser un ejemplo
funcional de lo que intenta documentar. Puede accederse por medio del men Help/Browser. Esto nos muestra un
navegador con todos los ejemplos disponibles para nuestra versin ordenados por temticas.
Imagen 2.7.
42
Explicaremos ahora cmo analizar de forma sencilla la seal proveniente de nuestro micrfono para utilizarla luego
como controlador de nuestra aplicacin visual.
Si recordamos los conceptos fundamentales que hacen al sonido es fcil darse cuenta que los parmetros ms inmediatos que se pueden extraer de una seal sonora, para controlar cualquier cosa, son la amplitud o intensidad y la
frecuencia o tono.
La amplitud representa la fuerza del sonido o sea la sutileza o intensidad con que el sonido llega al micrfono. Como
parmetro de control la amplitud podra emplearse de manera anloga a la saturacin de la tinta en una imagen. Por
otra parte la frecuencia podra utilizarse para controlar el tono (tinte).
El objeto Fiddle~ nos permite extraer informacin de amplitud y
frecuencia predominante en una seal de audio. Es la pieza fundamental de un anlisis de audio sencillo y rpido. Puede consultarse
un ejemplo de cmo usar este objeto en el siguiente recurso:
<http://www.lucarda.com.ar/pd-tutorial/ch03s08.html#id432668>
Veremos ahora la cuestin grfica. Es interesante poder pensar la imagen digital no como copia o representacin sino ms bien como imagen original, la cual
presenta sus propias problemticas as como diversas
materialidades intrnsecas a su propio fundamento tecnolgico. Es evidente, en este sentido, la idea de pantalla y de cmo pueden generarse imgenes electrnicas sobre tal sustrato.
Es importante el hecho de que existan diversas maneras de generar imgenes en una pantalla de computadora, y en los dispositivos mviles o proyecciones de
todos los tamaos que se puedan imaginar.
<http://es.wikipedia.org/wiki/
Transformada_r%C3%A1pida_
de_Fourier>
La primera raz fundacional que determina cmo fue que surgieron los primeros grficos computarizados tiene que
ver con el uso de grficos vectoriales. La idea de los grficos vectoriales se remonta a las primeras computadoras con
interfaz visual. Ya en el ao 1961 se comenz a producir imagen con esta tcnica que consiste en definir una lista de
coordenadas para centros, inicios, y fines de arcos y lneas.
43
Las computadoras de la dcada de 1960 usaban monitores de tipo vectoriales donde un haz de electrones se mueve
dibujando un punto. Ese haz de electrones puede ser direccionado en dos sentidos, vertical y horizontal. El veloz
movimiento de ese punto da lugar a la formacin de lneas continuas que aparecen sobre la superficie de la pantalla
comnmente recubierta de material fosforescente. Este sistema de generacin grfica es bastante eficiente y econmico (en trminos de hardware) ya que la imagen se genera de manera instantnea (no se necesita una memoria para
alojar el resultado de la imagen).
En nuestros das la idea sigue vigente. Programas como Adobe Illustrator y Corel Draw utilizan esta tcnica para generar imgenes y dibujos. Si bien la manera en que Processing termina generando una imagen es por mapa de bits,
el lenguaje nos permite varias formas de utilizacin de grficos vectoriales.
Una de ellas tiene que ver con el uso del mtodo beginShape(), endShape().
Vertex (Vrtice):
Un vrtice es una posicin definida por una coordenada (x,y). Una lnea tiene dos
vrtices, un tringulo tiene tres, un cuadriltero tiene cuatro, y as sucesivamente.
Formas orgnicas: tales como manchas o el contorno de una hoja se construyen
mediante la colocacin de muchos vrtices en los patrones espaciales.
Estas formas son simples en comparacin con las posibilidades. En los videojuegos
contemporneos, por ejemplo, personajes de gran realismo y elementos ambientales pueden estar formados por ms de 15.000 vrtices. Estos representan usos
ms avanzados de esta tcnica, pero son creados usando principios similares.
Para crear una forma de puntos de vrtice, utilice primero la funcin beginShape(), a continuacin, especifique una serie de puntos con la funcin vertex() y para
completar la forma use endShape(). beginShape() y endShape() siempre deben ser
utilizados por parejas. La funcin vertex() tiene dos parmetros que definen la coordenada x y la coordenada y: vertex(x , y);
Por defecto, todas las formas dibujadas con la funcin vertex() se llenan de blanco
y tienen un contorno negro que conecta todos los puntos, excepto el primero y el
ltimo. fill(), stroke(), noFill(), noStroke(), y strokeWeight() son funciones de control
de los atributos de las formas dibujadas con la funcin vertex(). Para cerrar la forma,
utilice la constante CLOSE como parmetro para endShape(). (Reas & Fry, 2007: 67
[traduccin de los autores])
Processing tambin dispone de una clase exclusiva para este tipo de tratamiento de grficos. La estructura que nos
permite generar formas y conservarlas para uso posterior es la clase PShape. Para eso veremos el ejemplo PolygonPShape includo en Processing v 2.0.1:
44
Cdigo 2.1.
/**
* PrimitivePShape.
*
* Using a PShape to display a custom polygon.
*/
// El objeto PShape sobre el que operaremos
PShape estrella;
void setup() {
size(640, 360, P2D);
smooth();
// Primero creamos nuestro objeto PShape
// en este caso no usamos el constructor con new puesto que es processing
// el que se encarga de crear ese objeto por nosotros.
estrella = createShape();
estrella.beginShape();
// configuramos el color de relleno y la linea.
estrella.fill(102);
estrella.stroke(255);
estrella.strokeWeight(2);
// Escribimos a mano algunos puntos...
estrella.vertex(0, -50);
estrella.vertex(14, -20);
estrella.vertex(47, -15);
estrella.vertex(23, 7);
estrella.vertex(29, 40);
estrella.vertex(0, 25);
estrella.vertex(-29, 40);
estrella.vertex(-23, 7);
estrella.vertex(-47, -15);
estrella.vertex(-14, -20);
// CLOSE le dice a processing que la forma que creamos queremos que sea cerrada, esto es:
// el primer punto y el ultimo se conectan
estrella.endShape(CLOSE);
}
void draw() {
background(51);
// podemos mover la estrella como querramos usando translate()
translate(mouseX, mouseY);
// dibujamos la estrella
// esta forma de hacerlo es similar a cuando queremos dibujar una imagen.
// la forma correcta de hacerlo es image(mi_imagen, x, y);
// el metodo shape(PShape p); es anlogo a image(PImage, int x, int y);
shape(estrella);
}
Otra forma de utilizar grficos vectoriales es por medio del formato grfico svg: es un estndar abierto de grficos
vectoriales, est desarrollado y mantenido por el World Wide Web Consortium (W3C).
Formato SVG:
<http://es.wikipedia.org/wiki/Scalable_Vector_Graphics>
<http://es.wikipedia.org/wiki/World_Wide_Web_Consortium>
45
Processing nos permite importar nuestros diseos en formato svg y visualizarlos en pantalla adems de manipularlos.
Para ello tambin utilizaremos la clase PShape.
Documentacin de la clase PShape:
<http://processing.org/reference/javadoc/core/>
En este caso Processing se encarga de abrir el archivo archivo_de_forma.svg que se encuentra en la carpeta /data de
nuestro sketch y que tiene que haber sido compuesto utilizando Inkscape o Adobe Illustrator puesto que no es una
implementacin completa del formato svg.
Como contrapartida a los monitores vectoriales, aparecieron los monitores TRC con barrido horizontal. Si bien el principio de funcionamiento es similar al de los monitores vectoriales donde tambin se usa un haz de electrones sobre
una superficie fosforescente, la generacin de imagen tiene otro fundamento: el haz de electrones barre la pantalla
de arriba hacia abajo dibujando lneas horizontales.
La modulacin de la intensidad del haz es lo que produce la variacin en el brillo resultante. Debido a estas caractersticas de funcionamiento aparece un nuevo concepto: la resolucin vertical de la imagen (en trminos de lneas).
La utilizacin de esta clase de monitores dio lugar, hacia finales de la dcada de 1960, al concepto de raster grfico.
El raster grfico es una grilla de puntos donde el encendido o apagado de cada uno de estos puntos construye la
imagen deseada. Surge entonces la idea del pxel como unidad mnima de imagen digital. Es evidente que con solo
determinar dos estados para cada uno de los pxeles en el raster no sera suficiente para producir, por ejemplo, imgenes a color.
Las computadoras digitales permiten procesar y almacenar gran cantidad de informacin lo que ha ido determinando tanto la resolucin en trminos espaciales como la profundidad de color para las imgenes que un cierto hardware
puede producir. En la actualidad, es prcticamente ubicua la idea del raster grfico de 32 bits donde cada componente de color (rojo, verde y azul) est determinada por un valor entre 0 y 255 (8 bits) y los restantes 8 bits se utilizan para
guardar informacin de transparencia (canal alfa).
Processing funciona utilizando este formato. Aplicando los mtodos set() y get() podemos modificar y obtener respectivamente el color de cualquier pxel en nuestro sketch.
46
Cdigo 2.2.
/*
Este ejemplo muestra el uso del metodo set(int x, int y, color col); para colocar un color en un
pixel determinado de nuestra ventana de dibujo.
- click con el mouse para activar
*/
Pintor pintores[]; // array de pintores (ie: muchos objetos de tipo Pintor en una lista ordenada)
int cantPintores = 1000;
boolean bandera = false;
void setup(){
frameRate(30);
size(1200, 400);
pintores = new Pintor[cantPintores];
reset();
background(255);
}
void draw(){
for(int i=0; i < cantPintores; i++)
{
if(bandera == true) {
pintores[i].avanzar();
pintores[i].pintar();
}
}
}
void largar(){
bandera = true;
}
void mousePressed(){
largar();
}
void keyPressed(){
if(key == )
{
bandera = false;
reset();
}
}
// en el metodo reset() uso un for para crear los pintores
void reset()
{
//
//
//
//
47
Pintor(){
println(hola ! soy un autito nuevo 0KM);
Pintor(color colorIncial){
col = colorIncial;
}
Pintor(color _col, int _posx, int _posy, int _velocidad){
col = _col;
posx = _posx;
posy = _posy;
velocidad = _velocidad;
}
void avanzar(){
posx += velocidad;
}
void pintar(){
set(posx, posy, col);
}
}
El protocolo de comunicacin OSC est especficamente diseado para compartir informacin entre todo tipo de herramientas vinculadas a la actividad audiovisual. En cierto sentido es el protocolo superador del ya clsico e inmortal MIDI.
OSC permite conectar controladores, instrumentos musicales y softwares de forma prcticamente irrestricta e ilimitada ya que por un lado la conexin fsica entre los dispositivos est basada en Ethernet y UDP y la parte lgica del
protocolo es abierta permitindonos generar nuestros propios lenguajes de comunicacin para conectar nuestros
propios softwares o hardwares.
El modelo de capas OSI es el que determina el funcionamiento de Internet. Es interesante como est desarrollado ya que sobre esas ideas
pueden implementarse muchos otros protocolos de comunicacin.
Modelo de capas OSI: <http://es.wikipedia.org/wiki/Modelo_OSI>
El protocolo OSC ya se encuentra implementado en nuestras aplicaciones (PD y Processing). Ambos lenguajes traen
incorporados objetos para enviar y recibir mensajes OSC desde y hasta una conexin de red que puede ser otro puerto dentro de la misma mquina, una direccin en la red local o incluso una computadora conectada a Internet.
48
En nuestro ejemplo, tanto el patch programado en PD como el sketch de Processing estarn corriendo en la misma
mquina. El patch de PD ser el encargado de emitir mensajes en funcin de las variaciones de amplitud y tono de
audio que recibe del micrfono. Para ello ampliaremos con el objeto sendOSC el ejemplo que vimos anteriormente.
49
Una de las caractersticas ms importantes (y tiles) de los lenguajes de programacin que utilizan este tipo de metforas visuales tiene que ver con que el patch se autoexplica por el solo hecho de la apariencia grfica que estas
determinan. Es fcil seguir las conexiones en el sentido de lectura convencional: de arriba hacia abajo y de izquierda
a derecha.
Esta lectura es anloga al flujo de los datos en el programa. Es evidente que en la parte superior izquierda comienza
todo: el audio a analizar ingresa al patch por medio del objeto adc~.
Este objeto, adc~, nos permite vincular una entrada de audio fsica (configurada anteriormente de manera global para
todos los patchs de PD) desde el men de configuracin.
Es importante ubicar un multiplicador para poder operar sobre el nivel de entrada. Este parmetro es clave para poder
calibrar nuestro programa en la situacin de instalacin real.
Mucho del trabajo con interfaces que permiten el sensado de alguna de las variables del mundo exterior est centrado en la calibracin que se haga en la lectura de esos datos en la situacin particular: no ser igual el funcionamiento
de nuestra instalacin que captura audio de un micrfono en una situacin de ambiente de galera de arte donde
el ruido y el flujo de gente es limitado a la de un espacio ms amplio como una discoteca o espacio de alto flujo de
pblico como una feria o un concierto.
Imagen 2.9. Entrada de audio y su control de volumen
50
51
Con la informacin obtenida vamos a crear un mensaje osc utilizando nuestras propias etiquetas, en este caso /pitch
para el tono y /amp para la intensidad. El uso de los objetos trigger (t) nos asegura que se enviar un mensaje siempre que se modifique el valor de tono o intensidad de manera indistinta y que el orden en que se arme el mensaje tendr lugar siempre con el envo de ] al final. El objeto sendOSC necesita ese dato como disparador para efectivamente
enviar el mensaje a la red. El caracter ] viene a cerrar el mensaje dndole la forma adecuada que el objeto sendOSC (y
el protocolo osc) necesita.
Imagen 2.13. Compilacin del mensaje completo.
La palabra clave localhost refiere siempre a la direccin actual de nuestra computadora. localhost es un alias de la direccin ip 127.0.0.1. Esta
direccin est siempre reservada para referir a la misma mquina.
<http://es.wikipedia.org/wiki/Localhost>
52
Texto Aparte
Generacin de sonido
Cuando nuestro proyecto requiera integrar sonido, las opciones con las que contamos son variadas y dependen fundamentalmente del tipo de sonorizacin que
queremos lograr. En principio, los caminos posibles para lograr que nuestra instalacin suene son tres: producir sonidos por medio de sntesis digital, disparar
sonidos previamente producidos (playback) y la combinacin de ambos.
La consideracin de base es que los sonidos que aparecen guardan algn tipo de
relacin con la resultante visual, esto es: sonidos que de alguna manera se sincronizan o responden a algn parmetro de la imagen. En ese sentido, el uso de sntesis
nos permitir explorar variaciones ms ligadas a lo generativo, es decir, sonido que
se produce a partir de parmetros que controlan tanto la resultante visual como la
sonora.
Por el contrario, el uso de samples (muestras) de sonido pregrabado, nos permite
conectar fcilmente un resultado sonoro a un comportamiento visual, por ejemplo, una accin de un personaje en la pantalla. Si bien Processing cuenta con una
librera de sonido completa con la cual resolver muchas de estas cuestiones, a los
fines didcticos de este tema utilizaremos PD por encontrarlo ms intuitivo y cmodo a la hora de trabajar con sonidos.
En la unidad siguiente explicaremos cmo conectar ambos programas para poder
intercambiar eventos entre uno y otro y lograr as la sincrona antes mencionada.
Cuando hablamos de sntesis sonora nos referimos al fenmeno de producir sonidos por medios no acsticos, esto es, utilizando osciladores
electrnicos o medios digitales. En nuestro caso solo nos referiremos
a los ltimos aunque los conceptos de generacin sonora electrnica
por medios analgicos se encuentran presentes pero de manera emulada. Es decir, osciladores y mdulos digitales que emulan las funciones de los mismos dispositivos electrnicos analgicos. Sntesis sonora:
<http://es.wikipedia.org/wiki/S%C3%ADntesis_(sonido)>
En el siguiente enlace puede verse un tutorial completo sobre cmo
emular un sintetizador Moog Minimoog en PD.
<http://en.flossmanuals.net/pure-data/audio-tutorials/simple-synth/>
53
A partir de la versin 2.1 de Processing podemos instalar libreras por medio del menu Tools /add Library.
Para mayor referencia ver el documento How To Install External Libraries de la wiki de Processing (en ingls): <http://wiki.processing.org/w/How_to_Install_a_Contributed_Library>
Cdigo 2.3.
/**
* Ejemplo sobre como recibir mensajes osc en processing.
* ejemplo original tomado de la libreria oscP5:
* http://www.sojamo.de/oscP5
*/
import oscP5.*;
import ndtP5.*;
// el objeto oscP5 nos permite recibir mensajes osc a travs de
la
// red.
OscP5 oscP5;
void setup() {
size(400,400);
frameRate(25);
/* inicializamos oscP5, escuchando mensajes en el puerto 12000
*/
oscP5 = new OscP5(this,12000);
}
void draw() {
background(0);
}
/* los mensajes recibidos son redireccionados internamente por
la clase OscP5 al mtodo oscEvent(OscMessage msg) */
void oscEvent(OscMessage theOscMessage) {
/* imprimimos la etiqueta con la que fue enviado el mensaje y
el tipo de dato que contiene */
print(### mensaje recibido.);
print( etiqueta: +theOscMessage.addrPattern());
println( tipo de dato: +theOscMessage.typetag());
}
Nuestro ejemplo ser solamente ilustrativo, por eso la lgica ser de lo ms sencilla: dibujar un cuadrado que cambie
de color segn la frecuencia presente y que modifique su tamao en funcin de la intensidad. En ese sentido, resultar muy til cambiar el modo de color por defecto de Processing para que funcione con parmetros de tipo HSB (hue,
saturation, brightness o tono, saturacin, brillo).
Para ello utilizaremos la instruccin:
54
De esta forma, todos los parmetros y definiciones de color se harn con base en ese sistema que resulta ms natural
a nuestros propsitos ya que el hue puede asociarse directamente al tono y con el valor de intensidad manipularemos
el tamao del objeto. Cabe recordar que el rango de estos valores est dado en 8 bits por lo cual puede tomar valores
entre 0 y 255. Es evidente que los valores producidos por PD no sern tiles tal cual los recibimos: debemos ajustarlos
a este rango para obtener una variacin significativa.
En nuestro caso particular, los valores de pitch estn oscilando entre 80 y 92 aproximadamente para la voz humana
cantando y entre 20 y 60 para la amplitud.
Para acondicionar esos valores utilizaremos el mtodo map (int in, int minin, int maxin, int minout, int maxout).
Definiremos dos variables:
int tono = 0;
int intensidad = 0;
Esas variables sern actualizadas en el mtodo oscEvent(...) y utilizadas en draw() para dibujar:
Cdigo 2.4.
/**
* Ejemplo sobre como recibir mensajes osc en processing.
* ejemplo original tomado de la libreria oscP5:
* http://www.sojamo.de/oscP5
*/
import oscP5.*;
import netP5.*;
// el objeto oscP5 nos permite recibir mensajes osc a travs de la
// red.
OscP5 oscP5;
void setup() {
size(400, 400);
frameRate(25);
/* inicializamos oscP5, escuchando mensajes en el puerto 12000 */
oscP5 = new OscP5(this, 12000);
colorMode(HSB);
rectMode(CENTER);
}
int tono = 0;
int intensidad = 0;
void draw() {
background(0);
// ajustamos el tono
fill(tono, 255,127);
// movemos al centro de la pantalla
translate(width/2, height/2);
// aplicamos una rotacin
rotate(frameCount * 0.01);
// dibujamos un cuadrado con los parametros recibidos
rect(0,0, intensidad, intensidad);
55
/* los mensajes recibidos son redireccionados internamente por la clase OscP5 al mtodo
oscEvent(OscMessage msg) */
void oscEvent(OscMessage theOscMessage) {
/* imprimimos la etiqueta con la que fue enviado el mensaje y el tipo de dato que contiene */
print(### mensaje recibido.);
print( etiqueta: +theOscMessage.addrPattern());
println( tipo de dato: +theOscMessage.typetag());
if (theOscMessage.addrPattern().equals(/pitch))
{
/*
theOscMessage trae la informacin. para recuperarla utilizamos el metodo
OscMessage.get(int id) donde id es la posicin del valor que queremos recuperar.
En nuestro caso es 0 ya que es el nico parametro presente en nuestro mensaje
de pitch.
Adems debemos asegurarnos de que nuestro mensaje es del tipo que esperamos:
*/
if (theOscMessage.typetag().equals(f))
{
/*
Una vez que estamos seguros de que el mensaje es del tipo que esperamos
utilizamos el mtodo get(int id) que nos devuelve un objeto de tipo OscArgument
OscArgument nos permite efectivamente recuperar el valor con el tipo
en el que fue enviado. En este caso usaremos OscArgument.floatValue();
*/
float valorDePitch = theOscMessage.get(0).floatValue();
/*
y por ltimo ajustamos el valor de pitch a un numero entre 0 y 255 y
lo convertimos a entero usando int();
*/
tono = int(map(valorDePitch, 80, 92, 0, 255));
}
}
// y el mismo tratamiento para intensidad:
if (theOscMessage.addrPattern().equals(/pitch))
{
if (theOscMessage.typetag().equals(f))
{
float valorDeAmplitud = theOscMessage.get(0).floatValue();
}
}
56
El resultado es el siguiente:
Imagen 2.15.
Hemos visto entonces el proceso completo para generar la estructura mnima de una aplicacin interactiva que conjuga imagen y sonido en un todo. Esos conocimientos permiten adentrarse ahora en cuestiones ms complejas: buscar otras formas de producir imagen a travs del cdigo y vincular otros parmetros del sonido, por ejemplo detectando rangos de frecuencias para controlar diferentes elementos visuales.
Con las herramientas aprendidas es nuestra sugerencia intentar realizar configuraciones ms sofisticadas utilizando
otras funciones de dibujo o algoritmos avanzados para generar composiciones ms atractivas y de mayor dinamismo.
57
3.1. Introduccin
En esta unidad explicaremos los principios de los mtodos de captura de movimiento mediante el uso de sistemas
pticos, es decir, los que usan cmaras de video para tal fin. Estos mtodos permiten captar el movimiento de personas, en un escenario o el espacio de una instalacin artstica, y controlar la imagen y el sonido en funcin de los parmetros obtenidos. Tambin, se introducir el mtodo de captura por substraccin de video, a la vez que se explicar
su implementacin en el lenguaje de programacin Processing.
58
59
60
La captura de video se realiza mediante el objeto de tipo capture llamado cmara. Dicho objeto es inicializado en
el void setup() y durante el void draw() se revisa si tiene fotograma disponible para cada ciclo del draw, mediante la
ejecucin del mtodo .available() en un condicional (estructura if). Si la consulta devuelve un valor positivo (un valor
de verdad true), entonces se usa el mtodo .read() para cargar el nuevo fotograma. Al final, con la funcin image(), se
muestra la imagen del nuevo fotograma en pantalla.
61
Puesto que los valores de los pxeles casi nunca son exactamente iguales, sino que en el mejor de los
casos son muy cercanos, debido al ruido de captacin de la imagen y el de la iluminacin, es necesario
distinguir entre las pequeas diferencias (que corresponden al ruido) y las grandes diferencias, que pertenecen al sujeto buscado
Con este procedimiento se genera una nueva imagen bitonal, que est en la parte inferior de la imagen, que indica en
blanco el movimiento y en negro el resto de la escena.
Luego de estas operaciones el proceso concluye con el anlisis de los pxeles blancos para determinar el tamao y
posicin del sujeto en la escena.
El proceso de captura de movimiento por substraccin de video puede realizarse de dos formas en funcin de cul es la imagen de referencia con la que se compara la imagen actual. Al primer mtodo lo
llamaremos captura de movimiento por substraccin de video con imagen de referencia. Debajo puede
verse un diagrama en el que se representa el flujo de la informacin. La imagen fija, que figura en el
mismo, corresponde a una imagen de la escena sin ningn sujeto.
62
Imagen 3.3.
63
El otro mtodo es el que llamaremos captura de movimiento por substraccin de video con imagen
retardada (tambin podemos llamarla con delay). La diferencia con el mtodo anterior consiste en que
la imagen que se utiliza para comparar con la imagen actual proviene del mismo flujo de imgenes de la
cmara pero con un retardo en el tiempo. De esta manera el fotograma que est actualmente ingresando
de la cmara es comparado con uno anterior y deja una cantidad fija de fotogramas de retraso en medio.
Imagen 3.5. Captura de movimiento por substraccin de video con imagen retardada
64
Cdigo 3.2.
// se importa la libreria de video de Processing
import processing.video.*;
// objeto para ver la cmara
Capture camara;
//LINEA A: objeto para la captura de movimiento
PMoCap capturaDeMovimiento;
// variable que definen el ancho y alto de la imagen de la cmara
int ancho = 320;
int alto = 240;
// variable que indica si se monitorea la captura
boolean monitoreo = true;
void setup() {
// tamao de la pantalla
size( 800, 600 );
// imprime las cmaras disponibles en el sistema operativo
println( Capture.list() );
// inicializa el objeto de la cmara
camara = new Capture( this, ancho, alto );
//con Processing 2.0
//camara.start();
void draw() {
// si la cmara tiene un fotograma nuevo disponible
if ( camara.available() ) {
// leer un nuevo fotograma
camara.read();
//LINEA C: analiza el movimiento en funcin del nuevo fotograma
capturaDeMovimiento.capturar( camara );
//LINEA D: carga en un objeto PImage el resultado del anlisis del movimiento
PImage imagenDelMovimiento = capturaDeMovimiento.getImagenAnalisis();
//LINEA E: carga la cantidad de movimiento en la regin superior izquierda
float movimientoALaIzquierda = capturaDeMovimiento.movEnArea(
int( 0.05 * ancho ),
int( 0.05 * alto ),
int( 0.25 * ancho ),
int( 0.45 * alto ),
imagenDelMovimiento );
65
void keyPressed() {
// si se presiona la tecla espacio
if ( key == ) {
// invierte el estado de activacin del monitoreo
monitoreo = !monitoreo;
}
}
void mousePressed() {
// si se presion el botn principal del mouse
if ( mouseButton == LEFT ) {
//LINEA G: si se preciona el botn del mouse se recaptura el fondo
capturaDeMovimiento.recapturarFondo();
}
else {// si se presion el botn alternativo
//si esta en monitoreo
if ( monitoreo ) {
// si el mouse fue presionado en la regin de monitoreo del umbral
if ( mouseX > ancho*2 && mouseX < ancho*2 + 150 &&
mouseY >= 0 && mouseY <= 255 ) {
// calculo un nuevo valor
float nuevoValor = map( mouseY, 0, 255, 255, 0 );
//LINEA H: asigna el nuevo valor de umbral
capturaDeMovimiento.setUmbral( nuevoValor );
}
}
}
}
66
El segundo mtodo que nombramos fue .capturar() que se encuentra en la lnea C. Este mtodo es el ms importante
ya que es el que pone la captura en funcionamiento. Recibe un objeto de tipo PImage (una imagen de mapa de bits)
o un objeto de tipo Capture (es decir, uno para acceder al contenido de la cmara de video). Por eso, se lo ejecuta
inmediatamente despus de leer el fotograma de la cmara:
Cdigo 3.4.
// leer un nuevo fotograma
camara.read();
//LINEA C: analiza el movimiento en funcin del nuevo fotograma
capturaDeMovimiento.capturar( camara );
La idea es que el objeto capturaDeMovimiento reciba uno a uno los fotogramas de la cmara y los procese aplicando
el algoritmo de substraccin de video. Cuando funciona con el mtodo de imagen de referencia prefijada, toma como
imagen el primer fotograma que le llega.
Como, generalmente, estos primeros fotogramas no son buenos (a veces vienen en negro hasta que la cmara se
acomoda), es necesario volver a tomar un nuevo fotograma como imagen de referencia. Esto se hace con el mtodo
.recapturarFondo() que se encuentra en el mtodo mousePressed() para poder obtener una nueva imagen al presionar al botn del mouse. Cuando el objeto est funcionando con el otro mtodo, esto es innecesario y aplicar este
comportamiento no tiene mayores consecuencias.
67
68
Las dos lneas en las que se invoca al mtodo definen las regiones de captura que se busca analizar y que se muestran
en el grfico siguiente.
Imagen 3.7. Regiones de anlisis de la captura de movimiento
69
El mtodo .movEnArea() devuelve el proporcional de la regin que est involucrado en el movimiento, por ejemplo,
si la mitad de la regin especificada posee pxeles blancos (pxeles pertenecientes al sujeto de movimiento) entonces
el mtodo devuelve el valor 0,5 , es decir el 50/100. Obviamente, los valores posibles se encuentran en el rango entre
0 y 1 inclusive.
El objeto de imagen (Pimage llamado imagenDelMovimiento) que se pasa como ltimo parmetro sirve como monitoreo del resultado. En la imagen 3.8. pueden observarse tres figuras (o cuadros), sobre un fondo, de izquierda a
derecha: la imagen original de la cmara, la del anlisis del movimiento y el nivel de umbral (representado con un
rectngulo lleno parcialmente). En la segunda, del anlisis del movimiento, se muestran: el rea del movimiento en
color blanco, el rectngulo contenedor (bounding box) en verde, y otros dos rectngulos que representan las dos
regiones analizadas con las llamadas a .movEnArea(). La de la izquierda se encuentra de color verde (indicando que
contiene movimiento) con la seccin de movimiento tambin resaltada en verde, la de la derecha se encuentra en
rojo, indicando que no hay movimiento.
Imagen 3.8. Monitoreo de los diferentes parmetros de la captura de movimiento
70
71
}
else {
72
}
//pinta el pixel de la imagen bitonal
bitonal.pixels[i] = bitono;
//SECCIN F
if ( area>0 ) {
x = totx / area;
y = toty / area;
}
Iniciaremos con la que est etiquetada como SECCIN A. Que inicia con un condicional (ciclo if) que segn el valor de
una variable boolena llamada comparaConFondo bifurca el flujo en dos direcciones. Cada uno de estos caminos se
corresponde con los dos mtodos de captura por substraccin: 1) el que compara con una imagen de referencia prefijada (compara con fondo) y 2) el que compara contra la misma imagen retardada. Cuando la variable comparaConFondo tiene valor verdadero (true) implementa el primer mtodo (compara con fondo) y con valor falso (false), el otro.
En el cdigo citado, dado que la pregunta est negada, la primera parte del if se dedica al mtodo que comparar
contra una imagen retardada:
Cdigo 3.7.
if ( !comparaConFondo ) {
// siendo el mtodo comparar con un fotograma anterior
// carga la nueva imagen en el buffer
retardo.cargar( entrada );
// toma una imagen del buffer como fondo actual para comparar
imagenAcomparar = retardo.punteroPrimero();
Utiliza un objeto llamado retardo que pertenece a la clase Buffer-Video y fue implementada para esta aplicacin.
La clase BufferVideo funciona como una cola (pool) que almacena objetos de Pimage. Se ingresan imgenes por un extremo y se las extrae por el otro, en funcin de la longitud de dicha cola es el retardo
(contados en fotogramas) que sufre el flujo de video que ingresa de la cmara.
El mtodo .cargar() es el encargado de ingresar una nueva imagen a la cola, y el mtodo .punteroPrimero() retorna
la primera disponible en la salida. Como se ve en el extracto de cdigo anterior (3.7.), la imagen actual de la cmara
ingresa a la cola y de la cola se extrae la imagenAcomparar, que es la que se comparar con la imagen actual.
73
Por el otro lado del if, se verifica si ya existe una imagen de referencia mediante la variable boolena fondoTomado que
funciona como bandera (flag) para este fin. Si an no existe una imagen de referencia, esta es tomada de la imagen
actual, que est almacenada en el objeto entrada. Luego designa esta imagen de referencia (fondoFijo) como la imagenAcomparar.
Cdigo 3.8.
}
else {
//cuando el mtodo es comparar con fondo
if ( !fondoTomado ) {
//si aun no se a tomado un fondo, se toma la imagen actual como nuevo fondo fijo
fondoFijo.copy( entrada, 0, 0, ancho, alto, 0, 0, ancho, alto);
//se indica que el fondo fijo ha sido tomado
fondoTomado = true;
}
//tomar la imagen del fondo fijo como imagen para comparar
imagenAcomparar = fondoFijo;
}
La SECCIN B se encarga de inicializar los arreglos de pxeles de los objetos entrada e imagenAcomparar, mediante el
mtodo .loadPixels(). Con el fin de cargar los pxeles de la imagen en un arreglo unidimensional siguiendo el orden de
la lectura (occidental), de izquierda a derecha y de arriba hacia abajo, esto agiliza la lectura de los valores de los pxeles.
Sin embargo, requiere de un pequeo ajuste para transformar las coordenadas bidimensionales en una
posicin unidimensional: si tomamos la variable i del ciclo for, que determina la posicin unidimensional,
entonces las operaciones para obtener la posicin X e Y de dicha posicin son:
Cdigo 3.9
for ( int i=0 ; i<largo ; i++ ) {
//obtiene la posicion en X e Y en funcin del orden del pixel
posx = i % ancho;
posy = i / ancho;
Para obtener X se usa la operacin mdulo (%) que calcula el resto de la divisin entera. Para calcular Y
se usa la divisin entera.
En la SECCIN C se obtiene el color de las respectivas imgenes, la actual y la que se usar para comparar. Luego en
la SECCIN D se separan los componentes color de estos, es decir, los valores de rojo, verde y azul y se los opera realizando una substraccin con valor absoluto:
Cdigo 3.10.
//SECCIN D
// obtiene la diferencia (absoluta, es decir en valor positivo) de cada uno de los componentes
// color: rojo, verde y azul
float difRed = abs( red(actual) - red(delFondo) );
float difGreen = abs( green(actual) - green(delFondo) );
float difBlue = abs( blue(actual) - blue(delFondo) );
74
Esta operacin es la que le da nombre al mtodo de captura. El valor absoluto ( abs() ) vuelve el resultado de la substraccin positivo, sin importar cul de los valores operados sea mayor.
Posteriormente, se obtiene el promedio de estas substracciones y se toma como valor de gris para crear la imagen
resultante. A continuacin, en la SECCIN E se usa dicho valor de gris para ser comparado con el valor de umbral y
decidir si este corresponde a un pxel que debe ser tomado como movimiento:
Cdigo 3.11.
// obtiene la diferencia promedio
float gris = ( difRed + difGreen + difBlue ) / 3.0;
//carga el resultado de la substraccin en la imagen para tal fin
substraccion.pixels[i] = color( gris, gris, gris );
//SECCIN E
//si la diferencia supera el valor de umbral, se lo considera movimiento
boolean conMovimiento = gris>umbral;
En la misma SECCIN E se consulta con un condicional (if ) el valor de la variable booleana conMovimiento (recin cargada) para realizar los clculos pertinentes (esto es actualizar los valores del rea, la posicin del centro de gravedad y
los lmites del bounding box), en caso de ser movimiento, y pintar los pxeles de blanco o negro (segn corresponda)
en la imagen bitonal.
Los clculos del centro de gravedad se completan en la SECCIN F, obteniendo el valor promedio de las posiciones de
todos los pxeles blancos (de movimiento).
Para ver otras tcnicas sobre implementaciones de la captura de movimiento se recomienda esta pgina de Daniel Shiffman:
<http://www.learningprocessing.com/examples/chapter-16/example-16-13/>
75
void draw() {
// si la cmara tiene un fotograma nuevo disponible
if ( camara.available() ) {
// pinta todo el fondo con el color gris con mucha transparencia para difuminar las figuras
pasadas
limpiarFondoConEsfumado( color( grisFondo, grisFondo, grisFondo, 10 ) );
76
77
}
}
//retorna a la configuracin de atributos de dibujo original
popStyle();
void keyPressed() {
// si se presiona la tecla espacio
if ( key == ) {
// invierte el estado de activacin del monitoreo
monitoreo = !monitoreo;
// si se quita el monitoreo se vuelve a limpiar el fondo
if ( !monitoreo ) {
background( grisFondo );
}
}
}
78
void mousePressed() {
// si se presion el botn principal del mouse
if ( mouseButton == LEFT ) {
// si se preciona el botn del mouse se recaptura el fondo
capturaDeMovimiento.recapturarFondo();
}
else {// si se presion el botn alternativo
//si esta en monitoreo
if ( monitoreo ) {
// si el mouse fue presionado en la regin de monitoreo del umbral
if ( mouseX > ancho*2 && mouseX < ancho*2 + 150 &&
mouseY >= 0 && mouseY <= 255 ) {
// calculo un nuevo valor
float nuevoValor = map( mouseY, 0, 255, 255, 0 );
// asigna el nuevo valor de umbral
capturaDeMovimiento.setUmbral( nuevoValor );
}
}
}
}
Este ejemplo, que contiene al anterior, calcula la cantidad de movimiento en las regiones definidas por las llamadas
.movEnArea(), luego, calcula la diferencia entre las dos regiones para determinar la cantidad de figuras que sern
mostradas en pantallas:
Cdigo 3.13.
// calcula la diferencia entre el movimiento captado en cada extremo
float diferencia = abs( movimientoALaDerecha - movimientoALaIzquierda );
// esta variable define la cantidad de figuras a ser dibujadas
int cantidad = 0;
// si la diferencia de movimiento es mayor a la diferencia mnima
if ( diferencia>diferenciaMinima ) {
// determina la cantidad en funcin de la diferencia
cantidad = int( map( diferencia, diferenciaMinima, 1,
cantidadMinima, cantidadMaxima ) );
}
La idea consiste en que, cuanto mayor diferencia, mayor cantidad de figuras. De esta manera, la cantidad se incrementa solo cuando una de las regiones se activa por vez, si ambas se activan se cancelan mutuamente y la cantidad
baja. Por ejemplo: si una persona se encuentra en el centro de la escena y mueve uno de sus brazos (pongamos, por
ejemplo, el izquierdo) entonces su silueta se dibuja con el tipo de figura que le corresponde (crculos o cruces), pero
si extiende ambos brazos, entonces la figura deja de dibujarse.
Una vez que la cantidad es determinada, un ciclo for es ejecutado con dicha cantidad, haciendo que en cada ciclo elija
una posicin al azar, en forma normalizada (es decir tomando valores entre 0 y 1), y utilice esta para dibujar una figura
(eligiendo la adecuada segn la regin activada).
79
Cdigo 3.14.
// se usa el ciclo for para dibujar la cantidad decidida de figuras
for ( int i=0 ; i<cantidad ; i++ ) {
//decide una posicin al azar en forma normalizada (entre 0 y 1)
float x = random( 1 );
float y = random( 1 );
// dimensiona las posicin al tamao de la cmara
int xEnCamara = int( x * ancho );
int yEnCamara = int( y * alto );
// revisa si hay movimiento en ese pixel
if ( capturaDeMovimiento.movEnPixel( xEnCamara, yEnCamara ) ) {
Como se ve en el extracto anterior, se obtiene una variable X e Y al azar, en forma normalizada y luego se traducen a
posiciones en el cuadro de la cmara.
Por ejemplo, si X tuviera un valor de 0,1, entonces la variable xEnCamara = int( x * ancho) adquirira
int(0,1*320) = 32.
A continuacin se invoca al mtodo .movEnPixel() del objeto capturaDeMovimiento para verificar la existencia de
movimiento en dicho pxel. Si hay movimiento, entonces calcula la posicin equivalente en pantalla, elige la figura
correspondiente y la dibuja.
Cdigo 3.15.
// calcula la posicion equivalente en la pantalla
float xEnPantalla = x * width;
float yEnPantalla = y * height;
// en funcin de cul de las dos regiones tiene ms movimiento
// decide cul figura dibuja
if ( movimientoALaDerecha > movimientoALaIzquierda ) {
// elige un color entre el rojo y el violeta al azar
stroke( random( 200, 255 ), 200, 250 );
// dibuja un crculo en dicha posicin
ellipse( xEnPantalla, yEnPantalla, tamanio, tamanio );
}
else {
// elige un color entre cercano al verde al azar
stroke( random( 40, 110 ), 200, 250 );
// dibuja una cruz en dicha posicin
cruz( xEnPantalla, yEnPantalla, tamanio );
}
Causa, E. Algoritmos de captura ptica de movimiento por substraccin de video, [en lnea]. www.biopus.com.ar, 2007. Disponible
en: < <http://www.biopus.com.ar/html/lista-textos.html> [Consulta: 13 de febrero de 2014].
80
El problema surge si hay dos sujetos de movimiento, ya que este algoritmo no es capaz de distinguir entre uno del
otro. Todo pxel blanco es considerado movimiento, omitiendo el sujeto que los genera. Bsicamente, el problema
se reduce a lograr reconocer las manchas inconexas, es decir: ver cules pxeles dependen de cul mancha y no
confundir pxeles de diferentes manchas (diferentes sujetos).
En general, de un blob se puede obtener el rea que ocupa (medida en cantidad de pxeles), el ancho y alto de la caja
que lo contiene (bounding box) y el centro de gravedad de la misma.
Tambin se puede examinar la forma del contorno de la mancha, entendiendo a dicho contorno como una secuencia
de segmentos. Otro dato que se puede analizar es su identidad, como un nmero entero que lo identifica y que no
debera cambiar de un fotograma a otro, producto de los sucesivos anlisis.
81
82
La captura por umbral funciona sin una imagen de referencia, simplemente se toma la imagen actual y se discrimina, en funcin de un valor de gris, aquellos valores que son ms claros de los ms oscuros. En rigor, se compara el
nivel de brillo de cada pxel con el valor de umbral y se transforma a los que estn por encima en blanco y a los que
estn por debajo en negro.
En este caso, el filtro que discrimina forma de fondo se aplica directamente a la imagen de la cmara en vez de al resultado de una substraccin. La librera BlobDetection permite aplicar dicho filtro y hacer un anlisis de los blobs resultantes, ya sea buscando las formas claras u oscuras, es decir decidiendo si la relacin figura/fondo se aplica tomando
lo claro (o lo oscuro) como figura. La librera se organiza mediante un conjunto de clases principales:
1) La clase BlobDetection que se encarga de hacer el anlisis de la imagen y separar los blobs.
2) La clase Blob que se utiliza para ver los atributos de cada uno de los blobs separados.
3) La clase EdgeVertex que sirve para ver los atributos de cada uno de los segmentos del contorno de un blob.
Cada una de esas clases sigue una jerarqua que respeta el orden en que fueron presentadas, es decir, un objeto del
tipo BlobDetection devuelve objetos del tipo Blob y estos, a su vez, devuelven objetos EdgeVertex, siguiendo la lgica
en la cual el BlobDetection es el analizador que devuelve los blobs encontrados y que estos, por su parte, devuelven
la forma de su contorno.
Esta estructura de rbol, que tiene al BlobDetection como raz, a los Blob como ramas y a los EdgeVertex como hojas,
requiere de un ciclo for para recorrer a los segundos y otro ciclo anidado para recorrer cada una de las hojas.
83
84
El cdigo principal del ejemplo se encuentra dividido en secciones. La porcin expuesta a continuacin utiliza un
conjunto de funciones que sern citadas ms adelante.
Cdigo 4.1.
//SECCIN A
//importa las libreras necesarias
import blobDetection.*;
import processing.video.*;
//variable que permite activar y desactivar el monitoreo
boolean monitor = true;
//variable que permite activar y desactivar el desenfoque para suavizar la imagen
boolean conDesenfoque = false;
//variable que permite definir si el sujeto el claro sobre fondo oscuro o al revs
boolean buscaClaro = true;
//esta variable define cual es el tipo de bucle que se usa
int CUAL_BUCLE = 1;
//SECCIN B
//objeto para capturar la imagen de la cmara
Capture camara;
//objeto que busca los Blobs en la imagen
BlobDetection manchas; //declaracion
//variable que define el nivel del umbral que discrimina entre claro y oscuro
float umbralBlobDetection;
//ancho y alto de la cmara
int anchoCamara = 320;
int altoCamara = 240;
void setup() {
//define el ancho y alto de la pantalla
size( 800, 600 );
//define la cantidad de cuadros por segundo
frameRate( 30 );
noFill();
smooth();
//SECCIN C
//imprime los dispositivos de video disponibles en el sistema
println( Capture.list() );
//inicializa la cmara
camara = new Capture( this, anchoCamara, altoCamara );
//camara.start(); esto es necesario en Processing 2.0
//SECCIN D
//inicializa el objeto BlobDetection
manchas = new BlobDetection( anchoCamara, altoCamara );
//define si se busca claro sobre oscuro a al revs
manchas.setPosDiscrimination( buscaClaro);
//define el umbral en 0.4 (40% del rango)
umbralBlobDetection = 0.4;
//establece dicho valor como umbral en el objeto
manchas.setThreshold( umbralBlobDetection );
85
void draw() {
//SECCIN E
//si la cmara tiene un nuevo fotograma disponible
if ( camara.available() ) {
//lee el nuevo fotograma de la cmara
camara.read();
//SECCIN F
//si el desefonque est activado, entonces lo aplica a la imagen
if (conDesenfoque) fastblur( (PImage) camara, 2 );
//ordena al objeto BlobDetection analizar los blobs en la imagen
manchas.computeBlobs( camara.pixels );
//SECCIN G
//muestra la imagen de la cmara a pantalla completa
image( camara, 0, 0, width, height );
//pone el color de dibujo en verde
stroke( 0, 255, 0);
//ejecuta la funcin que dibuja los bordes con un motivo de bucles
//en pantalla completa y para los blobs que miden ms de un 10% del ancho y
//alto de la imagen
dibujarTodosLosBlobsConMotivo( manchas, 0, 0, width, height,
width*0.1, height*0.1, 10);
//SECCIN H
//si el monitoreo est activado
if ( monitor ) {
//muestra la imagen de la cmara en el tamao original
image( camara, 0, 0 );
//dibuja los blobs, sus cajas (boundingbox)
dibujarTodosLosBlobsConAtributos( manchas, 0, 0, anchoCamara, altoCamara,
anchoCamara*0.1, altoCamara*0.1);
}
void keyPressed() {
//SECCIN I
//si se preciona la tecla espaciadora se activa/desactiva el monitoreo
if ( key == ) {
monitor = !monitor;
}
//si el monitoreo est activo
if ( monitor ) {
//SECCIN J
//si se presiona la tecla ARRIBA se sube el umbral
if ( keyCode == UP ) {
umbralBlobDetection += 0.025;
umbralBlobDetection = constrain( umbralBlobDetection, 0, 1 );
println( umbralBlobDetection = +umbralBlobDetection );
manchas.setThreshold( umbralBlobDetection );
86
En la SECCIN A del ejemplo se importan las dos libreras necesarias: processing.video y blobDetection. Luego se declaran tres variables booleanas que sirven para activar y desactivar el monitoreo, para activar el filtro de desenfoque
(blur) y la bsqueda de claro sobre oscuro en la deteccin de blobs.
La SECCIN B declara el objeto cmara de tipo Capture, y el objeto manchas del tipo BlobDetection. Luego declara
tres variables, encargadas de definir el nivel de umbral (de la captura) y las dimensiones de la imagen de la cmara. A
continuacin, en el void se-tup(), en la SECCIN C, se inicializa el objeto cmara.
En la SECCIN D se inicializa el objeto manchas del tipo BlobDetection. Este paso requiere de tres mtodos. El
primero, obviamente, el constructor de la clase, al que se le pasa las dimensiones de la imagen. El segundo mtodo,
.setPosDiscrimination(), define si se buscan las regiones claras u oscuras. Si se pasa un parmetro con valor true,
entonces las regiones claras son tomadas como figura y las oscuras como fondo. Con el valor false se invierte esta
relacin. El tercer mtodo, .setThreshold(), configura el umbral, recibiendo un valor entre 0 y 1. Cuando el valor es
0, el umbral es negro, y cuando el valor es 1, entonces es blanco. Los valores intermedios son valores de gris, por
ejemplo, el 0,8 es un gris claro, y si se usa como umbral, solo grises ms altos pasarn por blanco.
Ya en el mtodo void draw(), en la SECCIN E, se consulta si la cmara tiene un fotograma disponible (mtodo available() del objeto Capture) y si la condicin se cumple, se usa el mtodo read() para leer dicho fotograma.
La clave del algoritmo se encuentra en la SECCIN F, en donde se usa el mtodo computeBlobs() del objeto manchas
(del tipo BlobDetection) para que el objeto analice la imagen, ejecute la captura por umbral y detecte los blobs. Este
objeto ejecuta el anlisis y construye una lista de blobs, disponible para ser consultadas. Esta consulta se ejecuta en el
mtodo dibujarTodosLosBlobsConMotivo(), dentro de la SECCIN G, que se encarga de poner la imagen capturada y
el anlisis del BlobDetection en la pantalla.
A continuacin, mostraremos el cdigo que posee la mayora de las funciones invocadas en el cdigo principal del ejemplo.
Cdigo 4.2.
//variable que se usa como constante para definir la tolerancia para corroborar
//continuidad entre segmentos en la funcin
float TOLERANCIA = 10;
//-----------------------------------------------//funcin que dibuja los Blobs con sus atributos
//recibe como parmetro un objeto BlobDetection, la posicin y tamao para mostrar
//los blobs, y los tamaos mnimos para considerar los blobs (por debajo
//de esas dimensiones desestima el blob)
void dibujarTodosLosBlobsConAtributos( BlobDetection manchas, float x, float y,
float ancho, float alto, float anchoMinimo, float altoMinimo ) {
87
}
//-----------------------------------------------//funcin que dibuja los contornos de los Blobs
//adornados con bucles
//recibe como parmetro un objeto BlobDetection, la posicin y tamao para mostrar
//los blobs, y los tamaos mnimos para considerar los blobs (por debajo
//de esas dimensiones desestima el blob)
void dibujarTodosLosBlobsConMotivo( BlobDetection manchas, float x, float y,
float ancho, float alto, float anchoMinimo, float altoMinimo, int largo) {
//consulta la cantidad de blobs del objeto BlobDetection
int cantidadBlobs = manchas.getBlobNb();
//declara un objeto Blob para recibir los distintos blobs
Blob unaMancha;
//recorre los blobs
for ( int i=0 ; i<cantidadBlobs ; i++ ) {
//toma el i-simo blob
unaMancha = manchas.getBlob( i );
//revisa que el blob de turno supere el tamao mnimo definido
if ( (unaMancha.w*ancho)>anchoMinimo && (unaMancha.h*alto)>altoMinimo ) {
}
//-----------------------------------------------//funcin que recibe un blob y dibuja su caja y centro
void dibujarBlobCajaYCentro( Blob laForma, float x, float y,
float ancho, float alto ) {
88
}
//-----------------------------------------------//funcin que recibe un blob y dibuja el contorno
void dibujarBlobContorno( Blob laForma, float x, float y,
float ancho, float alto ) {
//consulta la cantidad de segmentos
int cantidadSegmentos = laForma.getEdgeNb();
//dibuja el segmento
line( x+desde.x*ancho, y+desde.y*alto,
x+hasta.x*ancho, y+hasta.y*alto
);
}
//-----------------------------------------------//dibuja el contorno del blob adornado con un bucle
//recibe como parmetros un blob, el largo de los motivos (cantidad de segmentos
//que se agrupan para simplificar la forma), la posicin y dimensin
void dibujarBordeDelBlobConMotivo( Blob laForma, int largo, float x, float y,
float ancho, float alto ) {
//consulta la cantidad de segmentos
int cantidadSegmentos = laForma.getEdgeNb();
//crea dos objetos para tomar los puntos de cada segmento
EdgeVertex desde, hasta;
//esta variable se usa para contar la cantidad de segmentos que se toman para
//simplificar la forma
int contador = 0;
//objetos para simplificar la forma
EdgeVertex anteriorHasta = null;
EdgeVertex inicio = null;
EdgeVertex fin = null;
89
}
}
else {
90
inicio = desde;
//cargar el valor del punto final, para tener de referencia en el siguiente ciclo
anteriorHasta = hasta;
}
//-----------------------------------------------//dibuja el motivo (adorno)
void dibujarUnSegmento( float x1, float y1, float x2, float y2 ) {
//decide cual motivo se dibuja
if ( CUAL_BUCLE == 1 ) {
dibujarUnSegmentoBucle( x1, y1, x2, y2 );
}
else {
dibujarUnSegmentoOtroBucle( x1, y1, x2, y2 );
}
}
//-----------------------------------------------//usa curvas de bezir para dibujar el bucle
void dibujarUnSegmentoBucle( float x1, float y1, float x2, float y2 ) {
//obtiene el angulo entre los dos puntos
float angulo = atan2( y2-y1, x2-x1 );
//obtiene la distancia entre los dos puntos
float distancia = dist( x1, y1, x2, y2 );
//obtiene el punto medio partiende el primer punto y recorriendo
//medio camino en la misma direccin
float xMedio = xDistanciaAngulo( x1, angulo, distancia*0.5 );
float yMedio = yDistanciaAngulo( y1, angulo, distancia*0.5 );
//parte del punto medio y consigue un nuevo punto girando -90 y
//recorriendo la misma distancia
float x3 = xDistanciaAngulo( xMedio, angulo-HALF_PI, distancia*2 );
float y3 = yDistanciaAngulo( yMedio, angulo-HALF_PI, distancia*2 );
//a partir del punto anterios obtien otros dos sobre una paralela a la recta
//definida por los dos puntos originales
float x4 = xDistanciaAngulo( x3, angulo+PI, distancia*0.5 );
float y4 = yDistanciaAngulo( y3, angulo+PI, distancia*0.5 );
91
}
//-----------------------------------------------//esta funcin hace lo mismo que la anterior pero varia la ubicacin de los puntos
//y su uso en la curva
void dibujarUnSegmentoOtroBucle( float x1, float y1, float x2, float y2 ) {
float angulo = atan2( y2-y1, x2-x1 );
float distancia = dist( x1, y1, x2, y2 );
float xMedio = xDistanciaAngulo( x1, angulo, distancia*0.5 );
float yMedio = yDistanciaAngulo( y1, angulo, distancia*0.5 );
float x3 = xDistanciaAngulo( xMedio, angulo-HALF_PI, distancia );
float y3 = yDistanciaAngulo( yMedio, angulo-HALF_PI, distancia );
float x4 = xDistanciaAngulo( x3, angulo+PI, distancia*0.5 );
float y4 = yDistanciaAngulo( y3, angulo+PI, distancia*0.5 );
float x5 = xDistanciaAngulo( x3, angulo, distancia*0.5 );
float y5 = yDistanciaAngulo( y3, angulo, distancia*0.5 );
beginShape();
vertex(x1, y1);
bezierVertex(x2, y2, x5, y5, x3, y3);
endShape();
beginShape();
vertex(x2, y2);
bezierVertex(x1, y1, x4, y4, x3, y3);
endShape();
}
//-----------------------------------------------//estas dos funciones encuentran un punto a partir de un punto de origen
//un ngulo y una distancia
float yDistanciaAngulo( float y, float angulo, float distancia ) {
return distancia * sin( angulo ) + y;
}
//-----------------------------------------------float xDistanciaAngulo( float x, float angulo, float distancia ) {
return distancia * cos( angulo ) + x;
}
92
Un dato importante es que estos valores se devuelven en forma normalizada, lo que significa que son valo-res entre
0 y 1. Por ejemplo, si unaMancha.x vale 0,5, entonces se encuentra en la mitad del cuadro, pero para traducir eso a
una posicin en la pantalla, hay que multiplicarlo por el ancho de la misma: unaMan-cha.x * width.
Dentro del ciclo for, hay un condicional (if ) que revisa que el blob tenga un tamao mnimo para ser tenido en
cuenta. Para facilitar los clculos, se multiplican el ancho y alto del blob (que estn normalizados) por el ancho y
alto recibido como parmetro, para hacer el clculo en pxeles: if ((unaMancha.w*ancho)>anchoMinimo &&
(unaMancha.h*alto)>altoMinimo).
Cdigo 4.3.
//funcin que dibuja los Blobs con sus atributos
//recibe como parmetro un objeto BlobDetection, la posicin y tamao para mostrar
//los blobs, y los tamaos mnimos para considerar los blobs (por debajo
//de esas dimensiones desestima el blob)
void dibujarTodosLosBlobsConAtributos( BlobDetection manchas, float x, float y,
float ancho, float alto, float anchoMinimo, float altoMinimo ) {
//consulta la cantidad de blobs del objeto BlobDetection
int cantidadBlobs = manchas.getBlobNb();
//declara un objeto Blob para recibir los distintos blobs
Blob unaMancha;
//recorre los blobs
for ( int i=0 ; i<cantidadBlobs ; i++ ) {
//toma el i-simo blob
unaMancha = manchas.getBlob( i );
//revisa que el blob de turno supere el tamao mnimo definido
if ( (unaMancha.w*ancho)>anchoMinimo && (unaMancha.h*alto)>altoMinimo ) {
93
En el cdigo recin citado se invoca la funcin .dibujarBlobCajaYCentro() que mostraremos a continuacin. Esta recibe un blob como parmetro y utiliza sus atributos para imprimir el bounding box y el centro del mismo:
Cdigo 4.4.
//funcin que recibe un blob y dibuja su caja y centro
void dibujarBlobCajaYCentro( Blob laForma, float x, float y,
float ancho, float alto ) {
//dibuja la caja (bounding box)
rect( x + laForma.xMin*ancho, y + laForma.yMin*alto,
laForma.w*ancho, laForma.h*alto );
//dibuja el centro
ellipse( x + laForma.x * ancho, y + laForma.y * alto, 10, 10 );
Otra funcin que queremos destacar es .dibujarBlobContorno() que recibe un blob como parmetro y usa un ciclo for
para recorrer los segmentos del contorno. Cada segmento se representa con dos puntos, del tipo EdgeVertex, que son
los lmites de cada segmento: el punto inicial y el punto final:
Cdigo 4.5.
94
//dibuja el segmento
line( x+desde.x*ancho, y+desde.y*alto,
x+hasta.x*ancho, y+hasta.y*alto
);
95
96
Se necesita que la cmara sea infrarroja para que no vea las proyecciones sobre la pantalla; si esto sucediera, dicha
imagen retroalimentara el sistema de captacin, lo que sera perjudicial. Por este motivo, la cmara solo debe ver
el espectro infrarrojo de la luz y no el visible. El proyector de video emite solo luz visible y por ende no sera percibido por el sistema de captacin, pero dicho sistema requiere una iluminacin que a su vez no interfiera con la
proyeccin de la imagen, por esto se usa tambin una iluminacin infrarroja que solo es percibida por la cmara y
no por el ojo humano.
Evidentemente, el eje de la problemtica gira en torno de la cmara y las condiciones de luz, y aunque parezca un
problema menor (que no lo es), el material del que se construye la pantalla es tan decisivo como la eleccin de la
cmara y la iluminacin:
97
Uno de los mayores focos de problema est en el material que se elige para usar
de superficie de retroproyeccin (este tema es ampliamente tratado en el texto de
Diego Pimentel). Esta superficie debe cumplir con una serie de requisitos complejos de lograr:
1. Resistencia: debe ser lo suficientemente resistente para permitir apoyar objetos
y posar los dedos para interactuar (a esto se suma el hecho de que la altura de la
mesa invita al pblico a apoyarse).
2. Opacidad: debe ser lo suficientemente opaca para permitir ver ntidamente (desde abajo) slo los objetos apoyados, pero no aquellos por encima. Por ejemplo,
deben poder verse los dedos apoyados, pero no la mano por encima de ellos, ni las
caras de las personas.
3. Transparencia y nitidez: tambin debe poder ser lo suficientemente transparente para dejar ver la imagen proyectada por detrs, pero lo suficientemente opaca
como para atrapar la luz y no dejarla pasar. Por ejemplo: si es muy transparente, la
proyeccin seguir de largo (proyectndose en el techo, en vez de la pantalla), si es
muy opaca no podr verse bien la imagen (hasta puede perder nitidez).
4. Antirreflejo: la superficie debajo de la pantalla debe poseer un tratamiento antirreflejo ya que el sistema de captura es muy sensible a los altos contrastes, principalmente si los producen los reflejos en esta superficie. Cuando la superficie no es
antirreflejos, funciona como un espejo que refleja el sistema de iluminacin.
En nuestra implementacin no pudimos encontrar una superficie que cumpla con
todos estos requisitos. El material que mejor cumpla el segundo y tercer requisito
es el papel vegetal (de tipo calco), pero claramente no cumpla el primer requisito,
lo que oblig a apoyarlo sobre un acrlico que no cumpla con el cuarto requisito. [...]
[...] La iluminacin que este sistema utiliza es infrarroja. Nosotros optamos por utilizar lmparas incandescentes filtradas con acetatos de color rojo y azul, que permiten generar luz infrarroja con focos comunes. Este tipo de iluminacin tiene como
ventaja su bajo costo y la facilidad de encontrar esos elementos en el mercado de
nuestro pas. Una de las ms importantes desventajas es el calor que genera, lo que
obliga a tomar medidas de ventilacin. El sistema alternativo que ms se utiliza es
el de reflectores de leds, que no generan calor y tienen una mayor durabilidad.
El mayor problema encontrado con la iluminacin fue con la superficie de la pantalla, que al no ser antirreflejo funcionaba como un espejo ms. Este pseudoespejo
termina haciendo que la cmara vea las lmparas, lo que produce ruido en la captacin de patrones. Debido a esto, nos vimos obligados a poner las lmparas lo
ms apartadas hacia los lados posible, para que no entre en el rea del reflejo, pero
esta solucin genera un tipo de iluminacin desigual que complica nuevamente la
captura. (Causa, 2011: 9 y 10)
98
[[] TUIO es un marco abierto (open framework) que define un protocolo y un API
(interfaz de programacin de aplicaciones) comn para pantallas multitctiles tangibles. El protocolo TUIO permite la transmisin de una descripcin abstracta de las
pantallas interactivas, incluyendo eventos de toque y estados de objetos tangibles.
Este protocolo codifica datos de control desde una aplicacin de seguimiento (por
ejemplo, basado en la visin por ordenador) y la enva a cualquier aplicacin de cliente que es capaz de decodificar el protocolo [] (Kaltenbrunner, s/f)
Es decir que TUIO es un protocolo con el que una aplicacin, que mediante visin artificial interpreta la accin de un
usuario en una pantalla (convirtindola en sensible al tacto), transmite a otras aplicaciones dichas acciones para que
estas acten en consecuencia. La idea es que la aplicacin de captura ya est resuelta y entonces solo quede implementar la aplicacin que utiliza dicha captura.
Este protocolo est pensado para captar patrones bitonales impresos en piezas tangibles (no virtuales) y dedos sobre
una pantalla. A los patrones les llama fiduciales u objetos, mientras que a los dedos los llama cursores. De cada
uno de estos tipos de elementos, el protocolo reconoce tres eventos: 1) el ingreso en escena, 2) la modificacin de la
posicin o rotacin en escena, 3) el egreso de la escena.
[] TUIO distingue dos tipos de elementos: objetos y cursores. Los objetos son los
patrones bitonales, mientras que los cursores son los dedos que se apoyan sobre
la pantalla (dado que el sistema tambin es capaz de reconocer el tacto). Cada una
de estas funciones informan un evento de un patrn o de tacto:
addTuioObject: informa la aparicin de un nuevo patrn sobre la pantalla.
removeTuioObject: informa que un patrn sali de la pantalla.
updateTuioObject: informa los cambio que sufre un patrn, ya sea de posicin
como de rotacin.
addTuioCursor: informa la aparicin de un dedo sobre la pantalla.
removeTuioCursor: informa que un dedo sali de la pantalla.
updateTuioCursor: informa los cambios que sufre un dedo, un cambio de posicin
[] (Causa, 2011)
Processing posee una librera que permite conectarse a este protocolo y as recibir informacin de los eventos recin
explicados. Seguidamente puede observarse un ejemplo mnimo de aplicacin en Processing que recibe mensajes
mediante el protocolo TUIO:
99
Cdigo 4.6.
import TUIO.*;
TuioProcessing tuioClient;
void setup()
{
tuioClient = new TuioProcessing(this);
}
void draw()
{
}
void addTuioObject(TuioObject tobj) {
}
void removeTuioObject(TuioObject tobj) {
}
void updateTuioObject (TuioObject tobj) {
}
void addTuioCursor(TuioCursor tcur) {
}
void updateTuioCursor (TuioCursor tcur) {
}
void removeTuioCursor(TuioCursor tcur) {
}
void refresh(TuioTime bundleTime) {
redraw();
}
En el ejemplo, puede verse la importacin de la librera y la declaracin de un objeto de tipo TuioProcessing en las primeras lneas. Luego, en el void setup() se inicializa el objeto. No aparecen lneas en el void draw() ya que no son obligatorias,
pero ms adelante veremos que existen formas de acceder a los mensajes de TUIO desde esta estructura.
Debajo del void draw() aparece una serie de siete funciones, de las cuales las seis primeras se corresponden con los
seis tipos de eventos (o mensajes) que el protocolo transmite: addTuioObject, removeTuioObject, updateTuioObject,
addTuioCursor, removeTuioCursor y updateTuioCursor. La ltima, refresh() la utiliza TUIO para redibujar la escena.
Una cuestin importante de comprender es que Processing, con la librera de TUIO, puede acceder a los eventos y
estados de los objetos y cursores en forma sincrnica y asincrnica. A los eventos accede en forma sincrnica mediante las funciones de los eventos que fueron listados en el prrafo anterior. A los estados, de forma asincrnica
consultando durante el void draw(). Los eventos son fenmenos que no tienen duracin y que dividen el tiempo.
Mientras que los estados permanecen, tienen duracin. En general, un estado est limitado por eventos y/o los
eventos son cambios de estado.
La imagen siguiente (4.8.) muestra un esquema con un ejemplo de cmo se accede en forma sincrnica y asincrnica
a los eventos y estados. La secuencia de eventos que muestra es:
a) Ingresa el fiducial (objeto) 1,
b) el mismo fiducial se mueve,
c) ingresa el fiducial 2,
d) se quita el fiducial 1,
e) se quita el fiducial 2.
100
Para cada uno de estos eventos hay un recuadro rojo o azul que lo representa y a su izquierda el fiducial que lo genera.
A la derecha se encuentra la secuencia de funciones que se ejecutan en Processing, en amarillo los void draw() y en
verde las que son disparadas por los eventos de TUIO.
Por ejemplo, se puede ver que la primera ejecucin del void draw() no accede a ningn objeto. Luego ingresa el fiducial 1 que dispara la funcin void addTuioObjetct() y pasar como parmetro los datos de dicho evento: posicin del
objeto, rotacin, identidad, etctera.
En la siguiente ejecucin del void draw(), este accede al estado del fiducial 1, es decir que sabe que est en escena
y dnde se encuentra (as como la rotacin, velocidad de movimiento, etc.). Cuando el fiducial se mueve, dispara el
evento void updateTuioObject(), luego el fiducial aparece en escena y dispara su correspondiente evento void addTuioObjetct().
Obviamente, la ejecucin de las funciones de los eventos solo puede acceder a la informacin del objeto o cursor que los
gener, mientras que el void draw() puede acceder al estado de todos los objetos o cursores existentes en ese momento,
tal como se ve en el grfico, en la tercera y cuarta ejecucin de esta estructura, que acceden a ambos fiduciales.
Imagen 4.8. Ejemplo de cmo se accede a los eventos y estados
101
En la seccin de Simulacin de
Ecosistema/Movimiento, del Tutorial de Arte y Vida Artificial, se
encuentra una detallada explicacin de cmo desarrollar agentes
autnomos que se mueven en un
espacio bidimensional usando sistemas de coordenadas polares.
Para ahondar en nuestro ejemplo, diremos que existe un arreglo de agentes que se encarga de mover y dibujar en
cada ciclo del void draw(). Los agentes tienen dos estados, activos o inactivos. Cuando se los activa, vagan azarosamente siguiendo una direccin que van cambiando lentamente, a partir del punto donde fueron creados, y luego de
un tiempo (que es distinto para cada agente) se desactivan.
As, el ciclo de vida del agente tiene este recorrido: se lo crea en una posicin de pantalla (nace activo) y vaga por la
pantalla hasta que cumple su tiempo y se desactiva, luego permanece en ese estado a la espera de volver a ser creado
(sobreescrito). Un agente posee un conjunto de mtodos de los que nombraremos los ms importantes:
.dibujar(): se encarga de dibujar el agente en cuestin en pantalla. Este mtodo solo se ejecuta si el agente est activo.
.mover(): se encarga de hacer avanzar al agente un paso en su movimiento por la pantalla. Solo se ejecuta si el agente est activo. Tambin revisa el tiempo que el agente lleva activo para desactivarlo cuando haya pasado el valor
prefijado para este (el cual se fija al momento de crear el agente).
.desactivar(): desactiva al agente.
.encontrar(): este mtodo se ejecuta con relacin a otro agente (que se le pasa como parmetro) y evala si ambos
agentes estn activos y si estn colisionando en la pantalla, en cuyo caso dibuja un cuadrado con un color que es
mezcla de los de los agentes. Esto sucede si las identidades de los agentes son diferentes entre s. La identidad se
asigna a los agentes segn cul objeto los haya creado. Es decir, que dos agentes que nacen del mismo objeto
(fiducial) no producen un encuentro, aunque estn colisionando.
La idea de la aplicacin es que cuando entran fiduciales en escena, cada uno de ellos genera agentes, estos salen a
vagar por la pantalla y cuando agentes (provenientes de diferentes fiduciales) colisionan, entonces se dibujan cuadrados en la posicin de la colisin. Por otro lado, cuando ingresa un cursor, es decir que alguien arrastra un dedo en la
pantalla, entonces los agentes se ven influenciados por la direccin del movimiento del cursor.
Por ejemplo, en la imagen siguiente (4.9.) vemos una captura de pantalla en la que se encuentra la aplicacin del
ejemplo y a la derecha el simulador de ReacTiVision. All, pueden verse los nodos generadores de agentes que produce cada uno de los fiduciales en escena, como algunos cuadrados generados a partir de las colisiones de los agentes
provenientes de diferentes fiduciales:
102
Imagen 4.9.
104
}
//--------------------------------------------------------void draw() {
//pinta un rectngulo del tamao de la pantalla blanco y muy transparente
//para ir cubriendo
fill( 255, 10 );
rect( 0, 0, width, height);
//SECCIN E
//carga (en un vector) la lista de objetos presentes en TUIO
Vector listaDeObjetosTUIO = clienteTUIO.getTuioObjects();
//consulta la cantidad cargada en el vector
int cantidadDeObjetos = listaDeObjetosTUIO.size();
//recorre con un ciclo for la lista de objetos
for ( int i=0 ; i<cantidadDeObjetos ; i++ ) {
//extrae un objeto de la lista
TuioObject esteObjeto = (TuioObject) listaDeObjetosTUIO.elementAt(i);
//obtiene la posicin en pantalla del objeto
float x = esteObjeto.getScreenX(width);
float y = esteObjeto.getScreenY(height);
//ejecuta esta funcin que crea un nuevo agente en el arreglo (sobreescribiendo uno existente)
crearNuevoAgente( x, y, esteObjeto.getSymbolID(), esteObjeto.getAngle() );
}
//SECCIN F
//con estos dos ciclos for anidados compara todos los agentes contra todos los otros
//sin repetir la comparacin, es decir: si compara A->B, entonces no hace B->A
//es decir, considera que la relacin es simtrica y por ende igual desde ambos lados
//por ende injustificado hacer la comparacin recproca de cada una
for ( int i=0 ; i<cantidad-1 ; i++ ) {
for ( int j=i+1 ; j<cantidad ; j++ ) {
agentes[i].encontrar( agentes[j] );
}
}
//SECCIN G
//recorre todos los agentes, los mueve y los dibuja en escena
for ( int i=0 ; i<cantidad ; i++ ) {
agentes[i].mover( seguirAngulo, angulo );
agentes[i].dibujar();
}
//desactiva el seguimiento del cursor
seguirAngulo = false;
}
//--------------------------------------------------------//esta funcin tiene que estar por el uso de TUIO, aunque en este caso no se usen los datos que trae
void addTuioObject(TuioObject tobj) {
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(add object +tobj.getSymbolID()+ (+tobj.getSessionID()+) +tobj.getX()+
+tobj.getY()+ +tobj.getAngle());
}
105
//esta funcin tiene que estar por el uso de TUIO, aunque en este caso no se usen los datos que trae
void removeTuioObject(TuioObject tobj) {
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(remove object +tobj.getSymbolID()+ (+tobj.getSessionID()+));
}
//esta funcin tiene que estar por el uso de TUIO, aunque en este caso no se usen los datos que trae
void updateTuioObject (TuioObject tobj) {
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(update object +tobj.getSymbolID()+ (+tobj.getSessionID()+) +tobj.getX()+
+tobj.getY()+ +tobj.getAngle()
//
+ +tobj.getMotionSpeed()+ +tobj.getRotationSpeed()+ +tobj.getMotionAccel()+ +tobj.getRotationAccel());
}
//esta funcin tiene que estar por el uso de TUIO, aunque en este caso no se usen los datos que trae
void addTuioCursor(TuioCursor tcur) {
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(add cursor +tcur.getCursorID()+ (+tcur.getSessionID()+ ) +tcur.getX()+
+tcur.getY());
}
//SECCIN H
//esta funcin tiene que estar por el uso de TUIO
//en este ejemplo se usa para extraer el angulo del ltimo cursor en movimiento
void updateTuioCursor (TuioCursor esteCursor) {
//carga en un vector la lista del puntos del camino recorrido por el cursor
Vector listaDePuntos = esteCursor.getPath();
//obtiene la cantidad de datos de la lista
int cantidad = listaDePuntos.size();
//si hay al menos dos puntos en el camino
if ( cantidad>1 ) {
//obtiene el anteltimo punto
TuioPoint desde = (TuioPoint) listaDePuntos.elementAt( cantidad-2 );
//obtiene el ltimo punto
TuioPoint hasta= (TuioPoint) listaDePuntos.elementAt( cantidad-1 );
//obtiene el ngulo de direccin entre los dos puntos
angulo = atan2( hasta.getScreenY(height) - desde.getScreenY(height),
hasta.getScreenX(width) - desde.getScreenX(width) );
//activa el seguimiento del cursor
seguirAngulo = true;
}
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(update cursor +tcur.getCursorID()+ (+tcur.getSessionID()+ ) +tcur.getX()+
+tcur.getY()
//
+ +tcur.getMotionSpeed()+ +tcur.getMotionAccel());
}
//esta funcin tiene que estar por el uso de TUIO, aunque en este caso no se usen los datos que trae
void removeTuioCursor(TuioCursor tcur) {
//se puede descomentar la linea de abajo para ver los valores que ingresa
//println(remove cursor +tcur.getCursorID()+ (+tcur.getSessionID()+));
}
//esta funcin tiene que estar por el uso de TUIO
void refresh(TuioTime bundleTime) {
redraw();
}
106
La estructura central de la aplicacin es la misma que la citada en el ejemplo mnimo de ReacTiVision, es decir, el void
setup(), el void draw() y la secuencia de siete funciones que TUIO exige para administrar sus eventos. El cdigo tiene
unas etiquetas SECCIN para destacar algunas porciones del mismo.
Empecemos con la SECCIN A al inicio de la aplicacin, en dicha seccin se declara el objeto clienteTUIO que pertenece a la clase TuioProcessing. Este objeto es encargado de recibir los mensajes del protocolo TUIO proveniente de
ReacTiVision o del TuioSimulator. Debajo, en la misma seccin, se declara el arreglo de agentes[ ] perteneciente a la
clase Agente, que se encarga de poner la coleccin de agentes en funcionamiento y unas lneas ms abajo aparece
el arreglo paletaTintas[ ] del tipo flotante, que se encarga de asignar diferentes colores a los agentes en funcin del
fiducial del que provienen.
En la SECCIN B, dentro del void setup() se inicializa el objeto clienteTUIO usando el constructor de la clase y pasando
como parmetro el puntero this que apunta a la aplicacin, esto se hace para que la clase TuioProcessing tenga acceso
a la aplicacin para enviar los eventos en forma asincrnica (independiente del ciclo) del void draw().
La SECCIN C se encarga, primero, de inicializar el arreglo agentes[ ] usando la variable cantidad para otorgarle dimensin, luego con un ciclo for recorre una a una las celdas (elementos) del arreglo, inicializando cada uno como objeto
del tipo Agente e inmediatamente a continuacin, lo desactiva para que no entre en funcionamiento.
Esto puede parecer arbitrario, pero se debe a que es necesario iniciar los objetos del arreglo para que futuros ciclos
for no se encuentren con un error por puntero nulo (null pointer exception). La idea consiste en que todos los objetos
del arreglo estn inicializados, ya sea activos o inactivos; y cuando el objeto termina su ciclo de vida pasa a desactivarse. Inicialmente, todos los objetos Agente empiezan desactivados para que no haya nada en pantalla hasta que un
fiducial los ponga en escena.
Una de las partes ms complejas y centrales del algoritmo se encuentra en la SECCIN E, ya que trata del acceso
asincrnico a los datos de los fiduciales puestos en escena. Para esto se usa un objeto del tipo Vector, llamado listaDeObjetosTUIO, que es una suerte de arreglo capaz de almacenar varios elementos. En este caso se usar para que
el objeto clienteTUIO devuelva una lista de los fiduciales que estn actualmente en escena, para esto se invoca al
mtodo .getTiuoObjects().
Una vez que el vector fue cargado con los objetos, se usa el mtodo .size() para cargar la cantidad de elementos en la
variable cantidadDeObjetos. Para acceder a cada uno de los elementos del vector es necesario usar un ciclo for que
recorra el vector usando el mtodo .elementAt() que devuelve el i-simo elemento del vector:
Cdigo 4.8.
//recorre con un ciclo for la lista de objetos
for ( int i=0 ; i<cantidadDeObjetos ; i++ ) {
//extrae un objeto de la lista
TuioObject esteObjeto = (TuioObject) listaDeObjetosTUIO.elementAt(i);
Se usa un objeto de tipo TuioObject llamado esteObjeto para cargar el fiducial de turno. Una vez hecho esto es posible
acceder a los datos del fiducial, como su identidad, posicin y rotacin. Lo que en este caso es usado para crear un
nuevo agente, en dicha posicin (usando .getScreenX() y .getScreenY()), asignndole un color en funcin de la identidad del fiducial (usando .getSymbolID() y su rotacin (usando .getAngle()):
107
Cdigo 4.9.
float x = esteObjeto.getScreenX(width);
float y = esteObjeto.getScreenY(height);
//ejecuta esta funcin que crea un nuevo agente en el arreglo (sobreescribiendo uno existente)
crearNuevoAgente( x, y, esteObjeto.getSymbolID(), esteObjeto.getAngle() );
108
Luego, con un condicional (if ), si la cantidad de puntos es mayor a UNO (1), entonces se obtienen los dos ltimos puntos, llamados desde y hasta, y con la funcin atan2() se obtiene el ngulo determinado por dicho par de puntos, el
resultado es cargado en la variable ngulo, que justamente determinar la direccin de movimiento que los agentes
deben seguir.
Para que el seguimiento se ponga en marcha, se activa (pone en valor true) la variable seguirAngulo. Esta ltima seccin muestra cmo aprovechar un evento para extraer informacin sobre la interaccin del usuario.
Por ltimo veremos cmo trabaja la funcin crearNuevoAgente( ), que, como su nombre lo indica, genera nuevos
agentes en los lugares en dnde existen fiduciales. Veamos a continuacin el cdigo (cdigo 4.11.) de la misma:
Cdigo 4.11.
void crearNuevoAgente( float x, float y , int id , float angulo ) {
int cualPaleta = id % cantidadPaleta;
float medioAngulo = abs( degrees( angulo + HALF_PI ) );
medioAngulo = medioAngulo % 360;
if( medioAngulo>180 ){
medioAngulo = map( medioAngulo , 180 , 360 , 180 , 0 );
}
float brillo = map( medioAngulo , 0 , 180 , 255 , 0 );
float saturacion = map( medioAngulo , 0 , 90 , 0 , 255 );
saturacion = constrain( saturacion , 0 , 255 );
float tinta = paletaTintas[ cualPaleta ] + random(-VARIACION_COLOR,VARIACION_COLOR);
tinta = constrain( tinta , 0 , 255 );
color colorDeEsteAgente = color( tinta , saturacion , brillo , TRANSPARENCIA_AGENTES );
Tal como vimos, esta funcin es invocada en la Seccin E al momento de ir recorriendo los fiduciales que estn presentes. Al momento de ser invocada recibe como parmetros los del fiducial de turno, es decir: la posicin x e y, la
identidad del fiducial y el ngulo de rotacin del mismo. Veamos entonces qu uso hace esta funcin de cada uno
de estos parmetros. Iniciemos por el ID (la identidad), la cual sirve para determinar la paleta de colores con la que se
crear el agente.
En la Seccin D del programa principal, se crea una arreglo paletaTintas[ ] usando la variable cantidadPaleta para
definir la cantidad (en este caso tiene asignado un valor de 20). Este arreglo, tiene en cada celda definido un valor
numrico que ser el valor de tinte (en un sistema de color HSB) de los colores de los agentes.
109
La relacin que se establece para decidir la paleta en funcin de la identidad es con la siguiente operacin:
Cdigo 4.12.
int cualPaleta = id % cantidadPaleta;
La operacin mdulo (%) retorna el mdulo (resto) de una divisin entera, por ejemplo: 8 % 3 sera 2, es decir, el resto
de dividir 8 por 3 es 2. Por definicin el mdulo de N siempre est entre 0 y N-1. Por ende, con esta operacin nos
aseguramos que sin importar el nmero de ID, el valor de cualPaleta est dentro del rango entre 0 y cantidadPaleta-1.
La siguiente cuestin es el uso del ngulo de rotacin del fiducial, el cual se utiliza para definir, en forma conjunta, los
valores de la saturacin y brillo del color. La forma en que esto se hace es mediante una serie de operaciones (cdigo C):
Cdigo 4.13.
float medioAngulo = abs( degrees( angulo + HALF_PI ) );
medioAngulo = medioAngulo % 360;
if( medioAngulo>180 ){
medioAngulo = map( medioAngulo , 180 , 360 , 180 , 0 );
}
<http://es.wikipedia.org/wiki/
Radi%C3%A1n>
En la primera lnea se declara la variable medioangulo, a la que se le asigna el valor de angulo, ms 90 grados de giro, luego transformada a grados (para trabajar ms cmodo) y pasado a valor absoluto, es decir, siempre con valores positivos.
La suma de los 90 grados responde a un giro que se le agrega por comodidad, en funcin del tipo de giro que se busca.
La segunda lnea se asegura que la variable haya quedado en el rango entre 0 y 360, usando las propiedades de la
operacin mdulo ya citada. Por ltimo, con el if se transforman los valores entre 180 y 360 al rango 180 a 0. Con esto,
a un ngulo que va desde 0 a 360 en forma slo creciente, se lo transforma en un rango que va de 0 a 180 y luego
nuevamente a 0, es decir que crece y luego decrece, para ser cclico (como se ve en la Imagen 4.11.).
imagen 4.11. Evolucin de la variable medioAngulo en funcin del giro
110
Las siguientes lneas (cdigo D) traducen el valor de la variable medioAngulo, en los de saturacin y brillo. A su vez, se
utiliza el valor de la paleta elegida, ms un desfazaje al azar, para establecer el tinte del color. Por ltimo, se establece
la variable colorDeEsteAgente usando los valores de tinte, saturacin y brillo, as como el valor de transparencia.
Cdigo 4.14.
float brillo = map( medioAngulo , 0 , 180 , 255 , 0 );
float saturacion = map( medioAngulo , 0 , 90 , 0 , 255 );
saturacion = constrain( saturacion , 0 , 255 );
float tinta = paletaTintas[ cualPaleta ] + random(-VARIACION_COLOR,VARIACION_COLOR);
tinta = constrain( tinta , 0 , 255 );
color colorDeEsteAgente = color( tinta , saturacion , brillo , TRANSPARENCIA_AGENTES );
Por ltimo, como puede verse en las siguientes lneas (cdigo 4.15.), se utiliza la variable cual para recorrer el arreglo
de objetos agentes[ ] e ir iniciando los agentes usando el color establecido por la rotacin y la identidad, as como la
posicin del fiducial. En la ltima lnea se puede ver cmo se incrementa la variable cual y se le aplica el mdulo para
mantener el valor dentro del rango entre 0 y cantidad-1. Dicho de otra forma, la variable cual va avanzando cclicamente dentro del rango para ir turnando el agente que se reiniciar, para mantener el caudal de agentes en constante
generacin.
Cdigo 4.15.
agentes[cual] = new Agente( x , y , colorDeEsteAgente , id );
cual = (cual+1) % cantidad;
El uso de estas variables ( agentes[ ] y cual ) desde la funcin es posible debido a que estas estn declaradas como
variables globales.
111
Causa, E. (2011), Desarrollo de un sistema ptico para interfaces tangibles (mesa con pantalla reactiva), en: RIM 3: Revista de
Investigacin Multimedia, Area Transdepartamental del I.U.N.A,
Buenos Aires.
Causa, E. (2011), Desarrollo de una aplicacin con interfaces tangibles (mesa con pantalla reactiva), en: Red Mercosur de Facultades de Diseo y Arte Multimedial. 3ra Jornadas Interuniversitarias,
I.U.N.A, Buenos Aires.
Pimentel, D. y Otros (2011), Mundo Circular. Ejemplo low-tech de realidad aumentada e interfaces tangibles, Congreso SIGRADI 2011, Santa Fe, Argentina. [Proceedings of the 15th Iberoamerican Congress of Digital Graphics].
Causa, E. (2011), Diseo de interface para el desarrollo de una pantalla sensible al
tacto con aplicacin musical, en: RIM 3: Revista de Investigacin Multimedia, Area
Transdepartamental del I.U.N.A, Buenos Aires.
Causa, E. Tutorial de Arte y Vida Artificial, [en lnea]. www.biopus.com.ar. 2007. Disponible en: <http://www.biopus.com.ar/emiliano/tutorial_vida_artificial/index.
html> [Consulta: 18 de febrero de 2014].
Causa, E. Algoritmos para el anlisis de formas y reconocimiento de patrones bitonales, [en lnea]. www.biopus.com.ar. 2007. Disponible en: <http://www.biopus.com.ar/
emiliano/tutorial_vida_artificial/index.html> [Consulta: 18 de febrero de 2014].
112
Referencias bibliogrficas
Unidades 1 y 2
Processing: A Programming Handbook for Visual Designers and Artists Reas, Casey, Fry, Ben Published by The MIT
Press (2007-08-17) ISBN 10: 0262182629 / ISBN 13: 9780262182621
Learning Processing: A Beginners Guide to Programming Images, Animation, and Interaction (Morgan Kaufmann Series
in Computer Graphics) Shiffman, Daniel. Published by Morgan Kaufmann (2008-09-02) ISBN 10: 0123736021 / ISBN
13: 9780123736024
The Nature of Code: Simulating Natural Systems with Processing. Shiffman, Daniel. Published by CREATESPACE
01/02/2014, 2014 ISBN 10: 0985930802 / ISBN 13: 9780985930806
Bonsiepe, G. (1999), Del objeto a la interfase, Ediciones infinito, Buenos Aires.
Raymond, E. (1999), The Cathedral & the Baazar, Beijing, Cambridge, Mass, England.
Unidad 3
Causa, E. Algoritmos de captura ptica de movimiento por substraccin de video, [en lnea]. www.biopus.com.ar, 2007.
Disponible en: < <http://www.biopus.com.ar/html/lista-textos.html> [Consulta: 13 de febrero de 2014].
Noble, J. (2012), Programming Interactivity, 2nd Edition A Designers Guide to Processing, Arduino, and openFrameworks,
Editorial OReilly Media.
Shiffman, D. (2008), Learning Processing A Beginners Guide to Programming Images, Animation and Interaction, Editorial Morgan Kaufmann.
Szeliski, R. (2011), Computer Vision, Algorithms and Applications, Editorial Springer.
Unidad 4
Causa, E. (2011), Desarrollo de un sistema ptico para interfaces tangibles (mesa con pantalla reactiva), en: RIM 3:
Revista de Investigacin Multimedia, Area Transdepartamental del I.U.N.A, Buenos Aires.
Causa, E. (2011), Desarrollo de una aplicacin con interfaces tangibles (mesa con pantalla reactiva), en: Red Mercosur de Facultades de Diseo y Arte Multimedial. 3ra Jornadas Interuniversitarias, I.U.N.A, Buenos Aires.
Pimentel, D. y Otros (2011), Mundo Circular. Ejemplo low-tech de realidad aumentada e interfaces tangibles, Congreso SIGRADI 2011, Santa Fe, Argentina. [Proceedings of the 15th Iberoamerican Congress of Digital Graphics].
Causa, E. (2011), Diseo de interface para el desarrollo de una pantalla sensible al tacto con aplicacin musical, en:
RIM 3: Revista de Investigacin Multimedia, Area Transdepartamental del I.U.N.A, Buenos Aires.
113
Causa, E., Tutorial de Arte y Vida Artificial, [en lnea]. www.biopus.com.ar. 2007. Disponible en: <http://www.biopus.
com.ar/emiliano/tutorial_vida_artificial/index.html> [Consulta: 18 de febrero de 2014].
Causa, E., Algoritmos para el anlisis de formas y reconocimiento de patrones bitonales, [en lnea]. www.biopus.
com.ar. 2007. Disponible en: <http://www.biopus.com.ar/emiliano/tutorial_vida_artificial/index.html> [Consulta: 18
de febrero de 2014].
Kaltenbrunner, M., TUIO protocol, [en lnea]. <tuio.org>. Disponible en: <http://tuio.org/>, [Consulta: 18 de febrero
de 2014].
Shiffman, D. (s/d), Autonomolus Agents, The Nature of Code. Disponible en: <http://natureofcode.com>.
114