2013/05/11

C#.Net 使用WPF開發KINECT

決定幫學長寫這個程式了,也是因為國科會案子的展示大致上今年應該OK了,剩下明年展完也差不多要畢業了。

2009年6月,我知道這個東西後其實還蠻感興趣的。約2010就有推出Develop的網站,有分32bit和64bit的版本,親戚有購買XBOX360用的KINECT,不過不好意思跟親戚借來開發程式,後來就做罷了。其實我有偷偷拿來玩過XDDD


不過當初還有研究相關KINECT架構以及人體關節,也就是因為這樣對於影像辨識這塊非常的感興趣,不過技術技術說破就不值錢了。

當初最夯的Souce code應該是光劍吧?


微軟也推出切水果的一個遊戲,當初還蠻轟動的。






誰會知道還有機會接觸到,接觸了就做吧!

首先,必須前往KINECT Develop下載SDKToolKit
安裝順序建議由SDK安裝完成後在安裝ToolKit

下載完成後,請先重開機,讓環境變數重新載入


接著開啟Visual Studio 2010,選擇Windows/WPF應用程式作為開發



那何謂WPF?可以參考WIKIPEDIA寫得

那跟一般視窗程式差異在哪裡可以參考『Introducing WPF – Experiences of a former Windows Forms developer』和『Windows Forms Vs WPF

這是一開始畫面





新增一個Image元件進到視窗,並且將Image元件的高度寬寬都刪除

MainApplication.xaml
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="My first KINECT demo sample." Height="700" Width="520">
    <Grid>
        <Image Name="Image" />
    </Grid>
</Window>

專案內是不是還有一個App.xaml檔案?那個檔案就很類似C#.Net的Program.cs檔案一樣,用來指定Index是誰




將KINECT的DLL加入參考,位置大概是X:\Program Files\Microsoft SDKs\Kinect\v1.7\Assemblies\Microsoft.Kinect.dll



建議每次加入參考後,點擊參考套件名稱兩下用物件瀏覽器去看裡面包涵的物件有哪些,這樣會比較好知道可能會用到哪些物件開發程式



接著我們回到MainWindow.xaml.cs來開發程式

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private KinectSensor sensor;
        private byte[] dataPixels;

        public MainWindow()
        {
            InitializeComponent();
        }

        #region 載入視窗

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            sensor = KinectSensor.KinectSensors[0];
            sensor.ColorStream.Enable();
            sensor.ColorFrameReady += VideoFrameReady;
            sensor.Start();
        }

        #endregion 載入視窗

        #region 結束視窗

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            sensor.Stop();
        }

        #endregion 結束視窗

        #region 讀入影像

        private void VideoFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            bool hasData = false;
            using (ColorImageFrame frame = e.OpenColorImageFrame())
            {
                if (frame == null)
                {
                }
                else
                {
                    dataPixels = new byte[frame.PixelDataLength];
                    frame.CopyPixelDataTo(dataPixels);
                    hasData = true;
                }
            }
            if (hasData)
            {
                BitmapSource source = BitmapSource.Create(640, 480, 96, 96, PixelFormats.Bgr32, null, dataPixels, 640 * 4);
                Image.Source = source;
            }
        }

        #endregion 讀入影像
    }
}





這是成果,不過你們一定很好奇為什麼是黑色的?




就是透過三個鏡頭去擷取出來的,可能因為距離太近所以才會變成這樣
實際上是可以正常顯示的,在2公尺到3公尺內的拍攝距離可能會比較清楚


在編譯時我有遇到一個問題,就是執行時會當機
當機原因可能是因為Avast攔截KINECT運行,可能會因為KINECT被辨認為視訊
所以用程式去ON起來時會被防毒攔截

另一個可能是我將USB線插在USB3上面,不知道是不是因為我的主機板非原生的USB3 Chip
所以導致塞進去資料使I/O堵塞,造成整個系統Crash

死機好幾次,等等在重新開機試試看看是防毒還是USB版本問題

確認應該是USB版本才會導致當機


參考資料:
https://zh.wikipedia.org/wiki/Windows_Presentation_Foundation
http://www.centigrade.de/en/blog/article/introducing-wpf-experiences-of-a-former-windows-forms-developer/
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/0820f6be-2b5f-4c5c-b8a6-a3cba7deea4b/
http://tw-hkt.blogspot.tw/2012/03/kinect-for-windows-sdk-v1.html

圖片參考:
http://p2.v.iask.com/524/261/42665715_2.jpg
http://www.napgames.com/wp-content/thumbs/4ff2064f4a21ffac77000d14_1354919049.jpeg