Estás en: Cristalab > Artículos > Detección de movimiento de webcam con Flash 8
Detección de movimiento de webcam con Flash 8
Por: _CONEJO +
14 de Septiembre del 2005
Esto es más un ejemplo que un tutorial propiamente dicho, explotaremos una de las propiedades de Flash 8 ahora que ha sido por fin publicado, y todo ya saben donde, en su comunidad favorita, Cristalab!
Haremos un sencillo "menú" que detectará en que parte de la imagen estamos haciendo la simulación de que pulsamos los botones. Para ello utilizaremos la nueva version de Flash 8 aunque tambien podemos hacerlo con FAMES y Flash, aunque se podría realizar enteramente con la versión 7 del mismo y algunas clases extra.
Indispensable : Una WebCam!
Nota :
Apaga las luces de tu cuarto, el fondo deberá de ser oscuro y nosotros claros, esto es porque la función getPixel devuelve el color, números altos si son claros, números bajos si son oscuros. La iluminación de mi habitación en ese momento era de fondo oscuro, no es por otra cosa.
Teoría Para trabajar con getPixel nos hace falta un objeto BitmapData, a estos objetos se les da un ancho y alto, que será el tamaño del "lienzo". Una vez creado el BitmapData dibujaremos en el mediante el método "draw" pasándole como parámetro el MC que queremos "dibujar". Decir que el objeto BitmapData es "invisible" no se verá pues solo guarda los datos de las imágenes. En nuestro ejemplo "dibujaremos" cada 33 milisegundos la imágen que esté actualmente en la cámara para asi ir actualizando la información del BitmapData. Después con el método getPixel obtendremos el valor del color de 3 pixeles, hacremos una distinción como se comento antes entre oscuro [inactivo] y claro [activo].
Nota :
Si no entendiste nada pero de todas formas quieres experimentar, descarga el FLA: Descargar FLA Recuerda que debes tener el Flash Player 8 instalado en tu navegador, instalalo aqui
Comencemos el tutorial Como ya dije, se explicarán dos formas de realizar este sencillo "menu óptico" una con Flash8 y otra con Flash7 y FAMES.
En primer lugar abrimos Flash, creamos un archivo de 520x240 píxeles. Abrimos la biblioteca [Ctrl+L] y creamos un nuevo video. Si no sabeis como, en la pestañita de arriba a la derecha, pulsais y ahí estará la opción deseada. Lo pasamos de la biblioteca al escenario, a la posición 0,0 y le damos un tamaño de 320x240 píxeles, le damos el nombre de "vid", lo convertimos a MovieClip y le pones el nombre de "mcVideo", de forma que el video sea _root.mcVideo.vid .
En segundo lugar cogemos 3 imágenes cualesquiera, las convertimos a MovieClips y las soltamos en el escenario -en la derecha para que no se mezclen con el video- , dándoles de nombre "pron" , "maspron" y "koala". Finalmente podemos poner unos textos en una capa superior al video, en las dos esquinas superiores del video y en la parte central arriba.
Camino 1 : Usar Flash 8 Pues en flash, pulsamos F9 para abrir el panel de acciones y colocamos este código
Código :
//Variables que utilizaremos
var weedcam:Camera;
var zona;
var imagen:Video;
var pron,maspron,koala:MovieClip;
//La función que detecta si pulsamos o no
function accion()
{
//""Dibujamos"" la imagen de la webcam en el bitmapData
//Funciona con MC o dibujando a mano, ver la referencia al respecto
//para más información
zona.draw( imagen );
//Estos 3 son iguales, detectan si un pixel es claro o no
// este valor 16777215 es el que toman antes de que se inicialice la cámara así evitamos que aparezcan pulsados al principio
if(zona.getPixel(10,10)>9000000 && zona.getPixel(10,10)!=16777215) {
_root.pron._visible = true;
_root.maspron._visible = false;
_root.koala._visible = false;
};
if(zona.getPixel(310,10)>9000000 && zona.getPixel(310,10)!=16777215) {
_root.pron._visible = false;
_root.maspron._visible = false;
_root.koala._visible = true;
};
if(zona.getPixel(160,10)>9000000 && zona.getPixel(160,10)!=16777215) {
_root.pron._visible = false;
_root.maspron._visible = true;
_root.koala._visible = false;
};
}
//Ponemso las imagenes no visibles
_root.pron._visible = false;
_root.maspron._visible = false;
_root.koala._visible = false;
//Cogemos las webcam
weedcam = Camera.get();
//Le decimos donde tiene que dibujarla
_root.mcVideo.vid.attachVideo (weedcam );
//Creamos un nuevo bitmapData, indispensable para usar el getPixel
zona = new flash.display.BitmapData( 320, 240 );
//Lo guardamos en una variable
imagen = _root.mcVideo;
//LLamamos a la funcion chula unas 30 veces por segundo
setInterval(accion,33);
Sencillito no?
Camino 2 : Usar FAMES + Flash 7
Abrimos Eclipse, creamos un nuevo proyecto y una clase que llamaremos videoMotion copiamos este texto
Código :
//Iniciamos la clase
class videoMotion{
//Variables que utilizaremos
static var weedcam:Camera;
static var zona;
static var imagen:Video;
static var pron,maspron,koala:MovieClip;
//La función que detecta si pulsamos o no
static function accion()
{
//""Dibujamos"" la imagen de la webcam en el bitmapData
//Funciona con MC o dibujando a mano, ver la referencia al respecto
//para más información
zona.draw( imagen );
//Estos 3 son iguales, detectan si un pixel es claro o no
// este valor 16777215 es el que toman antes de que se inicialice la cámara así evitamos que aparezcan pulsados al principio
if(zona.getPixel(10,10)>9000000 && zona.getPixel(10,10)!=16777215) {
_root.pron._visible = true;
_root.maspron._visible = false;
_root.koala._visible = false;
};
if(zona.getPixel(310,10)>9000000 && zona.getPixel(310,10)!=16777215) {
_root.pron._visible = false;
_root.maspron._visible = false;
_root.koala._visible = true;
};
if(zona.getPixel(160,10)>9000000 && zona.getPixel(160,10)!=16777215) {
_root.pron._visible = false;
_root.maspron._visible = true;
_root.koala._visible = false;
};
}
//Punto de entrada de la aplicación
public static function main() {
//Ponemso las imagenes no visibles
_root.pron._visible = false;
_root.maspron._visible = false;
_root.koala._visible = false;
//Cogemos las webcam
weedcam = Camera.get();
//Le decimos donde tiene que dibujarla
_root.mcVideo.vid.attachVideo (weedcam );
//Creamos un nuevo bitmapData, indispensable para usar el getPixel
zona = new flash.display.BitmapData( 320, 240 );
//Lo guardamos en una variable
imagen = _root.mcVideo;
//LLamamos a la funcion chula unas 30 veces por segundo
setInterval(videoMotion.accion,33);
};
}
El código es el mismo en ambos casos, salvando excepciones como meterlo dentro de una clase y demás para que vaya bien con FAMES.
Un nuevo archivo.flashout, para no volver a explicarlo, vean este tutorial que aquí se explica como hacerlo, selecionamos la clase y el SWF que exporto Flash.
Publicar en Flash 8 Si has escogido el camino de usar Flash8 puedes saltarte este paso,si no sigue leyendo. MTASC - nuestro compilador favorito - viene con las nuevas clases de Flash, por lo que no tendremos que buscarlas por ahí ni importarlas ni nada parecido.""Supuestamente"" añadiendo el parámetro adicional "-version 8" al compilador desde el .flashout debería de exportar en formato de Flash8, a mi como esta manera no me funciona, me bajé un programa bien salaó que te convierte un swf7 a swf8 funciona a las mil maravillas y va incluido en los archivos del tutorial. Recuerden que FAMES compila "encima" -a menos que se indique que cree un nuevo archivo- por lo que una vez pasado el SWF a la versión 8 ya no habrá falta de hacerlo más veces.
Resultado final Recuerden, fondo oscuro, pueden apagar las luces y usar un móvil/linterna como punto de luz, ingénienselas!! ahora, posen la pequeña luz como si fuera un dedo sobre cada una de las frases de arriba, como si fuera un boton
Publicamos, aplicamos el programa si no nos funciona lo de "-version 8" y Voilá!Ahi tenemos una de las nuevas funcionalidades de Flash 8, que sin duda nos dará mucho juego. Desde emular la conocida EyeToy, detección más exacta de movimientos en la cámara, incluso para reconocer siluetas de objetos, menus a través de la imagen,...
Advertencia para los que intenten el ejemplo Necesitan el cuarto en ABSOLUTA PENUMBRA ... y aparte de eso, una luz lo bastante grande para abarcar el bloque completo de alguno de los 3 "botones de texto sensibles a la luz"
Una luz de un telefono celular o una pantalla de un PDA funcionaria Por:Freddie
No pues bastante bueno el experimento , y si como dice Freddie k onda con las fuentes??? Por:choco
va esta genial pero como identificamos objetos?? y caras?? alguien se apunta a intentar reconocer a un objeto o un usuario o algo??? si alguien se pica os dejo una url de las q he estado mirando..
Bueno, alteré un poco el código para que ahora detecte si un pixel cambia de color (se mueve) o no, en vez de de qué color son los pixeles.
Código :
//Variables que utilizaremos
var weedcam:Camera;
var zona;
var imagen:Video;
var pron, maspron, koala:MovieClip;
var px1, d1, px2, d2, px2, d3:Number;
/*Esta variable indica cuanto cambio de color ha de detectarse para activar el botón.
Dependerá de muchos factores, como el color de los muebles*/
sensibilidad = 1400000;
//La función que detecta si pulsamos o no
function accion(sens) {
//""Dibujamos"" la imagen de la webcam en el bitmapData
//Funciona con MC o dibujando a mano, ver la referencia al respecto
//paramas información
zona.draw(imagen);
/*hallamos la diferencia de los valores de los colores de los pixeles con los que tenían en
la toma anterior*/
d1 = Math.abs(px1-zona.getPixel(10, 10));
d2 = Math.abs(px2-zona.getPixel(310, 10));
d3 = Math.abs(px3-zona.getPixel(160, 10));
/*Estos 3 son iguales, detectan si el color de un pixel ha variado o no y si lo ha hecho,
ponen la imagen la primera.*/
if (d1>sens) {
_root.pron.swapDepths(_root.getNextHighestDepth());
}
if (d2>sens) {
trace(d2);
_root.koala.swapDepths(_root.getNextHighestDepth());
}
if (d3>sens) {
_root.maspron.swapDepths(_root.getNextHighestDepth());
}
/*refrescamos los valores de los pixeles "activos", para luego restarlos de los que serán
los valores actuales en la siguiente toma*/
px1 = zona.getPixel(10, 10);
px2 = zona.getPixel(310, 10);
px3 = zona.getPixel(160, 10);
}
weedcam = Camera.get();
//Le decimos donde tiene que dibujarla
_root.mcVideo.vid.attachVideo(weedcam);
//Creamos un nuevo bitmapData, indispensable para usar el getPixel
zona = new flash.display.BitmapData(320, 240);
//Lo guardamos en una variable
imagen = _root.mcVideo;
//LLamamos a la funcion chula unas 30 veces por segundo
setInterval(accion, 33, sensibilidad);
Así eliminamos la condición de que hay que estar en penumbra Así es como quedaría (recuerden no permitir la conexion a la webcam en el ejemplo de arriba):
pd:
Freddie® :
y aparte de eso, una luz lo bastante grande para abarcar el bloque completo de alguno de los 3 "botones de texto sensibles a la luz"
O mucho me equivoco o la extensión de los botones es un 1x1 pixel [/flash] Por:Zah
Perdon la tardanza, y porcierto gracias Zah, porque no habia visto esto. Por:lmenendez
no presise la penumbra y es pleno mediodia. solo acerque la camara lo suficiente y selecciono con la frente . Mi pelo negro carbo hace el resto. Por:Juampe_blog
este archivo es brutal. Muchas gracias a ICEMAN por este magnifico tutorial.
Yo, despues de aplicar la modificacion propuesta por zah tampoco necesito tener el cuarto oscuro para que me funcione.
Pero ahora se me plantean algunas dudas.
¿Como puedo hacerlo para que el àrea sensible tenga la forma de un cuadrado o un circulo?
¿Se puede hacer que con el movimiento de la mano se arrastre un objeto por la pantalla?
Gracias Por:Mamaun
Mamaun :
¿Como puedo hacerlo para que el àrea sensible tenga la forma de un cuadrado o un circulo?
Pon varios puntos, que formen un cuadrado y que se ejecute la acción si ha habido movimiento en todos.
Mamaun :
¿Se puede hacer que con el movimiento de la mano se arrastre un objeto por la pantalla?
Poderse se puede, pero es tremendamente difícil, y no creo que muy preciso. Se me ocurre que tendrías que modelar un vector con los datos de los movimientos de los puntos. Quizá ICEM4N sepa mejor cómo hacerlo. Por:Zah
Bueno, poderse se puede, pero creo qeu tumbaría al player de las cuentas que hay que hacer.
La versión "liviana" sería usar un guante, de forma que la mano (solo la mano) generase movimiento, ahí si sería posible más o menos
La otra opción sería detectar todo el movimiento del brazo, detectar su forma y escoger sólo la mano, debería saber si el brazo está recto, doblado, en definitiva, parametrizarlo... Por:_CONEJO
¿Pero entonces, como han hecho esto? Los tres ejemplos distan mucho de funcionar a la perfección (de hecho el ruido de mi cam mueve las cosas más que yo), pero al menos no se relentiza el player.A no ser que sea tan importante estar hecho en Director, supongo que en cualquier programa habrá que hacer los mismos cálculos. Por:Zah
El shockwave Player NO es el Flash Player... de hecho esos juegos estaban MUCHO antes de Flash 8 y las funciones getPixel... no conozco director, pero imagino que hará uso de toda su tecnología (en director puedes manejar 3D por ejemplo) Por:_CONEJO
¿y qué me dices de los ejemplos con webcam de aquí? ¿Como se hace, por ejemplo eso de las llamas sin hacer un for anidado? Por:Zah
http://www.theninjabunny.com/fl8/video.html <-- con un for anidado, es como todo, hay algunas resoluciones (bajas) que pueden ser buenas y más si añades ese efecto de llamas que realmente no sabes donde lo aplica (exactamente).
Esas son algunas pruebas que hice hace tiempo. Es C00L si consigues que las palmas tengan una tonalidad diferente al brazo, lo cual es relativamente "sencillo" jugando un poco con la luz. En el peor de los casos, el cliente no lo hará, por lo que se le marcará todo el brazo, ¿Qué hacer en estos casos?, bueno, si estás jugando al arkanoid, pues podrías tomar el punto donde el movimiento haya sido más brusco, podrías coger el valor de la rejilla "más alto" es decir, empiezas con el for a mirar puntos desde arriba abajo, cuando detectas movimiento paras, o podrías, recoger la forma del brazo, parametrizarla eliminar el brazo y quedarte con la mano, lo que posiblemente tumbe al player con las cuentas.
Todo se puede optimizar, por ejemplo NO mirando los puntos centrales o donde sepas que no habrá movimiento o no te interese. Quizás con el FP9 se consiga mejor rendimiento. Por:_CONEJO
De hechoSÍ puede hacerse sin un bucle anidado. Con este ejemplo y unas cuántas horas (lo había visto por primera vez hace unos cuántos meses, pero mi adversión hacia el inglés me había hecho olvidarlo por completo) se puede detectar el movimiento basante mejor. Usando el filtro de "difference" se puede conseguir la "resta" entre el bitMap ahora y el bitMap "antes" quedando sólo los píxeles que han cambiado. Aplicando el método threshold (que no se muy bien qué hace cada parámetro) se pueden seleccionar los píxeles negros y volverlos transparentes. Una vez allí se puede aplicar el comando BitMapData.hitTestm con el punto de las coordenadas de, por ejemplo un MovieClip. Copiando de ese ejemplo y de la ayuda de flash he hecho esto (lo haré más boito cuando tenga tiempo)
A ver, aquí las fuentes y aquí el swf Lo que no sé es si se puede hacer algo para quitar el ruido de la cámara... PD: No hay nada como no ir al colegio para aprender cosas XDXD[/flash] Por:Zah
Pues yo por mas que intento hacer algo parecido no me deja.. estoy intentando usar la función threshold() para detectar los pixels de color en una imagen propia que no tengo en la librería del fla ni viene de la web cam, pero por mas que intento meterlo en un bitmapData por medio de draw() no hay forma de que la función me deje hacer nada con threshold.. alguien sabe por que es??o me va a tocar recorrerme todos los pixels haciendo la comprobación a mano?? -_-
loader = new MovieClipLoader(); loader.addListener(this); loader.loadClip("file:///C|/image2.jpg", holder_mc); //esta es la imagen q uso
function onLoadInit() { myBitmap = new BitmapData(holder_mc._width, holder_mc._height, true, 0×00FFFFFF); myBitmap.draw(holder_mc); myBitmap.threshold(holder_mc, new Rectangle(0, 0, 100, 40), new Point(0, 0), “==”, 0×00CCCCCC, 0×000000FF, 0×0000FF00, false); } Por:antares_blog
Hola a todos, yo la verdad no se de flash, lo manejo muy poco, pero necesito hacer un flash que me capture la imagen que me sale en la webcam como los ejemplos de arriba, pero a la vez me deje tomar la foto y yo poder capturar esa imagen Por:SNEIDER
Una de las prácticas de la asignatura Realidad Virtual, de los estudios del Graduado Multimedia de la Universitat Oberta de Catalunya, se basa en este trabajo.
Necesito saber como peudo incorporar la imagen de webcam a mi swf y poderla agrandar sin que esta se vea pixelada Por:Dark_bta_blog
como guardo la imagen de mi webcam a una base de datos mysql Por:abrahan_blog
Solo una pregunta !! eso no sirve para que atraves de tu pagina te vean los usuario verdad!! porque lo puse en mi pagina y las personas en ves de verme se ven ellos !!!! que podria hacer al respecto!!! gracias !! Por:Pololito_blog
Hola gente sabia, me gustaría saber si es posible armar un sistema de este tipo para utilizarlo en una pista de autitos radios controlado e identificar por medio de un color o algo cuando pasa cada autito y utilizarlo como contador de vueltas y demás....
si me pueden ayudar les estaría muyyyyy agradecido, dado que por no tener todavía un sistema que nos cuente las vueltas el juego no deja de ser re aburrido...
saludos para toda esta gente linda.
kokito Por:gustavo ( kokito)_blog
hola esta muy bueno, pero quisiera saber como puedo gurdar es imagen en una base de datos, es decir tomar un foto. culquier yuda le grdesco si me escriben a mi correo abrahanmaximal@hotmil.com gracias Por:abrahan_blog
hice todo al pie de la letra, es mas como solo me interesa capturar la camara, le saque lo de las 3 imagenes.... soy nuevo en flash, se programacion, pero cuando lo ejecuto me muestra el reproductor solo, ni si quiera el cartel de permitir o denegar.... ayuda conejo o quien sea Por:german_blog
Necesito ayuda con flash.. tomar una foto con la camara y mandarla a la base de datos con php desde el mismo flash.. si alguien sabe como hacerlo u orientarme de como podria hacerlo. se lo agradeceria mucho...
Saludos!!! Por:Jose G. Hernandez-blog
Hola,
soy bastante nuevo en esto de flash y he llegado hasta aquí. Sé que este artículo está desde hace mucho tiempo y no sé cuándo fue la última alcutalización. tampoco sé, por el mismo motivo si alguien va a leer esto, pero yo lo intento...
estoy haciendo un "experimento" que consta de dos partes. en relacción a este artículo me referiré sólo a la segunda. Necesito seleccionar y mover unos dibujos (o gráficos, o imágenes) que están proyectadas sobre una pared. Es decir, tengo una aplicación flash en la cual hay diversos gráficos y ésto se proyecta sobre una pared o pantalla. Con algún sistema de detección de movimiento (un led en la mano, por ejemplo), quiero seleccionar y mover ese gráfico.
Por lo que he leído hasta aquí, más o menos se puede hacer, sobre todo teniendo en cuenta que todo el rato se habla de flash player 8 y ya vamos por el 10 (o casi).
Alquien me puede echar una mano? o indicarme dónde puedo pedir ayuda?
gracias de antemano!! Por:emil-blog
¿como te das cuenta que algo se mueve?
¿todos los movimientos son iguales?
¿crees que todos los movimientos son iguales? Por:mayte-blog
Que tal el activar la camarita y hacer videos, fotos y etc etc esta muy claro.. pero alguien ha intentado desactivar la camara, es decir, desocupar el recurso sin tener que bajar la aplicacion???? gracias por sus sugerencias... Por:difercm
Hola Como estan todos despuesde leerlos un rato me entro una duda, me gustaria saver como puedo capturar esa imagen que se ve con un boton desde el mismo flas y poderla almacenar en una carpeta ya sea local o si es remota aun mejor, me explico la idea es montar esta aplicacion en un servidor web y cuando capture Foto la pueda guardar en formato jpg y se guarde en el servidor si es posible, si no pues en el mismo equipo gracias. Por:ddarthp-blog
Se podria hacer un boton para captura de la imagen que esta apareciendo en el momento? Si no me explico bien les dejo esto: http://www.seenly.com/seenly.php
Si alguien sabe que me ayude porfa lo necesito Por:ksd-ksty-blog
Hola amigos. utilizando la webcam en flash. ¿Alguien sabe como puedo hacer un traqueo y remplazar el fondo por otra cosa. como por ejemplo una imagen? Por:Mauro_22-blog
muy buen codigo pero tengo una duda se podra hacer esto de la deteccion de formas pero en un lenguaje mas bajo como c++ visual studio 2008, si es posible me podrias mandar el codigo porfavor gracias por su ayuda