読者です 読者をやめる 読者になる 読者になる

Kinect for Windows SDK で RGBカメラの画像表示(F# + WPF)

Kinect F#

BetaではないKinect SDKがリリースされたのでBeta時代に作ったコードを軽く調整して動かしてみました。

参照の追加

XAML

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MyKinectApplication" Height="600" Width="800">
    <Grid>
        <Image Name="kinectImage" Height="480" Width="640" Stretch="Uniform" />
    </Grid>
</Window>

画面に映像を表示します。

FS

module FsSampleKinectApplication

open System
open System.Threading
open System.Windows
open System.Windows.Controls
open Microsoft.Kinect
open Coding4Fun.Kinect.Wpf
open System.Windows.Threading
open System.Reactive.Linq

let window = Application.LoadComponent(new System.Uri("/FsSampleKinectApplication;component/MainWindow.xaml", System.UriKind.Relative)) :?> Window

let syncContext =
  if SynchronizationContext.Current = null then new DispatcherSynchronizationContext() |> SynchronizationContext.SetSynchronizationContext
  SynchronizationContext.Current

let kinect = KinectSensor.KinectSensors.[0]

let kinectImage = window.FindName "kinectImage" :?> Image
  
do window.Loaded
     .Subscribe begin
       fun _ ->
         kinect.ColorStream.Enable()
         kinect.Start()
     end
   |> ignore

do window.Unloaded
   |> Observable.subscribe (fun _ -> kinect.Stop() )
   |> ignore

do syncContext
   |> kinect.ColorFrameReady.ObserveOn
   |> fun observer -> observer.Subscribe (fun (args:ColorImageFrameReadyEventArgs) -> kinectImage.Source <- args.OpenColorImageFrame().ToBitmapSource())
   |> ignore

[<STAThread>]
if KinectSensor.KinectSensors.Count <> 0 then window |> (new Application()).Run |> ignore

F#の場合は全体的にSynchronizationContextをかませないとイベントの同期がとれなくなりましたね。

(解説は後で書く…?)