Passa ai contenuti principali

Kinect: cosa cambia nella nuova SDK

Con questo post vorrei iniziare una serie dedicata alle novità e ai cambiamenti presenti nell’SDK rilasciato il 1 febbraio 2012.

Cominciamo con riportare il link del portale Kinect in cui trovare il pacchetto di installazione dell’SDK e le risorse necessarie per cominciare a lavorare con lo stesso.

In questi post prenderò spunto dagli esempi che avevo a suo tempo riportato in un’analoga serie di post (ai tempi della beta2) e proverò di farli funzionare nuovamente con il nuovo SDK analizzando ciò che è cambiato.

Installato l’SDK, abbiamo a disposizione un browser che ci permette di accedere facilmente alla documentazione e agli esempi.

SNAGHTML1cbd41a8

Prima cosa che balza all’occhio quando tentiamo di utilizzare l’assembly contenente le classi di gestione del Kinect è che l’assembly da referenziare non è più Microsoft.Research.Kinect.dll ma Microsoft.Kinect.dll.

In maniera analoga, il namespace principale delle classi dell’SDK non è più Microsoft.Research.Kinect ma Microsoft.Kinect.

La classe principale utilizzata nella Beta2 per accedere alle funzionalità del Kinect era la classe Runtime, nella versione 1.0 questa è completamente sparita ed è sparito anche il modo con cui si accede alla classe di gestione del Kinect.

La classe Runtime è stata sostituita dalla classe KInectSensor contenuta nel namespace Microsoft.Kinect.

Il seguente disegno mostra la struttura della classe KinectSensor:

KinectSensor class

La classe KinectSensor non ha costruttori ma espone una proprietà Shared chiamata KinectSensors che ci consente di avere a disposizione l’elenco dei sensori Kinect attaccati al nostro PC (fino a 4) e rilevati dal sistema. Altra cosa importante (di cui ci occuperemo in un prossimo post) è l’esistenza dell’evento AllFrameReady il cui scopo è quello di fornire dei frame sincronizzati per le sorgenti abilitate.

Possiamo, quindi, accedere al nostro Kinect nel seguente modo:

  1. If KinectSensor.KinectSensors.Any() Then
  2.     Sensor = KinectSensor.KinectSensors(0)
  3. End If

dove Sensor è la variabile che utilizzeremo per accedere al dispositivo.

Una volta recuperata l’istanza della classe per la gestione del Kinect, dobbiamo sottoscrivere gli eventi da gestire per i frame che arrivano dal dispositivo e aprire gli opportuni stream.

Anche per questo, ci sono stati dei cambiamenti. In particolare, l’evento VideoFrameReady della vecchia Runtime, è stato rinominato in ColorFrameReady e l’attivazione degli stream non avviene più con il metodo Initialize (che apriva gli stream e avviava la gestione degli stessi) ma richiamando il metodo Enable (o Disable per disabilitare) delle proprietà ColorStream, DepthStream o SkeletonStream (in base a quale stream gestire) seguito dal metodo Start.

Il metodo Enable prevede, nel caso del ColorStream, la possibilità di passare come argomento la risoluzione delle immagini da recuperare. La presenza dell’Enable e del Disable fa si che si possano attivare e disattivare i flussi provenienti dal Kinect “a caldo” senza dover fermare l’istanza del KinectSensor e riavviarla.

Ad esempio per gestire una risoluzione video di 640x480 a 30 fps, possiamo scrivere:

  1. If KinectSensor.KinectSensors.Any() Then
  2.     Sensor = KinectSensor.KinectSensors(0)
  3.     If Sensor.Status = KinectStatus.Connected Then
  4.         AddHandler Sensor.ColorFrameReady, AddressOf ColorFrameReadyHandler
  5.         Sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30)
  6.         Try
  7.             Sensor.Start()
  8.         Catch ex As Exception
  9.  
  10.         End Try
  11.     End If
  12. End If

La proprietà Status della KinectSensor ci consente di sapere lo stato del sensore (nel nostro caso se è connesso) in modo da eseguire le operazioni di apertura degli stream e di aggancio degli eventi solo se effettivamente il sensore è connesso.

Anche la firma del gestore dell’evento ColorFrameReady è cambiata rispetto alla firma del precedente evento presente nella classe Runtime.

  1. Private Sub ColorFrameReadyHandler(sender As Object, e As ColorImageFrameReadyEventArgs)
  2.  
  3. End Sub

L’argomento ColorImageFrameReadyArgs permette di accedere alle informazioni relative al frame recuperato dal Kinect

image


Da notare la presenza del metodo OpenColorImageFrame per recuperare l’istanza della classe ColorImageFrame che è il vero contenitore dei dati provenienti dalla video camera del Kinect.



Per ottenere l’array di byte costituenti l’immagine effettiva è necessario definire un array di byte della lunghezza pari a PixelDataLenght e copiarvi dentro i dati con il metodo CopyPixelDataTo().







  1. Using colorImageFrame = e.OpenColorImageFrame()

  2.     If colorImageFrame IsNot Nothing Then

  3.         Dim imageArray() = New Byte(colorImageFrame.PixelDataLength - 1) {}

  4.         colorImageFrame.CopyPixelDataTo(imageArray)

  5.         '

  6.         ' Gestione dell'array dati proveniente dal Kinect

  7.         '

  8.     End If

  9. End Using






Dato l’array di byte possiamo creare una BitmapSource e possiamo visualizzare la stessa all’interno, ad esempio, di un controllo image WPF:







  1. Private Sub ColorFrameReadyHandler(sender As Object, e As ColorImageFrameReadyEventArgs)

  2.     Dim colorImageFrame = e.OpenColorImageFrame()

  3.     Dim imageArray(colorImageFrame.PixelDataLength) As Byte

  4.     colorImageFrame.CopyPixelDataTo(imageArray)

  5.     Dim stride = colorImageFrame.Width * colorImageFrame.BytesPerPixel

  6.     Me.VideoImage.Source = BitmapSource.Create(colorImageFrame.Width, colorImageFrame.Height,

  7.                                                96, 96,

  8.                                                PixelFormats.Bgr32, Nothing,

  9.                                                imageArray, stride)

  10. End Sub






Ogni volta che l’SDK avrà ricevuto un frame dalla video camera del dispositivo, richiamerà il nostro gestore di evento e visualizzeremo l’immagine corrispondente.



Infine, nel momento in cui dobbiamo chiudere la nostra applicazione e rilasciare la classe di gestione del Kinect, possiamo utilizzare il metodo Stop (per fermare il flusso degli stream e il Dispose per rilasciare effettivamente l’istanza:







  1. If Sensor IsNot Nothing Then

  2.     If Sensor.IsRunning Then

  3.         Sensor.Stop()

  4.         Sensor.Dispose()

  5.     End If

  6. End If






Prima di concludere questo primo post, un accenno allo stride di una immagine per capire meglio il codice precedente.



Quando memorizziamo una immagine in memoria, in realtà, questa è memorizzata in un buffer che potrebbe contenere dei byte in più rispetto a quelli necessari a memorizzare l’immagine stessa (vedi figura). Questi byte in più non influenzano la visualizzazione ma solo lo spazio occupato.



IC156482



Lo stride di un’immagine altro non è che la lunghezza di una riga della precedente matrice buffer. Nella fattispecie è data dalla larghezza del frame per il numero di byte per pixel.



In allegato trovate una solution di esempio:




 



Commenti

Post popolari in questo blog

VB.NET for Dummies: Gli Eventi

Vorrei iniziare con questo post una serie dedicata ad aspetti di VB.NET di base che possono essere utile a coloro che si avvicinano al mondo .NET e che, in genere, non vengono trattati a livello base. La serie di post non ha la pretesa di essere assolutamente esaustivi sugli argomenti che tratterò In questo primo post parleremo degli eventi. Cosa sono e a cosa servono Un evento è la “notifica” dell’accadimento di qualcosa. Quando, ad esempio, premiamo un bottone della finestra di un’applicazione, dietro le quinte, il bottone stesso “notifica” al mondo circostante che qualcuno, in quell’istante, lo ha premuto. Sta, poi, al mondo circostante preoccuparsi di “intercettare” l’evento stesso per gestirlo (tramite un gestore di evento). Attenzione a non confondere la pressione del tasto con la “notifica” della pressione del tasto: l’evento è la “notifica” dell’accadimento, non l’accadimento stesso. Ma a cosa serve tutto ciò? Utilizzare gli eventi è un modo per disaccoppiare ...

VB.NET: SplashScreen con effetto fade-in

In questo post vorrei proporvi un modo per realizzare una splash screen per le nostre applicazioni Windows Form che appare progressivamente con un effetto fade. Supponiamo di avere il nostro progetto VB.NET in una soluzione Visual Studio 2008 in cui abbiamo il sorgente della nostra applicazione Windows Form. Inseriamo una splash screen utilizzando il menù Progetto->Aggiungi Nuovo Elemento e selezionando il tipo di elemento “Schermata Iniziale” A questo punto Visual Studio creerà, automaticamente, la schermata iniziale che possiamo personalizzare graficamente come vogliamo. Per poter fare in modo che questa finestra appaia nel momento in cui avviamo l’applicazione, è necessario aprire le proprietà del progetto e impostare la maschera di avvio: In questo modo, all’avvio dell’applicazione, la schermata appare immediatamente e scompare un attimo prima della visualizzazione della finestra dell’applicazione. Possiamo far apparire la schermata iniziale con un ef...

Alla scoperta del Kinect: presentazioni e convenevoli

Oggi è arrivato un Kinect nuovo nuovo su cui cominciare a fare sperimentazione ed ho, quindi, deciso di condividere tutto ciò che scopro, le cavolate che faccio e i segreti che scopro con chi mi segue. I post che cercherò di scrivere con frequenza sono post di un neofita che si avvicina all’”Aggeggio” e che quindi sono diretti a chi nulla dell’argomento. Gli esperti troveranno noiosi e banali questi post, ma non si può aver tutto dalla vita. Per cominciare, scartato l’”Aggeggio” ho cominciato a preparare l’ambiente di sviluppo: 1) Visual Studio 2010 Ultimate (che uso normalmente ma che non è necessario in quanto si può sviluppare tranquillamente con la express edition); 2) Kinect SDK, scaricabile all’indirizzo http://research.microsoft.com/en-us/um/redmond/projects/kinectsdk/download.aspx 3) DirectX Software Development Kit scaricabile all’indirizzo http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6812 A questo punto vi basta connettere il Kinect al...