Controlando uma interface com flash + webcam

Controlando uma interface com flash + webcam

Hoje estão surgindo muitas interfaces utilizando dispositivos de manipulação diferentes de teclado e mouse. É possível e muito fácil utilizar o flash para acionar eventos utilizando uma webcam comum ou microfone. Explorei esta técnica em meu TCC e vou disponibilizar aqui umas instruções básicas desta captura de movimento para identificação do nível de intensidade da movimentação e posicionamento.

Conceito

Não é preciso ter uma webcam caríssima ou ser um ninja em AS para desenvolver um aplicativo simples. Imagine o que é possível fazer no flash com o evento do clique do mouse e entenda que a identificação de movimento em um determinado ponto da interface pode executar a mesma ação. O que temos que fazer é identificar este movimento. No caso de controle de interface utilzando o microfone também, basta identificar o nível de atividade do microfone e definir um evento condicionado a um nível de atividade.

O conceito básico é mapear em um segundo cada informação de pixel da tela e no próximo segundo mapear novamente e comparar com o anterior. Se no novo mapa de pixels algum deles estiver com uma cor diferente do anterior, identificamos um movimento naquele ponto.Exemplo de mapeamento

É possível também definir uma tolerância de forma bem simples. Posso especificar à minha função que apenas deve-se entender a alteração como um movimento caso seja identificada a mudança de cor na matriz de pixels determinado número de vezes, por exemplo, se compar três vezes e sempre existir diferença, é um movimento. Caso contrário, nada a fazer.
Identificação de movimento

Capturando a câmera

  1. Insira no palco um objeto de vídeo e instancie-o como quiser. No exemplo instanciei como “meu_video”.
  2. declare o objeto criado e uma variável para a câmera como no código abaixo.
  3. Vincule a câmera ao objeto usando o attachVideo.
1
2
3
var meu_video:Video;
var cam:Camera = Camera.get();
meu_video.attachVideo(cam);

Teste e será possível visualizar a imagem da câmera no objeto.

Imagem da webcam capturada no flash.

Download do FLA

Identificando a intensidade de movimento

Para o objeto câmera existe um evento nativo do flash chamada onActivity que serve justamente para a detecção de atividade (movimento) do objeto. Vou utilizar também o activityLevel, propriedade que retorna um valor numérico para a intensidade de movimentação identificada no objeto.

Crie uma caixa de texto e no atributo “var” insira um nome de variável. No exemplo inseri “nivelAtividade”:

1
2
3
4
5
6
7
8
var meu_video:Video;
var cam:Camera = Camera.get();
meu_video.attachVideo(cam);
 
cam.onActivity = function(isActive:Boolean) {
  trace("algo se mexeu");
  _root.nivelAtividade = cam.activityLevel;
};

Teste e será possível visualizar o nível de intensidade do movimento inserido na caixa de texto. Podemos acionar um evento qualquer condicionado a estes valores dizendo, por exemplo, que caso a intensidade seja maior do que 50, deve-se avançar um frame ou acionar um evento qualquer. No caso do meu TCC na última fase era necessário que o usuário se movimentasse com nível 100 e utilizasse o mesmo nível de atividade no microfone, gritando, para avançar aos créditos finais.

Identificação da intensidade de movimentação da câmera.

Download do FLA

Identificando o evento de movimentação

Então vamos ao que interessa… crie um movie clip, duplique-o em três e instancie-os como bolinha1, bolinha2 e bolinha3 respectivamente e faça uma animação qualquer dentro dos MC, com um stop(); no primeiro frame.

O que faremos então:

  1. Identificaremos as propriedades de todos os objetos e as guardaremos em variáveis;
  2. Encontraremos a proporção da imagem capturada VS recipiente de exibição;
  3. Executaremos o tempo todo uma função para compararmos um mapa inicial com um final;
  4. Criaremos condições para os eventos de comparação positivos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
var meu_video:Video; //declara o objeto video
var cam:Camera = Camera.get(); //declara o obj camera
meu_video.attachVideo(cam); //atribui a imagem da camera ao objeto
 
cam.onActivity = function(isActive:Boolean) { //quando houver atividade, executar...
  trace("algo se mexeu"); //output
  _root.nivelAtividade = cam.activityLevel; //atualizar texto 
};
 
import flash.display.BitmapData; //importar a classe BitmapData
 
var videoX:Number = meu_video._x; //identificacao das coordenadas
var videoY:Number = meu_video._y;
var videoW:Number = meu_video._width;
var videoH:Number = meu_video._height;
 
var proporcao:Number = videoW/cam.width; //encontra a proporcao
 
var now = new BitmapData(cam.width, cam.height); //declara o mapa inicial
var before = new BitmapData(cam.width, cam.height); //declara o mapa de comparacao
 
function hitDetect() {
  //identifica as propriedades iniciais
    var bolinhaX:Number = (bolinha1._x-videoX)/proporcao
    var bolinhaY:Number =  (bolinha1._y-videoY)/proporcao
 
    var bolinha2X:Number = (bolinha2._x-videoX)/proporcao
    var bolinha2Y:Number =  (bolinha2._y-videoY)/proporcao
 
    var bolinha3X:Number = (bolinha3._x-videoX)/proporcao
    var bolinha3Y:Number =  (bolinha3._y-videoY)/proporcao
 
    now.draw(meu_video) //renderiza o "agora"
 
  //inicial
  var valNowBall1:Number=(now.getPixel(bolinhaX, bolinhaY) >> 16 & 0xFF);
  //comparacao
  var valBeforeBall1:Number=(before.getPixel(bolinhaX, bolinhaY) >> 16 & 0xFF);
 
  //inicial
  var valNowBall2:Number=(now.getPixel(bolinha2X, bolinha2Y) >> 16 & 0xFF);
  //comparacao
  var valBeforeBall2:Number=(before.getPixel(bolinha2X, bolinha2Y) >> 16 & 0xFF);
 
  //inicial
  var valNowBall3:Number=(now.getPixel(bolinha3X, bolinha3Y) >> 16 & 0xFF);
  //comparacao
  var valBeforeBall3:Number=(before.getPixel(bolinha3X, bolinha3Y) >> 16 & 0xFF);
 
  //condicoes para eventos
  //o valor "30" é a intensidade que eu defini. 
  //quanto menor este valor, maior a sensibilidade
  if (valNowBall1>valBeforeBall1+30 || valNowBall1<valBeforeBall1-30) {
    if (bolinha1._currentframe == 1)
    trace("bola 1");
    bolinha1.gotoAndPlay(2)
  }
 
	if (valNowBall2>valBeforeBall2+30 || valNowBall2<valBeforeBall2-30) {
		if (bolinha2._currentframe == 1)
			trace("bola 2");
			bolinha2.gotoAndPlay(2)
	}
 
	if (valNowBall3>valBeforeBall3+30 || valNowBall3<valBeforeBall3-30) {
		if (bolinha3._currentframe == 1)
			trace("bola 3");
			bolinha3.gotoAndPlay(2)
	}
 
	before.draw(meu_video) //compara a renderizacao anterior
}
 
//intervalo de repeticao da funcao
var intervalID:Number = setInterval(hitDetect, 20);

Veja o resultado:

Interação final: Acionando objetos com a webcam.

Download do FLA

Sobre o autor

Trabalho com desenvolvimento de layouts, desenvolvimento flash com Action Script semântico e facilidade de interação com linguagens de programação, desenvolvimento XHTML + CSS para estruturação, integração e possuo contatos com diversos programadores para trabalhos pessoais que necessitem de experiência maior com programação e interação com banco de dados. Tenho conhecimento em técnicas de otimização de sites (SEO), Acessibilidade, Usabilidade e Arquitetura da informação.