Kinect for Windows v2 のセットアップ

Kinect for Windows v2 のセットアップの方法や注意点について記述します。
開発環境と非開発環境では方法が異なります。
(v1 系については、以前に Kinect for Windows SDK のセットアップに書きました。)

 

■ 開発環境におけるセットアップ

開発環境には、Kinect for Windows SDK 2.0 (約 280 MB) をインストールします。

インストール後の接続確認をするには、「Developer Toolkit Browser」を利用するとよいでしょう。
これには多数のサンプルが含まれています。

環境変数については、Kinect for Windows SDK 2.0 をインストールすると

KINECTSDK20_DIR=C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\

が追加されます。

 

さて、アプリケーションを開発するには、Microsoft.Kinect.dll への参照が必要になります。
Visual Studio の参照マネージャーで、[アセンブリ] – [拡張] からこれを選択できます。

参照マネージャー

ただし、この方法では特定のバージョンに依存することになり、
例えば、今後バージョン 2.1 の SDK にアップグレードした場合、プロジェクトはビルドエラーになってしまいます。
そこで前述の環境変数を利用して、
プロジェクト ファイル (C# なら .csproj) において例えば次のようにアセンブリのパスを指定することもできます。


  <ItemGroup>
    <Reference Include="Microsoft.Kinect">
      <HintPath>$(KINECTSDK20_DIR)Assemblies\Microsoft.Kinect.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    (以下略)


この方法であれば、特定のバージョンに依存せずにビルドすることができます。

 

■ 非開発環境におけるセットアップ

本番用・配布用端末では SDK は不要で、Kinect for Windows Runtime 2.0 (約 90 MB) をインストールします。

なお、Kinect for Windows Runtime は Kinect for Windows SDK にも付属しており、次のパスに存在します。

%KINECTSDK20_DIR%Redist\KinectRuntime-v2.0_1409-Setup.exe

 

バージョン情報
Kinect for Windows v2
Kinect for Windows SDK 2.0
Visual Studio 2013

参照
Kinect for Windows v2 センサー
Kinect for Windows SDK 2.0
Kinect for Windows Runtime 2.0

Kinect for Windows SDK 2.0 (MSDN)
Getting Started (MSDN)
Kinect for Windows SDK のセットアップ (v1 用)

カテゴリー: 周辺機器. タグ: . 1 Comment »

LINQ のクエリ パターン

Visual Studio で C# のプロジェクト (ここではコンソール アプリケーションにしています) を作成して、
次のようなクエリ式を書いてみます。

Program.cs


class Program
{
    static void Main(string[] args)
    {
        var result =
            from x in new Monad<int>()
            select x;
    }
}

public class Monad<T>
{
}


Monad<T> はとりあえず空のジェネリック クラスです。
この状態でビルドすると、

「ソース型 ○○ のクエリ パターンの実装が見つかりませんでした。’Select’ が見つかりません。」

というコンパイラ エラーになります。

コンパイラ エラー CS1936

 

このクエリ パターンとは LINQ 標準クエリ演算子のことで、具体的には Select, Where, OrderBy メソッドなどがあります。
標準クエリ演算子のクエリ式構文に対応が記載されており、
例えば C# で select 句が有効になるようにするには、
IEnumerable<T> でいうところの Enumerable.Select メソッドに相当するメソッドが実装されている必要があります。

 

というわけで、例として Maybe モナドとそのクエリ パターンを実装してみます。

Maybe.cs


public struct Maybe<T>
{
    public static readonly Maybe<T> None = new Maybe<T>();

    T _value;

    public T Value
    {
        get
        {
            if (!HasValue) throw new InvalidOperationException();
            return _value;
        }
    }

    public bool HasValue { get; private set; }

    public Maybe(T value)
        : this()
    {
        _value = value;
        HasValue = true;
    }

    public static explicit operator T(Maybe<T> value)
    {
        return value.Value;
    }

    public static implicit operator Maybe<T>(T value)
    {
        return new Maybe<T>(value);
    }

    public Maybe<TResult> Bind<TResult>(Func<T, Maybe<TResult>> func)
    {
        return HasValue
            ? func(_value)
            : Maybe<TResult>.None;
    }

    public override string ToString()
    {
        return HasValue
            ? _value.ToString()
            : "";
    }
}

public static class Maybe
{
    public static Maybe<T> ToMaybe<T>(this T value)
    {
        return value;
    }

    public static Maybe<TResult> Select<T, TResult>(this Maybe<T> maybe, Func<T, TResult> selector)
    {
        return maybe.HasValue
            ? selector((T)maybe)
            : Maybe<TResult>.None;
    }

    public static Maybe<TResult> SelectMany<T, U, TResult>(this Maybe<T> maybe, Func<T, Maybe<U>> selector, Func<T, U, TResult> resultSelector)
    {
        var selected = maybe.Bind(selector);
        return selected.HasValue
            ? resultSelector((T)maybe, (U)selected)
            : Maybe<TResult>.None;
    }

    public static Maybe<T> Where<T>(this Maybe<T> maybe, Func<T, bool> predicate)
    {
        return maybe.HasValue && predicate((T)maybe)
            ? maybe
            : Maybe<T>.None;
    }
}


Select メソッドのほか、

  • 複数の from 句に相当する SelectMany メソッド
  • where 句に相当する Where メソッド

を実装しています。
このようにクエリ パターンを実装しておくと、次のようにクエリ式を書くことができます。

Program.cs


class Program
{
    static void Main(string[] args)
    {
        var result1 = Add(1, 2); // 3
        var result2 = Add(2, 1); // None
        var result3 = Add(1, Maybe<int>.None); // None
    }

    static Maybe<int> Add(Maybe<int> x, Maybe<int> y)
    {
        return
            from _x in x
            from _y in y
            where _x < _y
            select _x + _y;
    }
}


 

このようにして、IEnumerable<T> インターフェイス以外でもクエリ式を利用することができます。
ちなみに、IObservable<T> インターフェイスのクエリ式については、
Reactive Extensionsの概要と利用方法にコード例が載っています。

 

作成したサンプル
MonadConsole (GitHub)

参照
コンパイラ エラー CS1936
標準クエリ演算子の概要
select 句 (C# リファレンス)
Query Expression Pattern で Maybe monad を書く
モナドの驚異

F# で素数を求める

以前に LINQ で素数を求める (C#) という記事を書きましたが、
その中にある GetPrimeNumbers 関数を F# で書いてみると、次のようになります。

 

Program.fs


open System
open System.Collections.Generic
open System.Diagnostics

module Seq2 =
    let do2 action source =
        seq {
            for x in source do
                action(x)
                yield x
        }

let getPrimeNumbers minValue maxValue =
    (
        new List<int64>(),
        Math.Max(minValue, 2L),
        Math.Max(maxValue, 0L),
        if maxValue >= 0L then (maxValue |> float |> Math.Sqrt |> int64) else 0L
    )
    |> Seq.singleton
    |> Seq.collect (fun (primes, min, max, root_max) ->
        (seq { 2L .. Math.Min(root_max, min  1L) }, seq { min .. max })
        ||> Seq.append
        |> Seq.map (fun i -> (primes, i, i |> float |> Math.Sqrt |> int64)))
    |> Seq.filter (fun (primes, i, root_i) ->
        primes
        |> Seq.takeWhile (fun p -> p <= root_i)
        |> Seq.forall (fun p -> i % p <> 0L))
    |> Seq2.do2 (fun (primes, i, _) -> primes.Add(i))
    |> Seq.map (fun (_, i, _) -> i)
    |> Seq.skipWhile (fun i -> i < minValue)

[<EntryPoint>]
let main argv = 
    let stopwatch = Stopwatch.StartNew()
    let result = (1000000000000L, 1000000001000L) ||> getPrimeNumbers |> Seq.toArray
    stopwatch.Stop()

    result |> Seq.iter (printfn "%A")
    stopwatch.Elapsed.TotalSeconds |> printfn "%A seconds"
    0


 

プログラムを実行します。

実行結果

結果は、C# よりも遅くなりました。
F# は構文糖衣が多く、コンパイル時にクラスに置き換わるものがあるため、
実行時に生成されるオブジェクトが多くなるのが原因であると予想されます。

 

作成したサンプル
PrimeNumbersConsoleF (GitHub)

バージョン情報
.NET Framework 4.5

参照
エラトステネスの篩 – Wikipedia
シーケンス (F#) (MSDN)
LINQ で素数を求める (C#)

カテゴリー: プログラミング言語. タグ: , . 1 Comment »