Artigo
Exibindo dados do kinect dentro do XNA usando a biblioteca OpenNI
Este artigo demonstra como usar a biblioteca OpenNI para exibir informações capturadas pelo kinect na tela de um jogo em XNA
Enviado por Rodrigo Ferreira em 12/1/2011 0:00:00

Exibindo dados do kinect dentro do XNA usando a biblioteca OpenNI

Este artigo demonstra como usar a biblioteca OpenNI para exibir informações capturadas pelo kinect na tela de um jogo em XNA.

Recentemente adquiri o sensor do Kinect, ja tinha ssistido muitos vídeos sobre projetos bem interessantes que estava sendo desenvolvidos com o Kinect, alguns bem próximos do filme "Minority Report". Enfim, achei interessante e comecei estudar um pouco mais sobre o assunto, me deparei com duas bibliotecas bem interessantes: a OpenNI criada pela PrimeSense, empresa que participou junto com a Microsoft do projeto do Kinect(o principal chip foi criado por eles) e a biblioteca NUIPlataform da CodeLaboratories. Ambas possuem suporte ao .Net, então estou testando as duas mas com foco no OpenNI.

Depois de brincar um pouco com o sensor, rodando diversos exemplos que foram criado ao redor do mundo, resolvi rodar o código dentro do XNA para ver como ficava, o resultado são dois projetos: o XnaSimpleRead e o XnaSimpleViewer. O primerio apenas exibe na tela um texto com as informações que estão sendo capturadaspelo sensor, já o segundo exibe a imagem capturada pelo sensor infravermelho Primeiramente vou mostrar o exemplo mais simples de leitura dos dados,fiquem a vontade para indicar melhorias, segue abaixo o artigo:

===========================================================================

XNA + Sensor Kinect

Este tutorial mostra os primeiros passos na configuração da biblioteca do OpenNI dentro do XNA(Plataforma de desenvolvimento de games da Microsoft) e a leitura dos dados do Kinect.

Exemplo 1: Leitura dos dados do Kinect

Este exemplo demonstra como fazer a leitura das informações proveniente do sensor do Kinect e exibir na tela do XNA. Considerando que você ja possui o XNA Game Studio 4.0 instalado e já sabe como criar um projeto do XNA WindowsGame?(4.0), vamos ao código:

  • 1 Passo - Fazer referência a dll do OpenNI

No "Solution Explorer" do seu projeto no Visual Studio, clique com o botão direito em "References" > "Add Reference". Na tela que abrir clique na aba "Browse" e procure pela dll do OpenNI.net (OpenNI.net.dll) e clique em "Ok". Veja imagem abaixo:

  • 2 Passo - Declarar o namespace

Para poder acessar os métodos do OpenNI.net declare o using xn. Veja:

   using Microsoft.Xna.Framework.Media;
   
using xn;
   
using System.Text;
  • 3 Passo - Crie uma classe que representará as linhas na tela

       public class LinhaTela
       
    {
           
    private string texto;
           
    public string Texto
           
    {
               
    get { return texto; }
               
    set { texto = value; }
           
    }

           
    private Vector2 posicao;
           
    public Vector2 Posicao
           
    {
               
    get { return posicao; }
               
    set { posicao = value; }
           
    }

           
    public LinhaTela(string _texto,Vector2 _posicao)
           
    {
               
    this.texto = _texto;
               
    this.Posicao = _posicao;
           
    }
       
    }

 

4 Passo - Declara as variáveis

 

        SpriteFont fonte; //fonte para poder escrever na tela
       
Context context;  //variáveis de controle do OpenNI
       
DepthGenerator depth;
       
MapOutputMode mapMode;
       
DepthMetaData depthMD;
       
List<LinhaTela> linhas; //lista de linhas que serão exibidas
       
float posY;
       
string result;

 

5 Passo - Escrever o código de inicialização dos objetos

 

        protected override void Initialize()
       
{
           
// TODO: Add your initialization logic here
           
//Kinect
           
string SAMPLE_XML_FILE = "C:/SamplesConfig.xml";
            context
= new Context(SAMPLE_XML_FILE);

            depth
= context.FindExistingNode(NodeType.Depth) as DepthGenerator;
           
if (depth == null)
           
{
               
Console.WriteLine("Sample must have a depth generator!");
               
return;
           
}

            posY
= 125; //Posição inicial na tela onde a primeira linha com a leitura
                          das informa
ções irá aparecer.

            mapMode
= depth.GetMapOutputMode();
            depthMD
= new DepthMetaData();

            linhas
= new List<LinhaTela>(); //Criamos a lista
           
base.Initialize();
       
}

Inicialmente carregamos o arquivo de configuração do OpenNI o SamplesConfig?.xml. Instanciamos o objeto context, passando como parâmetro o xml de configuração.

 

6 Passo - Carregar a fonte no método LoadContent?

 

        protected override void LoadContent()
       
{
           
// Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch
= new SpriteBatch(GraphicsDevice);

           
// TODO: use this.Content to load your game content here
            fonte
= Content.Load<SpriteFont>(@"Arial");
       
}

Obs: este arquivo esta presente na pasta junto com o projeto do XNA na área de downloads.

 

7 Passo - Adicionar o código abaixo no método Update

 

O código abaixo captura as informações provenientes do sensor do Kinect(depth.GetMetaData?) e preenche a lista com as informações.

            // Allows the game to exit
           
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
               
this.Exit();

           
// TODO: Add your update logic here
            context
.WaitNoneUpdateAll();
            depth
.GetMetaData(depthMD);

           
if (linhas.Count >= 6)
           
{
                linhas
.RemoveAt(0);
           
}

           
StringBuilder linhaDados = new StringBuilder();
            linhaDados
.Append("Frame ");
            linhaDados
.Append(depthMD.FrameID.ToString());
            linhaDados
.Append(" - Middle point is: ");
            linhaDados
.Append(depthMD[(int)mapMode.nXRes / 2, (int)mapMode.nYRes / 2]);

            linhas
.Add(new LinhaTela(linhaDados.ToString(),new Vector2(10,posY)));

           
foreach(LinhaTela lin in linhas)
           
{
                lin
.Posicao = new Vector2(lin.Posicao.X, lin.Posicao.Y - 20);
           
}        
           
base.Update(gameTime);

 

8 Passo - Escrever na tela a lista com as informações capturadas.

 

        protected override void Draw(GameTime gameTime)
       
{
           
GraphicsDevice.Clear(Color.CornflowerBlue);

           
// TODO: Add your drawing code here
            spriteBatch
.Begin();
           
for (int i = 0; i < linhas.Count;i++)
           
{
               spriteBatch
.DrawString(fonte, "[" + i + "]: " +                                                                       linhas[i].Texto,linhas[i].Posicao, Color.White); //escrevendo na tela              
           
}
            spriteBatch
.End();
           
base.Draw(gameTime);
       
}

Observem que pouquíssimas alterações foram necessárias para fazer o OpenNI funcionar no XNA, já era de se esperar ja que o código é em c#. A única coisa que precisou ser criada foi a lista com os dados para serem exibidos. 

Uma alteração que foi feita em relação ao sample em C# que vem com o código do OpenNI foi a chamada do método context.WaitNoneUpdateAll?() que antes era context.WaitOneUpdateAll?(depth). O motivo é que pela documentação do OpenNI, este último método espera um determinado nó receber novos dados para atualizar todos os outros, e isto estava causando uma lentidão quando rodei o projeto em XNA. Leiam aqui um trecho da documentação:

Documentação do OpenNI explicando os métodos.

"Reading Data Generators usually constantly receive new data. However, the application might still use the old (previous) data. For this reason, any generator should keep the new data internally until explicitly asked to update its data to the new one. This request is called Update Data. OpenNI gives the application the option to wait for new data to be available, and then update it using xnWaitAndUpdateData() (xn::Generator::WaitAndUpdateData?()). In some cases, the application holds more than one node, and it usually wants all the nodes to be updated. OpenNI supplies several functions to do so, depending on what the application wants to wait for before updating takes place:

xnWaitAnyUpdateAll() (xn::Context::WaitAnyUpdateAll?()) - Waits for any node to have new data. Once new data is available from any node, all nodes are updated. xnWaitOneUpdateAll() (xn::Context::WaitOneUpdateAll?()) - Waits for a specific node to have new data. Once new data is available from this node, all nodes are updated. This is especially useful when having several nodes producing data, but only one determines the progress of the application. xnWaitNoneUpdateAll() (xn::Context::WaitNoneUpdateAll?()) - Does not wait for anything. All nodes are updated. xnWaitAndUpdateAll() (xn::Context::WaitAndUpdateAll?()) - Waits for all nodes to have new data available, and then updates them. Unless needing to update only a specific node, it is highly advised to use one of the UpdateAll? functions. In addition for updating all the nodes they have some more benefits:

If nodes are dependend in one another, it promises the needed node will be updated before the needing node. If playing a recording, it reads data from the recording until the condition is met. If a recorder exists, it records the data from all nodes added to it (without the need to call xnRecord())."

 

Dificuldades Encontradas

 

Problemas para rodar o projeto do XNA 4.0 no meu notebook Um dos problemas que tive for quando tentei rodar meu projeto do XnaSimpleRead? pela primeira vez no notebook, me deparei com o seguinte erro:

"No suitable graphics card found Could not find a Direct3D device that supports the XNA Framework HiDef? profile.."

para contornar este problema cliquei com o botão direito do mouse no meu projeto no "Solution Explorer" > Properties(Propriedades) > XNA Game Studio. Na seção Game Profile marquei a opção: "Use Reach to acess..." ao invés de "Use HiDef?".


Arquivos Anexados
Download: XnaSimpleRead.rar Download
Sobre o Autor

rodrigorf
Rodrigo Ferreira
Não Definido

Clique para avaliar:

Comentários
" vlwww pela dica Mopaz, to pensando em arranjar um xbox pra fazer alguns testes.Quem sabe em breve o pessoal não libere um versão compatível ne? :). jalf tenho interesse sim em trocar umas idéias, ainda to engatinhando com o Kinect então toda ajuda é bem vinda. "
Enviado por Rodrigo R. Ferreira em 13/1/2011 21:48:53:
 
" Gostei do projeto Kinmob. Pode me mandar um email em jalf@sharpgames.net para trocarmos umas idéias ?"
Enviado por Jose Antonio Farias em 13/1/2011 21:36:22:
 
" Pelo XBox não funciona mesmo, já que as APIS do OpenNI não são em .NET puro. No mais excelente artigo..parabéns!"
Enviado por Mopaz em 13/1/2011 19:46:24:
 
" Caso queira saber mais entra no site do Projeto Kinmob: http://code.google.com/p/kinmob/. Estamos sempre atualizando, essa semana ainda coloco mais exemplos."
Enviado por Rodrigo R. Ferreira em 13/1/2011 10:32:58:
 
" Na verdade não cheguei a executar no XNA 3.0, mas acredito que não terá problema nenhum pois não utilizei nenhuma estrutura específica da versão 4.0 e o OpenNI não irá fazer nenhuma exigência deste tipo. Mas obrigado por lembrar não tinha pensado nisso, vo fazer o teste e alterar o post para o pessoal não achar que precisar ser 4.0. Com relação ao teste do XBox não pude realiza-lo pois não tenho o console, comprei apenas o sensor. Caso você possa realizar o teste e criar um post acho que seria bem interessante. :) vlwwwwww"
Enviado por Rodrigo R. Ferreira em 13/1/2011 8:46:50:
 
" Olá rodrigo, parabens pelo trabalho. Gostaria de pergunta uma coisa. você testou o codigo usando Kinect no PC ou no XBOX? outra pergunta, projetos desenvolvidos em XNA 3.0 não conseguiram utilizar a biblioteca OpenNI?"
Enviado por elton sarmanho em 13/1/2011 7:12:40:
 
" Olá rodrigo, parabens pelo trabalho. Gostaria de pergunta uma coisa. você testou o codigo usando Kinect no PC ou no XBOX? outra pergunta, projetos desenvolvidos em XNA 3.0 não conseguiram utilizar a biblioteca OpenNI?"
Enviado por elton sarmanho em 13/1/2011 7:11:21:
 

Adicione seu Comentário  Voltar
Translator
Logos do XBox 360, XNA e Games For Windows
Copyright 2006-2012 por SharpgamesPolítica de Privacidade  |  Termos de Uso