2013年8月2日金曜日

LeapMotion サンプル その1 (WPF+VB)

KINECTよりすごい(かも)と言われているLeapMotionを手に入れました。
2013/7/22に一般発売でしたが、21日に注文して27日には到着しましたので比較手に入手はしやすいようです。

さて、LeapMotionで何ができるのかと簡単に説明するとセンサー上の手指の位置や移動の情報を高精度で取得できるガジェットです。

開発環境はC++,C#,JAVA,Javascript,Python等色々あります。OSはWindows7以降,MacOS X等(Linuxはまだβ版ドライバ)です。

SDKも一通り揃っているので、開発しやすいと思います。

ただ、SDK内のサンプルプログラムはWPF向けではないので、VB(開発環境には載っていないけれども.NetFramework3.5以降対応なので問題なし)+WPFのサンプルプログラムを作ってみました。

内容は指一本をセンサー上で動かすとCanvas上のポインター(Ellipse)が指先と同じように動きます。
LeapMotionはSDK上に仮想スクリーンを生成する機能を持っているので、それを利用しています。

早速コードをと行きたいところですが、まずは開発環境を整えましょう。

環境についてはこちらのブログを参照するのが早いと思います。

Natural Software
 http://www.naturalsoftware.jp/blog/8389

C#向けですが、VBも同じです。C++とかMacでの環境設定の説明もあるので他の記事も参考になると思います。

それではプログラムコードです。

まずはXAMLのソースです。画面構成はテキストボックスを4つと、Canvasを1つ配置しています。
Canvasのサイズは適当に変えても大丈夫です。

MainWindow.xaml
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="900" Width="1228">
    <Grid>
        <Canvas Name="Canvas1" Height="800" Width="1200" Margin="10,50,82,19"/>
        <TextBox Name="textbox1" HorizontalAlignment="Left" Height="23" Margin="85,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="80"/>
        <TextBox x:Name="textbox2" HorizontalAlignment="Left" Height="23" Margin="245,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="80"/>
        <TextBox x:Name="textbox3" HorizontalAlignment="Left" Height="23" Margin="358,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="80"/>
        <TextBox x:Name="textbox4" HorizontalAlignment="Left" Height="23" Margin="470,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="80"/>
        <Label Content="Frame ID:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="70"/>
        <Label Content="Finger ID:" HorizontalAlignment="Left" Margin="170,10,0,0" VerticalAlignment="Top"/>
        <Label Content="X:" HorizontalAlignment="Left" Margin="330,10,0,0" VerticalAlignment="Top"/>
        <Label Content="Y:" HorizontalAlignment="Left" Margin="443,10,0,0" VerticalAlignment="Top"/>
    </Grid>
</Window>

次にプログラムコードです。
MainWindow.xaml.vb

Imports Leap
Class MainWindow
    Private leap As New Controller
    Private windowWidth As Integer = 1200       ''仮想スクリーンの幅
    Private windowHeight As Integer = 800       ''仮想スクリーンの高さ
    Public Sub New()
        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()
        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        ''イベント登録
        AddHandler CompositionTarget.Rendering, AddressOf UpdateFrame
    End Sub
    Private Sub UpdateFrame(sender As Object, e As EventArgs)
        Dim frame As Leap.Frame = leap.Frame
        Dim finger As Finger = frame.Fingers.Frontmost                      ''一番センサーに近い指を選択
        Dim stabilizedPosition As Vector = finger.StabilizedTipPosition
        Dim iBox As InteractionBox = leap.Frame.InteractionBox
        Dim normalizedPosition As Vector = iBox.NormalizePoint(stabilizedPosition)
        Dim x As Double = normalizedPosition.x * windowWidth
        Dim y As Double = windowHeight - normalizedPosition.y * windowHeight
        ''テキストボックスに各情報をセット
        textbox1.Text = frame.Id
        textbox2.Text = finger.Id
        textbox3.Text = CInt(x)
        textbox4.Text = CInt(y)
        ''Canvasのクリア
        Canvas1.Children.Clear()
        ''指を認識していないときは何もしない
        If finger.Id = -1 Then
        Else
            Dim el As New Ellipse
            Canvas1.Children.Add(el)
            With el
                .Margin = New Thickness(CInt(x), CInt(y), 0, 0)
                .Fill = New SolidColorBrush(Colors.Green)
                .Width = 10
                .Height = 10
            End With
        End If
    End Sub
End Class



WPFを使う場合に問題になるのが、要素の書き換え(この場合はCanvas)とセンサーからのデータ取得を同一スレッドで行う必要があることになります。

今回はCompositionTarget.Renderingイベントに合わせて、センサーからデータを取得しています。
CompositionTarget.RenderingはWPFの描画プロセス中に発生するイベントです。

プログラム内の描画ルーチン(UpdateFrame)は最低限のことしかしていません。本来であれば指先をロストした時の処理なども必要になると思います。(なので指先がセンサーの認識範囲外に移動するとポインターが暴れます。)

次はこのプログラムにタッチエミュレーションを加えてみようと思います。


0 件のコメント:

コメントを投稿