• Nenhum resultado encontrado

Desenvolvimento de Aplicações para Kinect SDK

N/A
N/A
Protected

Academic year: 2021

Share "Desenvolvimento de Aplicações para Kinect SDK"

Copied!
20
0
0

Texto

(1)

Capítulo

2

Desenvolvimento de Aplicações para Kinect SDK

Luciano Silva, Ismar Frango Silveira

Abstract

These notes correspond to the mini-course entitled Developing Applications for Kinect SDK, presented at the Workshop on Virtual and Augmented Reality (WRVA'2011) November/2011 held in the city of Uberaba (MG). The text shows the main features of Kinect hardware, its principle of identifying movements, the

structure of Kinect SDK and several programming examples in C # using the

Microsoft Silverlight and Microsoft XNA frameworks. Resumo

(2)

1.1. Introdução

Oficialmente, o dispositivo Kinect chegou ao mercado consumidor no final de 2010 e, desde então, tem recebido muita atenção tanto do ponto de vista comercial quanto acadêmico. Na linha comercial, diversos jogos que exploram o corpo humano como sensor têm sido lançados nos mais diferentes gêneros: dança, esporte, simulação,

serious games, dentre outros. Do ponto de vista acadêmico, o dispositivo Kinect

disponibiliza uma nova alternativa para interfaces baseadas em gestos, podendo ser aplicado em diferentes contextos como Realidade Virtual, Realidade Aumentada, Visão Computacional, Interação Não-Convencional, dentre outros. Aliado ao recém-lançado Kinect SDK, é possível a prototipação rápida de diversas aplicações em várias linguagens como Java, C++, C# e Visual Basic.

Dentro do contexto acadêmico, o objetivo destas notas é apresentar o dispositivo, desde a sua estrutura de hardware até exemplos de programação em linguagens como C# (via os frameworks Microsoft Silverlight e Microsoft XNA) e Visual Basic. Devido ao lançamento recente tanto do dispositivo quanto do SDK, existem poucas fontes bibliográficas para suportar um aprendizado sistemático desta alternativa de interface não-convencional. Assim, estas notas também têm o objetivo de disponibilizar uma sequência sistemática para pesquisadores e alunos interessados no uso da arquitetura Kinect.

As notas estão organizadas da seguinte forma:

 a Seção 1.2 apresenta os detalhes fundamentais do hardware do dispositivo Kinect;

 a Seção 1.3 mostra os detalhes fundamentais de funcionamento deste dispositivo;

 a Seção 1.4 apresenta a organização do Kinect SDK, com evidência para os componentes essenciais para as aplicações;

 a Seção 1.5 apresenta uma sugestão de ambiente adequada para desenvolvimento de aplicações sob o Kinect SDK;

 a Seção 1.6 apresenta um exemplo de código completo para utilização do Kinect SDK com Silverlight e C#;

 A Seção 1.7 apresenta um exemplo de código completo para utilização do Kinect SDK com Silverlight e Visual Basic;

 A Seção 1.8 apresenta um exemplo de código completo para utilização do Kinect SDK com XNA e C#;

 Finalmente, a Seção 1.8 apresenta os comentários finais destas notas.

(3)

1.2. Hardware Kinect

O hardware do dispositivo Kinect é formado por uma cápsula quase retangular, conforme mostra a Figura 1, e que pode ser interligada a um PC ou a um console Xbox através de um cabo USB.

Figura 1: Hardware do dispositivo Kinect.

Fonte: adaptado de www.microsoft.com/xbox

Na parte frontal do dispositivo, existem duas câmeras (uma RGB e outra para infra-vermelho(IV)) e um projetor de infravermelho, além de um led indicador de funcionamento. O par PROJETOR IV-CÂMERA IV é o principal componente para detecção de profundidade e movimento. As especificações destas duas câmeras são mostradas na tabela abaixo:

Tabela 1: Especificações das câmeras do dispositivo Kinect. Câmera Resolução (pixels) Taxa de Amostragem

RGB 640 x 480 30 fps

IV 320 x 240 30 fps

(4)

A base motorizada é controlada por um pequeno motor de passo, mostrado na Figura 2, cuja angulação máxima é denotada pelo número inteiro +27 e, a angulação mínima, pelo número inteiro -27.

Figura 2: Motor de passos do dispositivo Kinect.

Fonte: adaptado de www.microsoft.com/xbox

Toda a parte lógico-digital do Kinect é encapsulada em duas placas, mostradas na Figura 3, que contém uma série de circuitos integrados como, por exemplo, o Prime Sense, responsável por grande parte das operações envolvendo imagens e áudio dentro do dispositivo Kinect.

Figura 3: Placas de circuitos integrados do dispositivo Kinect.

(5)

As duas placas de circuitos integrados estão ligadas diretamente a todos os componentes da parte frontal do Kinect (câmeras, projetor de IV, led indicador de funcionamento), além do array de áudio e o motor de movimentação do dispositivo. O aspecto desta interligação pode ser observado na Figura 4:

Figura 4: Interligação entre o sistema de câmeras e as placas do dispositivo Kinect.

Fonte: www.microsoft.com/xbox

O esquema básico de interligação entre câmeras, projetor de IV e array de áudio é mostrado na Figura 5:

Figura 5: Esquema de interligação entre os componentes do dispositivo Kinect.

(6)

O núcleo central do esquema de interligação mostrado na figura da página anterior é o processador Prime Sense PS1080-A1, desenvolvido pela empresa Prime Sense (www.primesense.com). Inclusive, conforme mostrado na Figura 6, a empresa Prime Sense já possuia o protótipo de um dispositivo que utilizava o Prime Sense PS1080-A1, de forma muito mais reduzida que o Kinect. O Kinect tomou a forma atual após uma parceria entre as empresas Prime Sense e Microsoft para o desenvolvimento de um projeto chamado Natal, nome inicial do Kinect.

Figura 6: Processador PrimeSense e a forma original do produto pré-Kinect.

Fonte: www.primesense.com

(7)

1.3 Mecanismo de Funcionamento do Kinect

O mecanismo de reconhecimento de padrões em imagens segue procedimentos bem conhecidos em Visão Computacional. Para a geração da imagem de profundidade, a parte mais essencial do equipamento, este esquema a projeção de um padrão luminoso na frequência de infra-vermelho e posterior medida de distância, conforme ilustra a Figura 7:

Figura 7: Diagrama esquemático de funcionamento do dispositivo Kinect.

Fonte: www.primesense.com

(8)

O luz estruturada projetada pelo Kinect segue um padrão de 9 quadrados contendo vários pontos aleatório e um ponto de brilho diferenciado no centro de cada quadrado, conforme mostrado na Figura 8:

(a) nove quadrados projetados (b) padrões aleatórios em torno do ponto central de cada quadrado

Figura 8: Luz estruturada projetada pelo dispositivo Kinect.

Fonte: www.primesense.com

Quando esta luz é projetada sobre os objetos da cena a ser reconhecida, a imagem capturada pela câmera IV aparece como mostrado na Figura 9:

Figura 9: Projeção da luz infra-vermelha nos objetos de uma cena.

(9)

Fonte: www.primesense.com

Uma estimativa da posição (x,y,z) dos pontos projetados pelo Kinect é dado pela fórmula da Figura 10. Esta estimativa é obtida através de ângulos de projeção do ponto e de observação pela câmera:

Figura 10: Estimativa de coordenadas (x,y,z) de pontos projetados.

Fonte: www.primesense.com

A partir dos mapas de profundidade gerados pelo processador PS1080, é efetuado um procedimento de reconhecimento de padrões para identificação dos clusters sobre um corpo diante das câmeras do Kinect para obtenção dos pontos de um sistema esquelético (bonés e articulações) de referência. Dois exemplos destes clusters são mostrados na Figura 11:

Figura 11: Mapas de profundidade, clusters e vinculação com esqueleto de referência.

(10)

O esqueleto de referência do Kinect é mostrado na Figura 12, onde os nomes das articulações serão constantes utilizadas nos programas envolvendo o Kinect SDK:

Figura 12: Esqueleto de referência do Kinect com nomes de articulações.

Fonte: www.microsoft.com/xbox

Assim, movimentações de corpos com padrões humanos na frente da câmera IV do Kinect resultam em alteração de coordenadas das articulações do esqueleto de referência, conforme mostra a Figura 13:

Figura 13: Movimentação real e sua vinculação com as articulações do esqueleto de referência.

(11)

1.4 Kinect SDK

No início do lançamento do dispositivo Kinect, sua programação não era uma tarefa muito simples devido à escassez de bibliotecas. Havia, inicialmente, um conjunto de drivers e uma interface de programação C/C++ desenvolvido pela própria empresa PrimeSense (Middleware NITE - http://www.primesense.com/nite) e diversos projetos “hackers” em outras linguagens como, por exemplo, o OpenKinect (http://openkinect.org).

Em Junho de 2011, a Microsoft disponibilizou uma versão beta do Kinect SDK com implementações diretas para as linguagens C# e Visual Basic. O Kinect SDK é formado essencialmente por um conjunto de classes para imagens (NUI) e outro para áudio (DMO). As aplicações, quando necessitam acessar o dispositivo Kinect, podem fazê-lo via chamadas a estas classes, conforme mostra a Figura 14:

Figura 14: Relacionamento entre as aplicações e o Kinect SDK.

Fonte: www.microsoft.com

Uma visão mais detalhada dos diversos componentes do Kinect SDK e suas relações com outros componentes Windows é mostrado na Figura 15:

Figura 15: Componentes de aplicação, do Windows e do Kinect SDK.

Fonte: www.microsoft.com

Video Components Audio Components

Windows components 1 2 3 5 4

Kernel-mode drivers for Kinect for Windows

DMO codec for mic array

Applications Kinect for Windows SDK User-created components USB Hub

Windows Core Audio and Speech APIs

Device

setup Video stream control Audio stream control

WinUSB device stack WinUSB camera stack USBAudio audio stack

Motor Cameras Audio mic array

NUI API A/V capture and transcoding

Media Foundation | DirectShow

(12)

1.5 Ambiente de Desenvolvimento

Como o Kinect SDK possui uma limitação de apenas poder ser “executado” dentro do ambiente Windows, os autores recomendam o seguinte ambiente de desenvolvimento para as aplicações:

 Microsoft Visual Studio 2010

 Microsoft XNA 4.0, framework para criação de jogos para Windows, Xbox, Web e Windows Phone 7, que pode ser obtido gratuitamente do seguinte endereço:

http://www.microsoft.com/download/en/details.aspx?id=23714

 SILVERLIGHT 4.0 + Expression Studio 4.0 (Opcional). O Silverlight é um framework da Microsoft para desenvolvimento de aplicações multimídia e hipermídia e, o Expression Studio, um conjunto de ferramentas de produtividade para este framework. Ambos podem ser obtidos do endereço:

http://www.microsoft.com/expression/

Uma ferramenta bastante útil para programação em Silverlight é o Blend 4.0 (Figura 16), que faz parte do pacote Expression Studio 4:

Figura 15: Expression Blend 4.0

Fonte: www.microsoft.com

 KINECT SDK, framework para programação do Kinect em Windows. Pode ser obtido gratuitamente do endereço:

(13)

1.6 Desenvolvimento com Microsoft Silverlight com C#

A seguir, é mostrado um código exemplificando o desenvolvimento com o framework Microsoft Silverlight para acesso aos recursos de esqueletos do Kinect SDK via C#:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Microsoft.Research.Kinect.Nui; using Coding4Fun.Kinect.Wpf; namespace SkeletalTracking { /// <summary>

/// Interaction logic for MainWindow.xaml /// </summary>

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //Kinect Runtime

Runtime nui = new Runtime();

private void Window_Loaded(object sender, RoutedEventArgs e) {

//Initialize to do skeletal tracking

nui.Initialize(RuntimeOptions.UseSkeletalTracking); #region TransformSmooth

//Must set to true and set after call to Initialize nui.SkeletonEngine.TransformSmooth = true; //Use to transform and reduce jitter

var parameters = new TransformSmoothParameters {

(14)

MaxDeviationRadius = 0.04f };

nui.SkeletonEngine.SmoothParameters = parameters; #endregion

//add event to receive skeleton data nui.SkeletonFrameReady += new

EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady); }

void nui_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) {

SkeletonFrame allSkeletons = e.SkeletonFrame; //get the first tracked skeleton

SkeletonData skeleton = (from s in allSkeletons.Skeletons where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault(); if(skeleton != null) { //set position SetEllipsePosition(headEllipse, skeleton.Joints[JointID.Head]); SetEllipsePosition(leftEllipse, skeleton.Joints[JointID.HandLeft]); SetEllipsePosition(rightEllipse, skeleton.Joints[JointID.HandRight]); } }

private void SetEllipsePosition(FrameworkElement ellipse, Joint joint)

{

var scaledJoint = joint.ScaleTo(640, 480, .5f, .5f); Canvas.SetLeft(ellipse, scaledJoint.Position.X); Canvas.SetTop(ellipse, scaledJoint.Position.Y);

}

(15)

1.7 Desenvolvimento com Microsoft Silverlight com Visual Basic

A seguir, é mostrado um código exemplificando o desenvolvimento com o framework Microsoft Silverlight para acesso aos recursos de esqueletos via Visual Basic:

Imports System.Text

Imports Microsoft.Research.Kinect.Nui Imports Coding4Fun.Kinect.Wpf Namespace SkeletalTracking ''' <summary>

''' Interaction logic for MainWindow.xaml ''' </summary>

Partial Public Class MainWindow Inherits Window

Public Sub New() InitializeComponent() End Sub

'Kinect Runtime

Private nui As New Runtime

Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) 'Initialize to do skeletal tracking

nui.Initialize(RuntimeOptions.UseSkeletalTracking) '#Region "TransformSmooth"

'Must set to true and set after call to Initialize nui.SkeletonEngine.TransformSmooth = True 'Use to transform and reduce jitter

Dim parameters = New TransformSmoothParameters With {.Smoothing = 0.75f, .Correction = 0.0f, .Prediction = 0.0f, .JitterRadius = 0.05f, .MaxDeviationRadius = 0.04f}

nui.SkeletonEngine.SmoothParameters = parameters '#End Region

'add event to receive skeleton data

(16)

Private Sub nui_SkeletonFrameReady(ByVal sender As Object, ByVal e As SkeletonFrameReadyEventArgs)

Dim allSkeletons As SkeletonFrame = e.SkeletonFrame 'get the first tracked skeleton

Dim skeleton As SkeletonData = ( _ From s In allSkeletons.Skeletons _

Where s.TrackingState = SkeletonTrackingState.Tracked _ Select s).FirstOrDefault() If skeleton Is Nothing 'set position SetEllipsePosition(headEllipse, skeleton.Joints(JointID.Head)) SetEllipsePosition(leftEllipse, skeleton.Joints(JointID.HandLeft)) SetEllipsePosition(rightEllipse, skeleton.Joints(JointID.HandRight)) End If End Sub

Private Sub SetEllipsePosition(ByVal ellipse As FrameworkElement, ByVal joint As Joint) Dim scaledJoint = joint.ScaleTo(640, 480,.5f,.5f)

Canvas.SetLeft(ellipse, scaledJoint.Position.X) Canvas.SetTop(ellipse, scaledJoint.Position.Y) End Sub

Private Sub Window_Closed(ByVal sender As Object, ByVal e As EventArgs) 'Cleanup

nui.Uninitialize() End Sub

(17)

1.8 Desenvolvimento com Microsoft XNA com C#

A seguir, é mostrado um código exemplificando o desenvolvimento com o framework Microsoft XNA para acesso aos recursos de esqueletos via C#:

using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using Microsoft.Research.Kinect.Nui; namespace KinectFundamentals { /// <summary>

/// This is the main type for your game /// </summary>

public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Runtime kinectSensor; Texture2D kinectDepthVideo; Texture2D overlay; public Game1() {

graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.PreferredBackBufferWidth = 640; graphics.PreferredBackBufferHeight = 480; } /// <summary>

/// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well.

/// </summary>

protected override void Initialize() {

(18)

kinectSensor = new Runtime();

kinectSensor.Initialize(RuntimeOptions.UseDepth); base.Initialize();

}

/// <summary>

/// LoadContent will be called once per game and is the place to load /// all of your content.

/// </summary>

protected override void LoadContent() {

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

kinectDepthVideo = new Texture2D(GraphicsDevice, 1337, 1337); kinectSensor.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.Depth); kinectSensor.DepthFrameReady += new

EventHandler<ImageFrameReadyEventArgs>(kinectSensor_DepthFrameReady); overlay = Content.Load<Texture2D>("overlay");

// TODO: use this.Content to load your game content here }

void kinectSensor_DepthFrameReady(object sender, ImageFrameReadyEventArgs e) {

PlanarImage p = e.ImageFrame.Image;

Color[] DepthColor = new Color[p.Height * p.Width]; float maxDist = 4000;

float minDist = 850;

float distOffset = maxDist - minDist;

kinectDepthVideo = new Texture2D(GraphicsDevice, p.Width, p.Height); int index = 0;

for (int y = 0; y < p.Height; y++) {

for (int x = 0; x < p.Width; x++, index += 2) {

int n = (y * p.Width + x) * 2;

int distance = (p.Bits[n + 0] | p.Bits[n + 1] << 8);

byte intensity = (byte)(255 - (255 * Math.Max(distance - minDist, 0) / (distOffset))); DepthColor[y * p.Width + x] = new Color(intensity, intensity, intensity);

} }

(19)

/// <summary>

/// UnloadContent will be called once per game and is the place to unload /// all content.

/// </summary>

protected override void UnloadContent() {

// TODO: Unload any non ContentManager content here kinectSensor.Uninitialize();

}

/// <summary>

/// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit();

// TODO: Add your update logic here base.Update(gameTime);

}

/// <summary>

/// This is called when the game should draw itself. /// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code her spriteBatch.Begin();

spriteBatch.Draw(kinectDepthVideo, new Rectangle(0, 0, 640, 480), Color.White); spriteBatch.Draw(overlay, new Rectangle(0, 0, 640, 480), Color.White);

spriteBatch.End(); base.Draw(gameTime); } } } 1.9 Considerações Finais

(20)

Estas notas apresentaram os fundamentos de programação para este dispositivo via Kinect SDK e os autores acreditam que, a partir delas, pesquisadores e alunos podem iniciar aplicações que demandem por recursos de interfaces baseadas em gestos.

Infelizmente, ainda não existem referências muito sólidas sobre o Kinect SDK. Porém, recomenda-se a leitura das referências abaixo para conhecer melhor as ferramentas que podem auxiliar o desenvolvimento de interfaces para suportar as aplicações baseadas em Kinect.

Referências

JAEGERS, K. XNA 4.0 Game Development by Example: Begginer´s Guide. New York: Packt Publishing, 2010.

Referências

Documentos relacionados

Our contributions are: a set of guidelines that provide meaning to the different modelling elements of SysML used during the design of systems; the individual formal semantics for

O valor da reputação dos pseudônimos é igual a 0,8 devido aos fal- sos positivos do mecanismo auxiliar, que acabam por fazer com que a reputação mesmo dos usuários que enviam

Assim, o que se pretende com a utilização de simulações em Realidade Virtual é proporcionar momentos de reflexão nos quais os conceitos são elaborados e relaborados, utilizados

Ficou com a impressão de estar na presença de um compositor ( Clique aqui para introduzir texto. ), de um guitarrista ( Clique aqui para introduzir texto. ), de um director

Changes in the gut microbiota appears to be a key element in the pathogenesis of hepatic and gastrointestinal disorders, including non-alcoholic fatty liver disease, alcoholic

da quem praticasse tais assaltos às igrejas e mosteiros ou outros bens da Igreja, 29 medida que foi igualmente ineficaz, como decorre das deliberações tomadas por D. João I, quan-

(essencialmente toalhas adamascadas, damasquilho de linho e algodão, panos de linho e lenços de linho e algodão, desenvolvidos essencialmente em 17 freguesias do concelho