KINECT V2 SDK Fusion is Not Working

元ネタ

KINECT Fusionが動いてないっぽい

KINECT FusionはKINECTを使って3Dキャプチャのようなことができる機能です。
SDKにもサンプルが付属していますが、実際に起動してみるとやたら重いし、画面の半分くらいが真っ暗でまともに動いていないような印象を受けます。

解決方法

KINECT Fusionは通常のKINECTアプリケーションよりもかなり狭い範囲でしか利用できないことが原因で画面が真っ暗になっているように見えているだけです。
具体的にはKINECT Fusionで対応できる範囲はKINECTから1.5M程度の距離だけです。(普通のKINECTアプリケーションは4.5M)

KINECT Fusionアプリケーションを作ろうとした時に引っかかりがちな対応距離の違いを紹介しました。

これで「KINECT Fusionアプリでもこの範囲カバーできる!」という、うっかりミスを回避することができます。(実際に一度やりました) やりましたね :)

Kinect V2 dose not work

KINECT V2のフォーラムでよく見るのが「KINECT V2が動かない」というものです。

Msdn forums - Kinect for Windows v2 SDK

基本

KINECTが動かない原因はいくつかありますが、最初に疑うべきなのはハードウェアが基準を満たしているかです。 KINECTのhardware requirementsは以下のように記載されていますので、まずはこちらを確認しましょう。 この基準を満たしていない場合は一部/全部の機能が正常に動作しない可能性があります。

  • 64-bit (x64) processor
  • Physical dual-core 3.1 GHz (2 logical cores per physical) or faster processor
  • USB 3.0 controller dedicated to the Kinect for Windows v2 sensor
  • 4 GB of RAM
  • Graphics card that supports DirectX 11
  • Windows 8 or 8.1, or Windows Embedded 8

裏標準

ただし、裏標準として現状では以下の様なことに気をつける必要があります。

  • USB Host ControllerがUSB 3.0に対応している必要がある
    • 現状で対応しているのはIntelもしくはRenesasのUSB Host Contorllerのみです
  • PCI-Express v2.0のカードを使用している必要がある
    • PCI-XカードでUSB3.0ポートを利用している場合はPCI-Express v2.0に対応しているか確認しましょう

動いたけど…のケース

また、「動いたけど異常にパフォーマンスが低い/画面が真っ暗」という場合は以下の点を確認するとよいでしょう

  • 電源オプションでUSBバスへの電源供給が制御されていないか
    • 特に最近のノートPCはエコ電源オプションが付いています。これらのオプションがONになっているとUSBバスへの電源供給が制限され、まともにKINECTが動かないことがあります。
      「ハイパフォーマンス」などのオプションに切り替えると正常に動くようになります。
  • 他のUSB機器を利用していないか
    • USBバスのリソースの取り合いになってKINECTが不定期にコマ落ちしたりします。他のUSB機器は外しましょう。
  • 他のアプリケーションでGPUを酷使していないか
    • GPUリソースの取り合いになってKINECTが不定期にコマ落ちしたりします。他のアプリケーションを一回停止しましょう。
  • 部屋が暗くないか
    • 特にカラーフレームが影響を受けます。KINECTは部屋が薄暗くなるとlow light mode (15fpsで動作するモード)に移行します。部屋の証明はある程度光度を保ってください。
  • リモートデスクトップ仮想マシン上で動かしていないか
    • VMWareやVirtual BoxはDirectX 11をサポートしていません。また、リモートデスクトップで接続した端末でKINECTを利用したい場合は Local Resource -> Remote Audio -> Remote Audio SettingsPlay on remote computerに変更する必要があります。

KINECT for Windows V2 SDK Forumでよくある「KINECTが動かない」という質問で最初に確認するべきチェックリストをまとめました。
これでKINECTプロジェクトのスタートも安泰ですね :)

Visual Gesture Builder関連のリソースとか

KINECT v2のSDKおよびセンサー本体のpublic previewがとうとう外れましたね。 正式版になったと同時にKINECT Adapter for Windowsが発表され、センサー自体はXBox Oneと同じものを利用していることが明らかになりました。

今後、KINECTを使って開発をしていく上でジェスチャー認識等が必要になってくるのですが、 ジェスチャー認識を簡単にKINECTアプリケーションに組み込むためのツール Visual Gesture Buidler に関して何回かメモを残していきます。

Visual Gesture Builderとは

Visual Gesture Builderはジェスチャー認識の機械学習を簡単に行うためのツールです。 KINECT SDK v2.0に付属しており、SDKブラウザもしくはスタートメニューから呼び出すことができます。

Visual Gesture Builderでできること

Visual Gesture BuilderからKINECT Studioで保存したストリームを読み込むことで以下の様なことができます。

  1. ジェスチャーのタグ付け
  2. タグ付けされたジェスチャーを認識するためのメタデータの出力
  3. タグ付けされた情報を元に、他のストリーム中のジェスチャーを自動的にタグ付けする

基本的にKINECT Studioで保存したBone Trackingの情報を利用します。 現状ではFace TrackingやColor Streamは扱うことができないので注意しましょう。

学習用の素材

Channel 9などでジェスチャー認識やVisual Gesture Builderに関しての動画が公開されています。

Tipsとか

前述のとおりVisual Gesture BuidlerはBone Trackingの情報を利用してジェスチャー認識を行います。 KINECT Studioでストリームを保存する際にColor Streamの保存をしないように設定するとストリームファイルのファイルサイズを大きく抑えられるので覚えておきましょう。

// ちなみにVisual~ って名前が付いているから今後はIDEの1ブランドになっていくのかしら…。

Windows Azure EventHubs 事始め 3

前回ではEventHubsに接続してアクセスログをコンソールに出力するアプリケーションを作成しました。

今回はKINECTから動態情報を送信し、ASP.NETアプリケーションで受信してクライアント(ブラウザ)に配信するという一連のアプリケーションを作成します。

実際のソースコード

Githubに置きました。今回の範囲はこれこれのPull Requestになります。

データ送信用のKINECTアプリケーションを作成する

これまでと特に変わりありません。今回はKINECT SDK V2 public previewに付属しているサンプルアプリケーション(Body Basic WPF)を利用しています。このサンプルアプリケーションでは人間の手の形(HandState)を判別しています。今回は手の形を判別したタイミングでイベントを送信します。

詳細はこちらのPull Requestを参照してください。

データ受信用のASP.NETアプリケーションを作成する

こちらもこれまでと大きな違いはありません。最終的にブラウザにプッシュ型で動態情報を送信したいので「空のASP.NETアプリケーション」にSignalRを追加して送信された手の形に応じて表示を切り替えるようにしました。

また、このアプリケーションではEventHubClientクラスを利用してEventHubsのクライアントインスタンスを作成する方法をとっています。(これまではMessagingFactoryを利用してインスタンスを作る方法を採っていました)

// use EventHubClient class

EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(GetAmqpConnectionString(), ConfigurationManager.AppSettings["ServiceBus.Path"]);

var defaultConsumerGroup = eventHubClient.GetDefaultConsumerGroup();

両者に大きな違いはありませんが、EventHubClientEventHubs専用 のクラス、MessagingFactoryServiceBusの各種サービスにアクセスするためのクラス と考えればよいでしょう。

さらに、データを受信した際の振る舞いもIEventProcessorを継承したHandStateEventProcessorクラスに実装する方法を採っています。

IEventProcessorはEventHubsに「接続」「切断」「データ受信」した際の振る舞いを登録するためのインターフェースです。ProcessEventAsyncメソッドでEventHubsから送信されてきたデータを受け取ることができますので、SignalRのHubを呼び出してデータを送信するようにしています。

public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
    foreach (var message in messages)
    {
        var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<HandStateEvent>(Encoding.Default.GetString(message.GetBytes()));
        Clients.All.broadcastState(tempData.MachineName, tempData.HandState);
    }

    return Task.FromResult<object>(null);
}

ブラウザで表示するためのスクリプトを記述する

クライアント側は適当にSignalRのイベントを受信するスクリプトを作成し、KINECTで入力されたHandStateに応じてグーチョキパーを表示するようにしました。

詳細はこんな感じ

実際に遊んでみる

EventHubSample.WebプロジェクトをAzure WebSitesなどにデプロイします。 ブラウザ等で正常に表示できることを確認したあとでKINECT v2に接続したPCでBody Basic-WPFを起動し、手でグーチョキパーなどの形を作ってみましょう。

ブラウザのグーチョキパーが手の動きに合わせて切り替わるはずです。

ちなみに

こちらのアプリケーションを使って第25回コンピュータビジョン勉強会@関東でお話をさせていただきました。

資料はこちらTogetter

Windows Azure EventHubs 事始め その2

前回ではEventHubsにアクセスログを渡すアプリケーションを作成しました。

今回はEventHubsに渡されたイベントを購読して利用するサンプルアプリケーションを作成します。

実際のソースコード

Githubに置きました。 今回の範囲はこのpull requestを参照してください。

1. Event購読用のアプリケーションを作成する

今回はEventHubSample.Consoleというアプリケーションを作成し、EventHubsに渡されたアクセスログをそのまま表示するようにしました。といっても、やることは前回と殆ど変わりません。MessagingFactoryクラスからクライアントのインスタンスを作成してメッセージの受信を行います。

送信側との相違点は以下の2点です。

  • Consumer Groupを指定する必要がある
  • Receiverインスタンスを作成してReceiveする

Consumer Groupを指定する

EventHubsは渡されたイベントは指定されたプログラムに従ってそれぞれのConsumer Group(購読者)から購読されます。

EventHubsから配信されるイベントを利用したい場合は、「どのConsumer Groupで購読されているデータを利用したいのか」を指定する必要があります。テレビでいうところのチャンネルみたいなものですね。

今回はとくにConsumer Groupによる制御は行っていないので、普通にデフォルトのConsumer Groupを指定するようにしています。

var group = client.GetDefaultConsumerGroup();

Receiverインスタンスを作成してReceiveする

Consumer GroupからReceiverのインスタンスを作成してデータの受信をします。EventHubsは受信したデータをパーティションキーに従ってそれぞれのパーティションに振り分けて保存していますので、それぞれのパーティション毎にReceiverインスタンスを作成してデータを待ち受けています。

このへんはもうちょっと簡単になりそうな気もしますが、どうなんでしょうね…。ConsumerGroup単位で制御できるとかだといいのですが。

// startTimeを過ぎてからデータの受信を待ち受け始める
var receiver = group.CreateReceiver(partitionName, startTime);
// Receiver#Receive の引数を指定することでクライアントが一度に受信可能なイベントデータの数を制御できます
var message = receiver.Receive(10);

ソースコードの全文が以下です。

2. 動作確認

実際にアプリケーションを起動してみましょう。前回作ったWebページのIndexにアクセスしたタイミングでコンソールにログが出てくれば成功です。

f:id:weathercook:20140930130833p:plain

次回はKINECTやNode.jsなどを使って動態情報を送受信するアプリケーションを作成します。

AngularjsでDirectiveを作るときに考えていること

最近、仕事や趣味でAngularjsのDirectiveを作る機会が何回かありました。Directiveは非常に強力な機能ですが、使い方を誤ると碌なことにならないので現在どのような方針でDirectiveを作っているのかを書きます。

いまや最も優れたJavaScriptフレームワーク「AngularJSリファレンス」出版記念会 イベントレポートでも触れられているように、ベストプラクティスが見つかっていない感じなので色々な人の意見を聞きたいです。

基本的な方針

可能な限りDirectiveは作らない

DirectiveはAngularjsの中でも仕様が複雑で理解しづらく、ファイルが分散するので作るだけの明確な理由がないものについてはDirectiveにするべきではない。Angularjsはビルトインディレクティブが充実しており、大半の問題はこれを利用すれば解決する。無駄な重荷を負う必要はない。

どのような時にDirectiveを作るか

以下の様な場合にDirectiveを作る

  • この実装をDirectiveにせずに放置した場合
    • HTMLが異常に長くなったりネストが深くなったりして、人間が理解できるものではなくなる
    • Controllerのscopeに大量のメソッドが生えることになる
    • 異なる場所で大量のHTMLを何度も書くハメになる

restrict: 'EA' は使わない

作ろうとしているDirectiveが属性的(Attribute)なものなのか、要素的(Element)なものなのかをよく考えて決める。 公式に決まりがあるわけではないが、必ずどちらかに決めて restrict を指定する。

  • Attribute は以下のいずれかもしくは全てに当てはまる場合に用いる
    • テンプレートを展開しない
    • 対象とするDOMに対して何かしらの入力(テキストボックスに値を入れるとか、クリックするとか、ドラッグするとか)を実装することが主な責務である
  • Element は以下のいずれかもしくは全てに当てはまる場合に用いる
    • テンプレートを展開する
    • 対象とするDOMを利用して何かしらの出力(表示とか)を実装することが主な責務である
Attribute Directiveはまだあんまり整理できていない

以下、Attributeとして作成するDirectiveをAttribute Directive、Elementとして作成するDirectiveをElement Directiveと表記する。

Directiveを設計する

BEMで考える

BEMという方法論がある。これ自体はCSSの命名ルール等でよく利用されるが、AngularjsのDirectiveをどう分割するか、どのように設計するかを考えるときのヒントとしてBEMを用いる。

BlockとElement Directiveを対応させる

BlockもしくはModifierの単位でDirectiveを分割する。Blockが入れ子になっている場合は最も外側のBlockから以下の問答をして'Yes'が多ければ子供に分割していく

  • 自分の子Blockを再利用して他のところで使いたいか
  • 自分の子Blockを「もう一度書け」と言われた時に、コードを見ないで書くことは不可能か
  • ユーザがこのアプリケーションを使った時、子Blockに求める機能と親Blockに求める機能が全く別か
Attribute Directive に関しては知見がなくて何も言えない…。

ElementとjqLiteで操作する範囲を対応させる

linkオプションの中でDOM Elementを操作したいケースが存在するかもしれない。それは問題ない。 ただしlinkオプションで提供されるjqLiteオブジェクトのうち、操作して良いのはElementに当たる部分のみである。その範囲を超えてDOMを操作してはいけない。

ModifierとIsolate Scopeを対応させる

原則としてIsolate Scopeを利用する。外部から渡されるオブジェクトは以下のものに分類する。

  • データ
  • Blockの状態(≒ Modifier)

また、以下の様な原則を守る。

  • データとBlockの状態が混在したオブジェクトを渡さない
  • Blockの状態を単一で巨大なオブジェクトとして渡さない

【補足】BEMについて

BEMについての解説はここを参照する。

Directiveを書く

コーディングに関するルールを列挙する。これは正しいかどうか確信がないので信用しすぎないこと。

  • タグ名は '-' 区切りで記述する
  • アプリケーション固有のDirectiveの場合は固有の接頭詞をつける
  • Element DirectiveのテンプレートはtemplateUriを利用する
    • ただしアプリケーションのユースケースを考慮し、リクエストの増大と可読性の高さを天秤にかけること
  • Isolate Scopeのプロパティ=&@はそれぞれの役割を理解した上で利用する
    • 雑に考えると以下の様な分類になる (引用)
      • @ Text Binding
      • & One-way Binding
      • = Two-way Binding
  • 原則としてIsolate Scopeを利用する(親Scopeを継承しない)

Windows Azure EventHubs 事始め

すっかり放置してしまいましたが、MicrosoftからWindows Azure EventHubsがプレビューされています。 Microsoftの一連のIoT戦略の一つであると考えられる本サービスをハンズオン形式で試してみました。

なお、本投稿は以下の記事を実際にやってみた結果のログになります。

Getting started Azure Service Bus EventHubs: building a real-time log stream

EventHubs ?

正式名称がイマイチわかりませんが、引用元のタイトルからわかるようにEventHubsはAzure Service Busに新たに実装されたデータストリームを高スループットで処理するためのサービスです。 現在はプレビューとして公開されており、Azureのサービスポータルからアクセスすることができます。

IoTやデータプロセッシングの分野で利用されることを想定しているようですが、個人的にはIntelligent Systems Servicesからイベントプロセッシングの部分だけをサービス化したようなイメージです。

0. EventHubs用のサービスバスを構築する

では、さっそくEventHubsを利用したサンプルアプリケーションを作っていきましょう。 まずはEventHubsのサービスを作成しておく必要がありますので、Azureのポータルから + new を選択し、 ServiceBus -> イベントハブ -> 簡易作成 をクリックします。

簡易作成の場合はイベントハブ名と地域、名前空間名を指定するだけでイベントハブを開始することができます。 名前空間名はServiceBus名前空間になるので注意してください。

create eventhubs service

作成されるとこんな感じの画面になります。

console of eventhubs

実際にEventHubにアクセスするにはAccess Policyに従ったKeyもしくはConnection Stringを指定する必要があります。今回はデータの送信用・受信用のAccess Policyを作成したうえで、Access Keyを指定してデータの送受信を行うことにします。

ダッシュボードの構成タブからAccess Policyを設定します。今回はデータ送信のパーミッションを持つ LogSender ポリシーと、データ購読用のパーミッションを持つ LogProcessor ポリシーを追加しています。

setup access policy

保存ボタンを押すとポリシー毎のアクセスキーが生成されます。これは後で使うのでメモしておきましょう。

1. Event送信用のアプリケーションを作成する

クライアント側のサンプルとしてアクセスログをEventHubsに送信するWebアプリケーションを作成します。 今回はASP.NET MVC5 Webアプリケーションを使っていくことにしましょう。

まずはテンプレートからMVCアプリケーションを作成します。 面倒なのでアプリケーションのAuthenticationは「なし」に変更しました。

次にEventHubsの関連クラスを扱うためにNugetからライブラリをインストールします。 Microsoft Azure Service Bus Event Hub - EventProcessorHost をNugetパッケージマネージャからインストールしました。

install eventhub library

Traceログを監視してEventを送信するクラスを作成します。

大まかな流れとしてはMessagingFactoryクラスからファクトリを作成し、ファクトリから生成されたクライアントを使ってデータを送信するというシナリオになります。

ソースコードの全文が以下です。

さらに全体を見る場合はGithubにホストしたものを見てください。

上記以外にもJSONシリアライズ用の LogMessageEvent クラスやweb.configの編集などを行っていますが、詳細はGithubのコミットログを参照してください。

最後にControllerクラスで適当にTraceログを出力するようにしたら完成です。

2. 動作確認

実際にアプリケーションを起動してホーム画面を表示してみましょう。 EventHubsのダッシュボードに要求のアクセスが表示されていれば成功です。

access log

これでEventHubsにデータを送信することが確認できました。 次回はEventHubsを購読(subscribe)してデータを受信するアプリケーションを作成してみます。