自習室

こもります

dropmark のビデオプレイリストの再生をループさせるChrome Extension を作った

動機

こんなことがしたい、と思いました

  • 余ってるPC + ディスプレイで、様々な動画を垂れ流しにしたい(会社でシェアしたい)
  • 極力簡単にプレイリストを管理したい
  • YouTube と Vimeo のリンクを貼るだけでOKみたいな感じがベスト
  • 全画面再生
  • ループ

イケてる動画をみんなであつめてそれを垂れ流しておくことで、ふとした瞬間に素敵な動画に出会えるたら良いなーというのが狙いです。

調査

公式

Vimeo だと、Likesなり Watch Laterなり Channel なりを、"Watch in Couch Mode" で再生開始すると、自動的に全画面 + ループになります。

f:id:AMANE:20150301201100p:plain

YouTubeだと、お気に入りなりプレイリストに、「繰り返す」ボタンがあります。これをONにしてから全画面再生すれば良い感じです。

f:id:AMANE:20150301201113p:plain

それぞれ良いのですが、会社で色んな人に登録してもらうとすると、両方のサイトにアップロードされている動画を扱いたくなります。

おしいやつ

Tumblrで動画を集めておくことはもちろん出来ますが、自動で再生していく機能はありません。

同じようなものがないかなーと探していたところ、dropmark というサービスの存在を知りました。

dropmark

自分も今回の目的以外で使ったことがないのでよくわかっていないのですが、いわゆるブックマークサービスです。その中の特徴的な機能として、ビデオのリンクを貼っておくと自動で再生してくれる機能、と言うのがありました。この記事で知りました

これで解決!と思ったのですが、ひじょーに惜しいことに、リストの最後まで行くと、そこで一覧画面に戻ってしまう仕様です。

そこで、Chrome Extensionを使って、ウェブサービスをハックしてみることにしました。

完成品と使い方

ぎっはぶ

ここに上げてあります

使い方

  • コードをPC内のどこかにおく
  • chromeの設定 > 拡張機能 > パッケージ化されていない拡張機能を読みこむ
  • フォルダを指定して開く

現状のコードは、すべてのウェブサイトに対して処理をしてしまうような物にになっているので、dropmarkを全画面で再生し続ける専用のPCを用意できる場合は良いのですが、もしご自身のPCで一時的に試してみたい、と言う場合は、利用しない場合は、拡張機能のリスト中で「有効」のチェックをはずしておくと良いかと思います。

f:id:AMANE:20150301205851p:plain

ついでに

YouTubeの再生を極力高画質で行いたいので、別途それ用のChrome-extension を入れます。この手の物はたくさんあるのですが、こいつはちゃんと動いていました

Vimeoの方は、ある程度大きくプレイヤーが開いたら、自動的に高画質になるので心配ありません。

設計(?)

主に、以下の三つのことをやっています。

  1. プレイリストの最後のビデオになったかの判定
  2. プレイリストの先頭のリンクを取得する
  3. 最後のビデオの次に、プレイリストの先頭のビデオを再生するようにハック

1. プレイリストの最後のビデオになったかの判定

これは、画面中の "Next Item" ボタンのハイパーリンクを見ることで判別出来ます。動画を指すURLではなく、動画一覧を指すURLだった場合は該当です。

f:id:AMANE:20150301202152p:plain

2. プレイリストの先頭のリンクを取得する

プレイリストのHTMLの中身を見て動画の一個目を指すURLを取得すれば良いのですが、実際は「最後の動画を見ている最中に」異なるページのHTMLを参照することになるので、少しトリッキーなことをします。

  1. jQuery<div> 要素を作ってその中にプレイリストのHTMLを丸っと挿入する
  2. その中から該当するHTML要素を見つける
$.get(playlisturl, function(data) {
  var playlisthtml = $('<div>').html(data);

jQueryのgetコマンドで動画一覧のページのHTMLを引っこ抜いてきて、それを <div> タグの中に展開することで、jQueryで解析可能なものにします。ここでこの <div>.append とかしなければ、その要素は表示されたりはしません。あくまでHTMLデータの中身を解析するためだけに一時的に存在するものになります。

プレイリストのhtmlを取得できたら、その中から、お目当ての「先頭の動画」のURLを見つけてきます

var firsturl = playlisthtml.find('.item-preview:first-child').attr('href');

3. 最後のビデオの次に、プレイリストの先頭のビデオを再生するようにハック

1.で、最後のビデオか判定するのに使った "Next Item" の href に、先ほど見つけてきた先頭動画のURLを代入すれば完了です。

まじで?

「えっ…?」って感じでした。次の動画への飛ばし方はちゃんと本家のjs読めばわかるかも知らん、気合い入れて解析してやろう!と意気込んで始めた直後、まぁそんなわけはあるまいと思いつつもものは試しでURL書き換えてやろーと適当こいたところ、出来てしまった、という感じです。結果オーライ、簡単で良かった。やったー

さいごに

と、説明しましたとおり、dropmarkの現状の実装を、偶然も織り交ぜつつ勝手にハックした感じですので、動作保証など一切できません。万が一ご入り用の方がいらっしゃった場合は十分ご理解の上ご利用ください。

3時間くらいで出来て良かったです。会社で運用してみます。

MOVERIOのお出かけ中利用シーン難しさランキング

前説

engadget さんにこんな記事があって

japanese.engadget.com

おっ、と思って脊髄反射で申し込んだら、当選したので、行ってきました。そのときのイベントレポート記事が上がっております。

写真のどこかに、私も写ってますね。私もEngadgetさんの記事が上がる前にレポートを書いておいたらリンクを貼ってもらえたはずでしたので、悔やまれます。

そう、そういうわけで EPSON 様から MOVERIO BT-200AV をお借りしてきました。

半年貸してやるから、7本ブログ書け

とのことです。全力で楽しんでいきましょう。開発にもトライしてみる予定です。

f:id:AMANE:20150317195651j:plain

うまく撮れました。

MOVERIOについて知る

MOVERIOは、公式には、以下の様なコンセプトの商品のようです。以下公式サイトから抜粋

  • 大画面を楽しむ
  • いつでもどこでもパーソナルシアター
  • レコーダーやスマートフォンの映像を楽しむ
  • 高画質・高音質のモバイルビューアー
  • 誰にも邪魔されず、自分だけで楽しめる
  • 好きな姿勢で、好きな場所で
  • 飲食しながらでも楽しめる

などなど。要するに、映像を見る装置です。私もBT-200 を使ってアニメを数本見てみましたが、思ったよりは普通に見られます。

一方で、こうもうたわれています。

  • Androidを採用し、カメラ、GPS機能、各種センサーを搭載。機能を活用した対応アプリで楽しみ方が広がります。
  • モベリオ用のオリジナルアプリが作れる
  • Webブラウジングをモベリオで楽しむ

Androidなので、この眼鏡スタイルを活かしたアプリ体験はいろいろ探索していけそうです。自分もいくつか作ってみたいアイデアを考え中ですので、このブログで報告できたら良いなと思います。

今回は 開発ネタは置いておいて 、メインの「映像を見る」機能についてちょっと考えてみます。どんな時に使えると嬉しいか。そして、それは実際可能なのか。

MOVERIOのお出かけ中利用シーン難しさランキング

考えてみました。難しそうだなーと思った順。

  1. 通勤電車
  2. ショッピングモール
  3. ディズニーランド
  4. 飲み屋
  5. ファストフード店
  6. 喫茶店(特にスタバ)
  7. お散歩中
  8. 公園・河川敷
  9. ジム
  10. 大学構内
  11. 野球場・サッカー場・競馬場
  12. 飛行機・新幹線・長距離バス

前提

前提として、「出先で映像を見る」という行為をそもそもしそうなシーンを想定しています。言い始めればもっといくらでも候補を挙げられそうですが、

  • コンテンツを見る、という行為をスマホ等でもそもそもしないところは除外
  • 論理的には上記に含まれますが、「1人で映像を見る」という行為が不適切な場合も除外

としています。MOVERIOのまっとうな使い方を考えてみよう、と言うことです。

解説

簡単そうな順に簡単に考察をしてきます

12. 飛行機・新幹線・長距離バス

f:id:AMANE:20150330145821j:plain

公式もおすすめの利用法。手にタブレットを持って持ち上げ続けたり、首を下に向けながら映像を見るのは結構しんどい。自由な姿勢で両手を空けられるモベリオ的には相当妥当な利用法!

車の中でタブレットで動画を見ていると弱い人だと車酔いしますが、「モベリオだったら車酔いしない!」みたいな展開があったりしないでしょうか。これは要調査です。

11. 野球場・サッカー場・競馬場

f:id:AMANE:20150330145911j:plain

ラジオを聞きながら野球や競馬を見る、というのは良くある話ですが、それのTV中継版。対象物が遠距離で焦点のズレも問題なさそう!

と思ったのですが、TV放送を見る方法ってあるんでしたっけ…?

まぁその、待ち時間に見るとか…

10. 大学構内

f:id:AMANE:20150330145919j:plain

ジャンル的には公園・河川敷に近いですが、大学内、特に理工系のキャンパスなら 「実験かな」と思われるので普通にスルーされること間違いなし!

9. ジム

f:id:AMANE:20150330145932j:plain

バイクをこぎながらの動画閲覧は鉄板ユースケースでしょう。ジムによってはスタッフさんに怒られるかもしれないので、真摯な態度で(EPSON社員になったつもりで!)モベリオの良さをアピールしていきましょう。タブレットで動画見てる人なんていくらでもいますしね。 最新のスポーツマンはこれ!くらいの堂々たる態度 を見せられるかがポイントになりそうです。

8. 公園・河川敷

f:id:AMANE:20150330145940j:plain

この辺りから、少し攻めたユースケースになります。そもそも、公園でひとりで動画を見るシーンが余り思いつきませんが、「変な人って思われないかな??」と少しドキドキしながら眼鏡を外で掛ける、わりとソフトな入門編という感じでしょう。たまに通りかかる人に、全く気がつかれないか、変わったサングラス?と思われるか、社交的なおじさんに話しかけられるか、くらいで済みそうですね!

7. お散歩中

f:id:AMANE:20150330145946j:plain

公園や河川敷でこそこそ見るのにスリルを感じなくなったら、次は出歩いてみるのも良さそうです。ただしおそらく結構危険ですので、がっつり映像を楽しみたい方にはおすすめできません。 普段からアニメを2本同時見したり、プログラミングしながらアニメを見ているような玄人の方向け の用法です。

家でビール飲みながらアニメ見てたらお腹に肉が付く一方ですので、お散歩しながら健康にアニメ鑑賞は、2015年のニューオタクスタイルとしてアピールしていけるかもしれません

6. 喫茶店(特にスタバ)

f:id:AMANE:20150330145956j:plain

Macbook

スタバにおけるドヤリングはもはや社会現象とも言えるかと思います。たとえTwitterを見ているだけでも、Mac in starbucks is very おしゃれ。ただのドヤリを超える新世代のドヤリとして、 モベリオドヤリング を提唱してきましょう。店員さんと仲良くなれるかも!

5. ファストフード店

f:id:AMANE:20150330150004j:plain

公式でも結構頭の方でおすすめしている、食事をしながらの動画鑑賞。両手がふさがっていても動画が見れる!モベリオは 録り溜めた深夜アニメの消化に追われる現代人には欠かせないデバイス と言えそうです。忙しいオタリーマンなあなた(誰)、ためしに、殺伐としている吉野家で、黙々と大盛つゆだくをかっこみながら幸腹グラフィティを見る、というのはいかがでしょうか。

4. 飲み屋

f:id:AMANE:20150330150027j:plain

今回のモニターで借りている人みんなで、塚田農場で MOVERIOオフ会 なんかどうでしょうか。良く訓練された浴衣ギャルの塚田農場店員は、きっと笑顔で「えーそれなんですかぁー?」と聞いてくれるに違いありません。 これぞ商機。

3. ディズニーランド

f:id:AMANE:20150330150038j:plain

プーさんのハニーハント、2時間待ち!みたいな時こそ、モベリオです。初めの1時間くらいはなんとかたわいもない話で持ちますが、次第に間が持たなくなってきます。こんな時こそモベリオ。なんなら2人で互いにモベリオ。サングラス代わりにもなってちょうど良い感じです。アニメを一話見終わる度に感想を語り合えば、2時間でも3時間でも待てそうなものです。

ディズニーランドはリア充の聖地かと思いきや、コアなネズミファン達の強烈なオタク感はすさまじいものがあります。ちょっと変わった眼鏡を掛けているくらいでとやかく言われる筋合いはありません。どんどんかけましょう。

2. ショッピングモール

f:id:AMANE:20150330150045j:plain

いつまでも終わらない奥さんのお買い物に付き合うのに疲れたら、最後の力を振り絞り最高の笑顔で理解ある夫を演じつつ「終わったら呼んでー」と奥様を送り出し、フードコートに腰を下ろしてモベリオを取り出します。

しかしそこは大量の親子連れであふれかえっています。

通りかかった子供「なんかかっこいいめがねだよー」
そのお母さん「しっ、見るんじゃありません」

なんて、ほほえましい風景もあるかもしれませんね。

1. 通勤電車

f:id:AMANE:20150330150051j:plain

個人的に最強のユースケースがこれ。

満員電車、周りはおっさんだらけ、顔近いっす、あなたの後頭部なんか見たくないっす。いやおねえさん、別にあなたのこと見つめてないっす偶然そちらしか向けないだけです! 手が挙げられなくてパズドラもできねぇ! なんて日常も、モベリオで一変します。

乗り込む前に再生開始。満員電車の不快な30分が快適アニメタイムに!

というシナリオなのですが、同時に変な人と思われるリスクもひじょーに高い。痴漢えん罪怖いです。あまり世の中に普及しているデバイスというわけでもないので、モベリオかけてるだけで「この人ちかんです!」と言われるリスクが無いわけではありません。この季節、花粉症もあってマスクをしてたりもしますので、より一層怪しいです。

女性ならそんな心配もありませんので、ぜひ試してみていただきたいです。

最後に

途中のディズニーやショッピングモールは冗談として、通勤電車ユースケースは(マスクが取れた頃に)勇気を出してトライしてみたいです。かなり実益があると思われる用途が同時に非常に危険度が高い、というのはなんともモベリオという商品の難しさを表している気がしますが、そこんとこぶち破っていきたいです。

最初に紹介したブロガーイベントでは、エプソンの中の人が電車の中で使っている様子をちゃんと動画にしてレポートしてたりして、がんばるなぁと思ったのですが、そういえば割と美人の女性の社員さんでした(笑)

MOVERIOは電車の中でも使える!(※ただし美人女性に限る) ってわけですね。

冗談はほどほどにして

開発ネタと並行して、「こんなところで使ってみた」レポートも、ブログとして書いていこうと思います。

フリー素材最高

今回はじめて自分のブログでフリー写真素材を使ってみました。フリー素材を使った記事感が見事に出てますね!

ブラウザ上の開発環境 "CLOUD PEBBLE" で Pebble アプリの開発をしてみた

はじめに

Kick Starter で、とんでもない額の投資を得て話題になっています。$500,000- の目標に対し、3月8日午前時点で $16,816,735- の投資を集めています。達成率で言うと3000% です。

公式:

追って発表された、Pebble Time Steel と Smartstrapsについての記事:

欲しい

Apple Watchも話題になっています。むろん、表現力やアプリの作り込み、コミュニティの大きさは圧倒的だと思われます。一方で、電池もちはだいじょうぶか?と心配されています。 Pebble Timeは e-paper のおかげで(カラーにもなったのに!) 一度の充電で7日間*1使える、という点で、Android Wear のプロダクト等と比較してもかなり特殊な立ち位置にいます。

自分はApple Watchも結局買ってしまうかもしれませんが、いつもそこにいて、ちらっと見る、という従来の時計に近い使い方が出来る(と期待できる)Pebble Time を結構楽しみにしています。

SDK

カラー画面に対応したSDKが公開されました。まだ現物はありませんが、おもしろそうなので開発してみようと思いました。Android Wear や Apple Watch ほどは流行らないかと思いますが、長時間駆動可能という特性を活かした体験を作れると良いなぁと思います。

開発者向けの情報はこちらのサイトにまとめられています。既存Pebble向けのSDK Ver2系と、カラーに対応したSDK Ver3が入手できます。それらのインストールガイド、APIのドキュメントや、チュートリアルもまとめられています。

サイトがお洒落です。

Mac の開発環境 (割愛)

チュートリアルをやる分には、Macの開発環境と CLOUD PEBBLE での開発には差が無いようです。もちろん最終的に完成したアプリをPebble本体にインストールする際にはMac上に開発環境を構築する必要がありますが、手始めにちょっと触ってみたいという今回みたいな段階では、ビルド、エミュレーション出来る環境が0ステップで手に入るのはかなりありがたいです。

また、アプリの設定系の .json ファイルを、いちいち手書きしていくのではなく、埋めるべきところをGUIで埋めていく形式で書けるのも、CLOUD PEBBLE の優れているところです。手始めには、CLOUD PEBBLEを使うのが良いでしょう。

と言うわけで実際は一応Macの開発環境も作ったのですが、今回は割愛いたします。

CLOUD PEBBLE

ブラウザ上で動くPEBBLE のIDE + シミュレーション環境、CLOUD PEBBLE ですが、少しワークフローが特殊だったので、簡単にまとめておきます。とりあえず、アカウントを作成してログインして下さい。

プロジェクトの作り方

主に三つあります

  1. テンプレートから作成する
  2. ローカルからzipでインポートする
  3. GitHubからインポートする
1. テンプレートから作成する

PROJECTSタブ > CREATE で新しいプロジェクトを作成します

f:id:AMANE:20150308125227p:plain

この状態だと、SDK2.0 準拠のプロジェクトも選択出来ます。SDK2.0準拠の場合は、C言語だけではなく、 simply.js や pebble.js といったjsの方言での開発も可能です

f:id:AMANE:20150308125417p:plain:w550

が、ここでは SDK3.0を使いたいのでそちらをえらびます。すると、Project Typeはえらべなくなり、C言語での開発のみとなります。今後アップデートされると、js系も使える様になるのかもしれません。

f:id:AMANE:20150308125510p:plain:w550

ここでえらべるテンプレートは、基本的にSDK2系の頃のサンプルのようです。基本を抑えるにはこのサンプルを色々読んでみると良さそうです。

2. ローカルからzipでインポートする

既にローカルにプロジェクトがある場合は、それをzipにまとめてアップロードできます。

先に1. の手順で作ったプロジェクトを、zip でDLすると、必要なファイルとディレクトリ構成がわかるので、それがちゃんとパックされた物をアップロードすればOKです。チュートリアルをCLOUD PEBBLEでやる分には、zipでインポートをする事は無いと思います。

3. GitHub からインポートする

SDK3系のサンプルは、GitHub上に上がっています。

このページ中のスクリーンショットをクリックすると、それぞれのプロジェクトが上げられているgithubに飛びます。これらをCLOUD PEBBLEに取り込むことが出来ます。下図のように適当な名前をつけ、対象リポジトリのアドレスを指定し、IMPORT すれば、CLOUD PEBBLE上で扱えるようになります。

f:id:AMANE:20150308142800p:plain:w550

また、先にGitHub上で Fork して自分のプロジェクトとした物を、CLOUD PEBBLE にインポートして、その際に "USE AS GIT REMOTE" にチェックを入れておくと、CLOUD PEBBLE上で編集した結果を、GitHub上に再度Push出来るようになります。

f:id:AMANE:20150308144659p:plain:w550

f:id:AMANE:20150308144913p:plain

さすがにCLOUD PEBBLE上でローカルコミットを作る機能は無いようで、毎回origin/masterに対しpushする形となります。あらかじめ GitHub 上でブランチを作っておいて、そのブランチをCLOUD PEBBLE上にpullし、編集するようにすれば良いでしょう。

GitHubとの連携

上記3で説明しましたように、プロジェクトをGitHubからインポートした場合は、そのGitHubリポジトリをそのままリモートリポジトリとして運用することが出来ますが、1や2の手順でCLOUD PEBBLE上のプロジェクトとした物については、後からGitHubに突っ込むことは出来ないようです。もし既存のプロジェクトをどうしてもGitHubで管理したい場合は、一度プロジェクトをzipとしてDLして、それをGitHubに突っ込み、再度3.の手順でCLOUD PEBBLEに取り込むと良いかと思います。

ビルド、実行

ビルドの方法は2種類有ります

  • COMPILATION > RUN BUILD して、INSTALL ON BASALT
  • コードの画面で、右上の緑色の "Save, Build, Install and Run" ボタンを押す

f:id:AMANE:20150308151807p:plain

f:id:AMANE:20150308151815p:plain

左上のPebbleのウィンドウ内にアプリが表示されれば成功です

f:id:AMANE:20150308151958p:plain:w600

操作法

Pebbleウィンドウの周囲四つのボタンを、マウスクリックで押すことが出来ます。

ログの出し方・見方

C言語の場合 APP_LOG() マクロを利用します

 APP_LOG(APP_LOG_LEVEL_INFO, "Outbox send success!");

js の場合、 console.log() 関数を利用します

console.log("Temperature is " + temperature);

ログの見方は2種類有ります。

  • インストール直後のモーダルウィンドウで、 "VIEW LOGS" をクリックする
  • COMPILATION > VIEW APP LOGS をクリックする

f:id:AMANE:20150308152941p:plain:w550 f:id:AMANE:20150308152951p:plain

これで、ログを見ることが出来ます f:id:AMANE:20150308153210p:plain:w600

[PHONE] と書いてある行は、PebbleKit.js 内で console.log() で出力された内容です。 [INFO][DEBUG] は、Cのファイル中から、APP_LOG() で出力された内容です。APP_LOG_LEVELについては、こちらを参照

チュートリアルを流してみる (CLOUD PEBBLE)

チュートリアルは上から順に通していけば良いと思いますが、数カ所の要点だけメモしておきます

チュートリアルのコードは、チュートリアル本文中のリンクから、CLOUD PEBBLEのプロジェクトとしてインポートできる

f:id:AMANE:20150308162419p:plain

上の図の様なリンクがあったら、そこを押すと、その時点のチュートリアルのプロジェクトをCLOUD PEBBLEに取り込むことが出来ます。これをやりながらチュートリアルを進めると良いと思います。

FONTや画像の取り込み方のちょっとしたコツ

ぽつぽつ引っかかったので。

ひとつの .ttf ファイルに対し複数のサイズでフォントを定義する

フォントは、取り込んだひとつの.ttfファイルに対し、複数のサイズで定義しておくことが出来ます。複数定義されていると、RESOURCES のなかのフォントファイルにマウスオーバーすることで、定義されているフォントを確認出来ます。

f:id:AMANE:20150308163738p:plain

サイズを追加するには、.ttf ファイルを選択して、一番下までスクロールし "ADD ANOTHRE FONT" して、"IDENTIFIER" の最後の _24 みたいなサイズの数値を、使いたいフォントサイズに変更して SAVE します。

.c コード中での画像リソースへのアクセスの仕方

画像ファイルをアップロードすると、下の画面のように表示されますが、ここに出ている "IDENTIFIER" の文字列「そのもの」では、.c コード上で扱う事が出来ません。なぜかそんな仕様です。

f:id:AMANE:20150308164714p:plain:w600

この画面に表示されている "IDENTIFIER" 文字列の先頭に、 "RESOURCE_ID_" とつける必要があります。たとえばこの場合は

  s_background_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND);

で、使える様になります。なぜかそんな仕様です。気をつけましょう。

AppMessage の使い方

スマホ側で動くPebbleKit.jsと、Pebble本体で動く .c 言語間でデータのやりとりをする AppMessage ですが、少し手続が煩雑でした。

スマホ側(JS)
1. {key: value} のオブジェクトを作る
2. SETTINGS で、1. で作ったオブジェクトに含まれる key を登録する
3. Pebble.sendAppMessage(object, ... で送り出す

Pebble側(C)
4. static void inbox_received_callback(DictionaryIterator *iterator 関数で
    DictionaryIterator インスタンスに格納された状態で受け取る
5. Tuple *t = dict_read_first(iterator); でオブジェクトのメンバの一つ目を読み出す
6. t->key で、データの種類を調べて、 t->value でデータを読み出す

サンプルの場合、 1と3 で以下の様にメンバをオブジェクトに突っ込んで送ろうとします

var dictionary = {
    "KEY_TEMPERATURE": temperature,
    "KEY_CONDITIONS": conditions
};

// Send to Pebble
Pebble.sendAppMessage(dictionary,

これを、ちゃんとC側で受け取れる様にするには、SETTINGSの画面で、2のステップで以下の様な登録をしておく必要があります

f:id:AMANE:20150308221257p:plain

また、6 で t->key としてデータのキーを調べますが、このときに参照されるのは、 KEY_TEMPERATURE といった文字列ではなく、2 で登録した Key ID (0とか1とか)の方ですので注意が必要です。

さいごに

一通りチュートリアルを通すことで、CLOUD PEBBLEの使い方と、コーディングの仕方がなんとなーくわかりました。これをベースに、watchface(時計のテーマ) や watchapp(Pebbleのアプリ) を作っていこうと思います。

ちょうど、ustwo が "Watch Face Design Guidelines" というのを出していたり、明後日が Apple Watch の発表(おそらく)だったり、またスマートウォッチ界隈が動き始めているので、その辺りを参考にしながら、自分なりのスマートウォッチのあり方を模索してみたいです。

*1:Pebble Time Steelに至っては10日間!

Kinect, OpenCV, openFrameworks のカラー画像を相互に変換する

はじめに

以前の記事で KinectColorFrameReader から得た画像を ofImage 形式に変換して描画したりしましたが、いろいろ調べてみると、Kinect の画像形式から直接 ofImage に変換している例は意外と少ないようでした。そりゃまぁカラー画像をそのまま取得するだけだったらわざわざKinect使わんわい、という話だと思います。

それで、OpenCV も一緒に利用するケースを考えてみました。

f:id:AMANE:20150209231053p:plain

この三者間を画像データが行き来出来れば、柔軟にプログラムが出来そうです。

oF 内で OpenCV を利用する方法について

先日の記事ではoFでKinect for Windows SDK 2.0 を使う手法について調査検討しましたが、OpenCVについても同様に調査します。

大まかには、以下の方法があると思います。

  • 公式の ofxOpenCV を使う
  • kylemcdonald/ofxCv を使う
  • OpenCV を直接叩く
公式の ofxOpenCV を使う

OpenCVのバージョンは2.3.1です。ofxCvColorimage など oF での編集や描画がしやすいようアレンジされた画像クラスが利用できるのは便利です。公式のアドオンですが、IplImageを使っている箇所があったりするあたりはイケてません。そしてちょっと古い。

kylemcdonald/ofxCv を使う

内部で ofxOpenCV のアドレスを見ているので、利用しているのは ofxOpenCV と同様に 2.3.1 です。toCv() toOf() という多目的の関数があり、以下の様な変換が可能です。これは非常に便利です。変換可能な組を一部抜粋します。

- ofVec2(3)f --- Point2(3)f
- ofImage --- cv::Mat
- ofRectangle --- cv::Rect

詳細はコードをご参考 ofxCv/Utilities.h at master · kylemcdonald/ofxCv · GitHub

OpenCVはちょっと古いのですが、一方でコード中で ofDraw** という openFrameworks 0.9 系で採用される予定の記述があったりもし、いくつかのサンプルがビルドできませんでした。これの修正も結構大変そうです。

OpenCV を直接叩く

ofxAddons では無いので導入は若干面倒ですが、最新の機能を全部使える様になります。ただし、画像のデータなど、自分で変換する必要があります。

どうするか

ofxCv が素直に使えれば良かったのですが、先述の通りの問題があったりするのが玉に瑕で、Kinect for Windows SDK 2.0 を直接叩くのと同様の理屈で OpenCV も直接使えば良いじゃん、という結論になりました。OpenCV の生コードを書くのが何だかんだ楽です。

ところで、ofxCv はその目標に以下の様な物を掲げています。

Provide clean implementations of all functions in order to provide a stepping stone to direct OpenCV use.

と言う風に素のOpenCVも書けるような仕様になっているらしいので、ちゃんと ofxCv がまとまり oF も 0.9 に上がった暁には、 ofxCv を利用するのも良いかもしれません。

環境

openFrameworksv0.8.4 を Visual Studio Community 2013 で使う方法については、先日の記事をご参照ください

また、Visual StudioOpenCV を用いて開発する方法については、下記ブログなどをご参照ください

完成品はあげてあります

解説

ウィンドウが複数開いて大量に絵が出てきますが、下図の様な変換を行っています。

f:id:AMANE:20150209231104p:plain

以下ポイントだけ説明いたします ofImage と cv::Mat の相互変換については、先述の Kyle先生の ofxCv から toCv toOf 関数の実装を参考にさせていただいております。

ofImage -> cv::Mat

cv::Matコンストラクタに、配列の中身になる実データを指定出来るものがあるので、ofImageから実データを引っこ抜いて利用します。

// ofImage ofColor; ... ofVideoGrabber からデータを引っこ抜いたモノ
ofColor.allocate(CAM_WIDTH, CAM_HEIGHT, OF_IMAGE_COLOR);
cv::Mat cvColor = cv::Mat(CAM_HEIGHT, CAM_WIDTH, CV_8UC3, ofColor.getPixels());

cv::Mat のドキュメントによると

data – Pointer to the user data. Matrix constructors that take data and step parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.

ということで、cv::Mat は実際は ofImage の確保しているデータを直接参照します。メモリの無駄がない、と言うことです。

また、ofImage は標準で RGB 配列ですが、 OpenCV では BGR 配列が標準ですので、変換が必要です

// #include <opencv2/imgproc/imgproc.hpp>
cvtColor(cvColor, cvColor, CV_RGB2BGR);

cv::Mat -> ofImage

// ofImage ofCropped;
ofCropped.allocate(CROPPED_WIDTH, CROPPED_HEIGHT, OF_IMAGE_COLOR); 
ofCropped.setFromPixels(cvCropped.ptr(), cvCropped.cols, cvCropped.rows, OF_IMAGE_COLOR, false);

cv 側でROIを決めてクロップした画像の生データ、のポインタを教えて sestFromPixels 関数で ofImage を作ることが出来ます。 四つ目の引数を false とすることで、BGR配列のデータでも直接 ofImage にRGB配列で突っ込むことが出来ます。

(Kinect) ColorFrame -> cv::Mat

// unsigned char* bufForColorFromKinect;
int nBufferSize = KINECT_CAM_WIDTH * KINECT_CAM_HEIGHT * 4;
bufForColorFromKinect = new unsigned char[nBufferSize];
hr = colorFrame->CopyConvertedFrameDataToArray(nBufferSize, bufForColorFromKinect, ColorImageFormat_Bgra);
cv::Mat cvColorFromK = cv::Mat(KINECT_CAM_HEIGHT, KINECT_CAM_WIDTH, CV_8UC4, bufForColorFromKinect);

Kinect画像の生データをバッファにいったんコピーして、それを使って先ほどと同様に cv::Mat() を作成します。 CopyCOnvertedFrameDataToArray() 関数で、ターゲットとなるフォーマットを指定するのがポイントです。cv::Mat のアルファ付きカラー画像は BGRAが標準です。

(Kinect) ColorFrame -> ofImage

// ofImage ofColorFromK;
ofColorFromK.allocate(KINECT_CAM_WIDTH, KINECT_CAM_HEIGHT, OF_IMAGE_COLOR_ALPHA);
int nBufferSize = KINECT_CAM_WIDTH * KINECT_CAM_HEIGHT * 4;
unsigned char* data = ofColorFromK.getPixels();
hr = colorFrame->CopyConvertedFrameDataToArray(nBufferSize, data, ColorImageFormat_Rgba);
ofColorFromK.update();

先ほどと同様に ColorFrame からデータを変換しつつバッファにコピーしますが、今回は ofImage ofColorFromK を事前に確保しているので、書き込む先の実データのポインタを直接指定できます。また、ofImage では色のフォーマットは RGBA になります。

最後の update() を忘れずに。

cv::Mat、ofImageから(Kinect)ColorFrameに戻す

Kinectの画像形式に戻すことは無い気がするので、ここでは割愛いたします。

さいごに

グレーの画像だったり、Depthなどビット深度の異なる画像も、CVの方で CV_8UC3 等と指定している画像のデータ形式を合わせることで対応出来ると思います。

少々面倒なところもありますが、ofxCv を使う場合より現時点では汎用性が高いと思います。活用していきます。

長期展示や実験の運用のため Windows8.1を定期的に自動再起動させる

はじめに

f:id:AMANE:20150202202006j:plain

展示や実験の運用で、定期的にPCを休ませたい、自動的に再起動してリフレッシュした後・展示・実験を再開したい、というニーズがあると思います。ありました。そのための手法を考えてみました。

修正

投稿当初、以下の様に書いていたのですが

Microsoft アカウント を利用しているとパスワード解除ができず、PCの再起動をしたとしてもログイン前で止まってしまいます。MSアカウント を利用されている方は、以下の手順でローカルアカウントログインに変更します。

その後調べていたら、MSアカウントでもパスワード無しで起動時ログイン出来ることがわかりました。その点について修正しています。

前提

- Windows8.1
- Microsoft アカウントを利用したまま、パスワードを不要にする **または**
- Microsoft アカウントでのログインは利用せず、マシンのローカルアカウントログインとする
- その上で、パスワードを解除してマシンを運用する
- BIOSに、Auto Power On 的な機能がないものとする

Windows 8.1 としましたが、おそらくwindows7,8 でも同様に可能だと思います。

Auto Power On があれば

完全にシャットダウンした状態からでもマザーボードの持っているタイマーで起動ができるので、本記事で説明するような 必要時間休止→復帰→リブート というプロセスを通る必要がなくなります。

本記事では、Auto Power On的な機能がない場合にどうするか、について説明していきます。

Auto Power On については下記記事を参考にされてください

MSアカウント でのログインのまま、起動時のパスワード入力を不要にする

下記サイトの方法で可能です

(または)ローカルアカウントにし、パスワードを解除する

Microsoft アカウント を利用しているとパスワード解除ができず、PCの再起動をしたとしてもログイン前で止まってしまいます。MS ID を利用されている方は、以下の手順でローカルアカウントログインに変更します。

ローカルアカウントを使用すると、パスワードをそもそも設定しないことが出来ます。

この工程の一番最後で、パスワードを入れて確認するところがありますが、ここを空白のまま「次へ」進むと、パスワードが解除された状態でローカルアカウントに切り替わります。

ちなみに、MSアカウント時代のデータが消えたりはしないのでご安心ください

工程

全容はこんな感じ

1. 展示・実験の終了時刻になったら、動いていたプロセスを殺して、PCをシャットダウンできる状況にする
2. ハイバネーション(休止)状態にする
3. 展示・実験の開始時刻の少し前に、タスクスケジューラの機能でハイバネーション(休止)から復帰する
4. 再起動する
5. 展示・実験に必要なプログラムをスクリプトで起動する

先述の通り、Auto Power On が出来ないためシャットダウンはせず、しかしハイバネーションさせることで極力PCを休ませたのちリフレッシュのために再起動する、という作戦となっています。

一個ずつ見ていきます

1. 動いていたプロセスを殺す + 2. ハイバネーション

バッチファイル作成

以下のようなバッチファイルを作成して適当な場所に置いておきます

rem
rem goToSleep.bat
rem

echo "kill all apps and go to Hibernation"

taskkill /im "iexplore.exe" /f

timeout /T 10

taskkill /im "notepad++.exe"

timeout /T 20

rundll32.exe PowrProf.dll,SetSuspendState

ここでは、 IEと "notepad++.exe" というアプリが仮に展示で使われていると仮定して、それを殺し、20秒待った後、ハイバネーションに入る、というバッチとなっています。

ハイバネーションは、setsuspendstate というWindowsAPIを使うことで実現しています。

rundll32.exe の罠

このStackoverflow のスレッドでは、 rundll32.exe PowrProf.dll,SetSuspendState 0,1,0 でスリープする、と言っていますが、これは間違いなようです。私も数パタン試してみましたが、最後のbool三つの「引数のような指定」はおそらく機能しておらず、すべてハイバネーションしています。APIのデフォルトの動作なのでしょうか。

この状態でも今回の目的は達成できているとも言えるのですが、もし何かしらの理由でハイバネーションできない/したくない場合は、正しくスリープのAPIを呼ぶ必要があります。プログラムからスリープを呼ぶ方法は、以下のページ様の手法で確認が出来ました。

これをちょっとカスタムして、以下のコードでプロジェクトを作って、exe をはき出しておきます。

// これを、 GoToSleep.exe としてビルド

#include <Windows.h>
#include <powrprof.h>
#pragma comment(lib, "powrprof.lib")

int main()
{
    SetSuspendState(FALSE, FALSE, FALSE);
    // 第1引数がFALSEだとスリープ、TRUEだと休止(hibernation)
    return 0;
}

その上で、バッチファイルを書き換えます

rem rundll32.exe PowrProf.dll,SetSuspendState
cd <PATH_TO_EXE>
start GoToSleep.exe

これで正しくスリープ / 休止が出来ます。

タスクスケジューラに登録
  • コントロールパネル > システムとセキュリティ > 管理ツール > タスクスケジューラ でタスクスケジューラを開きます
  • 基本タスクの作成 をクリックすると、タスク作成のウィザードが始まり、埋めていくことでタスクを登録できます。
  • 名前を適当につけます。 goToSleep とか
  • PCをハイバネート/スリープ させたい周期を考えてトリガーに登録します (たとえば、「毎日、20:30」 など
  • 操作として、先ほど作成したバッチを登録します

このスクリプトについては、タスクのオプションをいじる必要はありません

3. ハイバネーションから復帰 + 4. 再起動

バッチファイル作成

Windows 標準のタスクスケジューラの機能で、ハイバネーション or スリープ から復帰することができます。

以下のようなバッチファイルを作成して、適当な場所に置いておきます

rem
rem wakeFromSleepAndReboot.bat
rem

echo "wake from sleep and reboot"

timeout /T 20

shutdown -r -t 10

ここでは、20秒待ったのちリブートする、というスクリプトになっています。

タスクスケジューラに登録

今回、ハイバネーション/スリープからの復帰は、タスクスケジューラの機能を用いて行います。まず一個前と同様に作成したバッチをタスクスケジューラに登録します。

その後、登録したタスクのプロパティを開き 条件 タブ中の 「タスクを実行するためにスリープを解除する」 にチェックを入れます。

f:id:AMANE:20150202201830p:plain

これで、ハイバネーション/スリープ中であっても、登録したバッチが実行されるようになります。

このあたりについては、こちらのサイトで紹介されていました。

5. 必要なプログラムの起動

バッチファイル作成

複数のプログラムを順に起動したい場合も多いと思うので、これもバッチを作ります。

例として、notepad++ と IE を起動します。(意味はとくにありません(>_<))

rem
rem launchApps.bat
rem

echo "launch apps"

cd "C:\Program Files (x86)\Notepad++"
start notepad++.exe

timeout /T 10

start iexplore.exe

exit

notepad++ を起動した後、10秒待って、Internet Explorer を立ち上げます

タスクスケジューラに登録

ここでは上二つのバッチとは異なり、時刻指定ではなく、スタートアップを引き金としてアプリを立ち上げる指定にしてみます。起動からPCが色々立ち上げたり、ネットワークがつながって落ち着くまでの時間を多少取った方が良いかとも思うからです。

「基本タスクの作成」のウィザードで、トリガー を「コンピュータの起動時」にします。これでも十分かもしれませんが、更に少し余裕を持たせるために、開始を遅延させます。

  • タスクスケジューラの一覧から今登録したタスクのプロパティを開く
  • トリガースタートアップ時 を編集します。
  • 遅延時間を指定する にチェックを入れて、適当に時間を設定します。たとえば起動後1分。

f:id:AMANE:20150202195533p:plain

これで、上記のバッチは起動後1分で実行されることになります。

完成!

以上で、定期的に再起動する仕組みができました。ハイバネーションの設定周りで、PCごとに差があるかもしれません。その辺りは各自柔軟に対処、と言うことで。

Sleep / Standby / Suspend / Hibernation / Hybrid Sleep について

今回、setsuspendstate の挙動で結構はまっていろいろ調べたところ、日本語と英語の間、また、プログラマWindowsの一般ユーザ の間で、スリープや休止に関する言葉の使い方がそれぞれ異なることがわかりました。ここに整理してまとめておきます。

参照

Sleep == Standby == (hibernationでは無い)Suspend == スリープ、スタンバイ

メモリ上にOSの状態を残し、メモリにのみ通電を続けるもの。直ぐ起動できるがやや電気を食う。

Hibernation な suspend == 休止

HDD/SSD にOSの状態を保存し、いったんシステム全体の電源を落とす物。やや起動に時間がかかるが、シャットダウン時と同様に電気を使わなくなる

Hybrid Sleep == ハイブリッドスリープ

上の二つの合わせ技。通常はスリープ的に寝ていて直ぐ起動できる状態であるが、電池が切れそうになるとHibernation状態に移行する

初め、Suspend == 休止 だと思い込んでいて混乱しました。

さいごに

もしかすると似たような事をする為のユーティリティソフトもあるかもしれませんが、あまり調べていません。もし良いものをご存じの方がいらっしゃいましたら、教えていただけると嬉しいです。

openFrameworks に Kinect for Windows SDK 2.0 の AudioBasics サンプルを移植する

はじめに

前回、Color画像のサンプルや FaceTracking のサンプルを移植しましたが、今回は Audioのサンプルを移植してみます。

AudioBasics-D2D

このサンプルは、Kinectのマイクをつかって、1つの音源の方向を特定し、方向とその信頼度を可視化しつつ、リアルタイムに音波の強さを描画します。

f:id:AMANE:20150206203741p:plain

音源の方向特定はかなりの精度で出来ていますが、今のところ一方向のみの特定に制約されています。しかし、API複数の AudioBeamFrame を取り出せる作りになっているので、将来的にはもしかしたら、同時に複数方向から鳴っているときも、それぞれ識別できるようになるかもしれません。楽しみです。

本記事の完成品

事前に

ポイントになりそうなところを調べておきます。

マルチスレッド

本家サンプルコードをざーっと読んでみたところ

  • 受け取った音声データの解析・可視化を行うメインスレッド
  • 音声データの受け取りを行うスレッド

の2つがあることがわかりました。SDK本家サンプルではこれを CreateThread 関数や EnterCriticalSection 関数を使ったWindowsらしいマルチスレッドプログラミングで実現していますが、せっかくoFなのでoFのマルチスレッドで実現したいです。

リングバッファの取り扱いと逐次描画

Kinecet SDK を oF に移植するぜ!という主旨からは若干離れるので本記事では特段言及しませんが、

  • 「40byte分のボリュームの平均値」 を、可視化する量より少し多い 1000 個分ためて先頭を記録するリングバッファ
  • その中で可視化する領域の先頭を指すポインタ
  • 前回の描画フレーム後入ってきたデータの量の算出
  • 上記の情報を使って、数秒分を少しずつ進めながらリアルタイムにボリューム可視化する

あたりのプログラムのサンプルとして非常に勉強になりました。

取りかかる

oFでKinect for Windows SDK 2.0 を使う方法の概要については、前回の記事を参考になさってください。

ブロッキング

ofThread のサンプルを参考に、音声データの受け取りを行うスレッドを作ります。受け取る瞬間と、データを絵を描くのに使う配列に移動する瞬間がぶつかるとまずいので、スレッドを立てて、ロックアンロックを行います。

本家では EnterCriticalSection() LeaveCriticalSection()クリティカルセクションを作っているところは、 if(lock()) + unlock() で同様の処理になります。

WINAPIのクリティカルセクションについてはこちらの記事が分かりやすかったです

ofThread は startThread() 引数無しだとブロッキングなスレッドになって、 lock() 時に他でロックしてたら、それがアンロックされるのを待機します。一方 startThread(false) でスレッドをスタートさせるとノンブロッキングになり、if(lock()){} は即時に false を返すので、 if文ブロック内の処理はいったん飛ばされることになります。今回はWINAPIのクリティカルセクションの手法に習って、ブロッキングなスレッドとします。

ofThreadのブロッキングについてはこちらのフォーラムが勉強になりました。 Theo先生直々返答。

ofApp::exit() での処理 WaitForThread()

ofThreadのサンプルは stopThread() 関数で終了させていますが、今回のような音のプログラミングの終了時にこれをやると、データのコピー中等に処理を殺そうとしてしまい、多くの場合エラーを起こします。(エラーが起きない場合もあるようです) ちゃんとスレッド内の処理が終わるまで待ってあげるために、アプリ終了時は WaitForThread() を使いましょう。

それ以外

は、ほぼ本家サンプルのコピーです。すみません。ありがとうございます。

できあがり

描画は、適宜良い感じにしてください!

f:id:AMANE:20150208221425p:plain

openFrameworks で Kinect for Windows SDK 2.0 をまるっと利用する

はじめに

f:id:AMANE:20150201220035j:plain

この記事では、 ラッパなどを挟まず、 Kinect for Windows SDK 2.0 のフル機能を oF 内で直接利用する方法について調べた内容をまとめます。ラッパを利用しないのは、MSDN の公式リファレンスが非常にしっかりしているからです。ネットに転がっているKinect v2 がらみの情報も公式 SDK を直接たたくものが多いので、いまのとこは素で使った方がなにかと幸せな予感がしています。

oF 内で利用することで様々な機能をひっつけやすくなるので、アプリ全体としての構築も楽になると考えています。

環境

Visual Studio は Proの方が幸せですが、ここではExpressの前提ですすめます。

Visual Studio Community 2013 じゃだめか?

個人のデベロッパだと、Visual Studio Community 2013 を使ってアドオンうはうはしたいところです。しかし、公式には openFrameworks は、vs2013 をサポートしていません。そこで片手落ちではありますが以下の手順で ビルド環境としては2012ですが、エディタとしては VS Community 2013 を使って openFrameworks の開発 を行えるようになります。

  • VS Community 2013 とは別に VS2012 Express を入れておくと、VS2012 (v110) のビルドツールが使えるようになります。
  • oF の Project Generator でプロジェクトを作る
  • VS Community 2013 で開くと、通常だとソリューションのコンバートを勧められますが、これをキャンセルします

VS の Solution Explorer で下図のように表示されていたらできていると思います。

f:id:AMANE:20150127133522p:plain

このあたりは、@selflash 氏が説明してくださっているのでご参照ください。

使い方

プロジェクト設定

@kaorun55 先生の記事ではウィンドウズアプリの前提で説明されていますが、プロジェクト設定はoFでも同じです

Kinect for Windows SDK v2.0 で開発する環境を整える(C++編)

  • of の Project Generator でプロジェクトをじぇねれーーとする
  • 追加のインクルードディレクトリを設定する
    C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc
  • 追加のライブラリディレクトリを設定する
    C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Lib\x86
  • 追加の依存ファイルに Kinect20.lib を設定する

シンプルにカラー画像の表示だけ

簡単な作例として、SDK をインストールしたらついてくる公式サンプル Color Basics-D2D をベースに、oFで動かしてみました。Kinect v2 からカラーのイメージをとってきて描画するだけ。

f:id:AMANE:20150201223037j:plain

ofImage か ofTexture か

oF 使い的にはきっと基本的すぎてあれですが、動画をoFで描画する際にどっちを使うといいのかわかりませんでした。

調べてみたところ、下記フォーラムで同様の質問がなされていました。

ofImage は ofTexture を内部で使っていて、メモリの確保なども含めてラップしているクラスなので、描画部分に関しては差はない、とのこと。今回のような Kinect との連携だと、ofTexture を使う場合でも、ColorFrame からpixel配列をいったん引っこ抜いてからそれを ofTextureにloadData する必要があるので、確保するメモリ量的にも差がなさそうです。

コードは #ifdef して両方試しています

あげてあります

Face Tracking も試してみた

つづけて、FaceBasics-D2D というサンプルから、顔認識に関する最低限野部分をoF向けに移植してみました。

f:id:AMANE:20150201223113j:plain

顔出しツラいっすね。写真は悪用厳禁っす。

一生懸命口角を上げたおかげで笑顔判定がYESなのと、(普段かけない)めがね判定がYESなのが確認できると思います。(^^;)

Kinect v2 はボーンやデプスも使って顔認識とトラッキングを行うので、かなりロバストです。本当は顔出し恥ずかしいですが、写真の印刷だとほとんど判定しないのですすすs… Kinect v2 すごいっす。

コード

追加のインポート

FaceTracking の機能は Kinect20.Face.lib という別のライブラリにまとめられているので、プロジェクトの設定でそれも追加する必要があります

  • Kinect.face.h を必要なコードでインクルードする
  • Project Properties 追加の依存ファイルに Kinect20.Face.lib を設定する
(追記しました) ポストビルドコマンドで、dll等必要なファイルを持ってくる

また、oFやKinectwindowsアプリは、VSのビルドコマンド内で、必要なdllなどのファイルをoFやKinectSDKのインストールディレクトリから自分の実行ディレクトリ(exeを出力するところ)にコピーしてきて、それを使ってexeを実行しています。

たとえば Kinect for Windows SDK 2.0 のサンプル FaceBasics-D2D では、下図のような指定で必要なdllなどを取ってきています。

f:id:AMANE:20150212081206p:plain

Visual Studio で oFアプリをビルドする場合は更に、oFアプリの実行に必要なdll等一式も持ってくる必要がありますが、これは、Visual Studio向けのProject Generator でアプリを作成すれば、自動的にコマンドがセットされています。正確には、oFのインストールディレクトリ中に定義されている、デフォルトのプロパティーシートを見ています。

(下図のプロパティシートは、 VIEW > OTHER WINDOW > PROPERTY MANAGER で開きます)

f:id:AMANE:20150212083706p:plain

したがって、今回のケースで言うと、 oF のデフォルトのポストビルドコマンドと、Kinect20.Face.dll 関連のポストビルドコマンドを同居させてあげる必要があります。

プロパティシートがプロジェクトに登録してあったら、その内容は継承されるのかと思ったのですが、どうもプロジェクト固有のプロパティに書いた内容で上書きされる仕様なようですので、すべて記入されてある必要があります。できあがりはこんな感じ。

xcopy /e /i /y "$(ProjectDir)..\..\..\export\vs\*.dll" "$(ProjectDir)bin"
xcopy "$(KINECTSDK20_DIR)Redist\Face\x86\NuiDatabase" "$(TargetDir)NuiDatabase" /e /y /i /r
xcopy "$(KINECTSDK20_DIR)Redist\Face\x86\Kinect20.Face.dll" "$(TargetDir)" /c /y

この状態でビルドすると、ビルド結果の出力で、exeがはき出された後にいろいろコピーしているのがわかると思います。

1>  KinectV2Sample.vcxproj -> F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\bin\KinectV2Sample_debug.exe
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\Assimp32.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\fmodex.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\fmodexL.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\FreeImage.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\FreeType-6.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\glut32.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\libeay32.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\ssleay32.dll
1>  F:\develop\of_v0.8.4_vs_release\apps\myApps\KinectV2Sample\..\..\..\export\vs\Zlib.dll
1>  9 個のファイルをコピーしました
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\FaceAlignment.bin
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\FaceAlignmentColor.bin
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\FaceAlignmentColor27.bin

中略。この辺りは、顔発見のための辞書データなどをコピーしている

1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\HDFaceTracker\ViewModel\left.p.txt
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\HDFaceTracker\ViewModel\right.mod.bin
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\HDFaceTracker\ViewModel\right.p.txt
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\HDFaceTracker\WholeHeadModel\FullHeadMaskVertexCorrespondence.txt
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\NuiDatabase\HDFaceTracker\WholeHeadModel\fullMeanHead60_tri.ply
1>  57 個のファイルをコピーしました
1>  C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\Redist\Face\x86\Kinect20.Face.dll
1>  1 個のファイルをコピーしました

これで実行可能です。

一応あげてあります

コードはかなりやっつけな感じで書いたので、一応上げますが、あまり参考にはされない方が良いかと思います(>_<)

先ほどのリポジトリにブランチとしてぶら下げています。

そのほかのアプローチ

以上のように使えることの確認をしましたが、ここに至る前に、いろいろ Kinect for Windows SDK 2.0 と oF のつなぎ方を調査したので、それもまとめておきます。

Kinect Common Bridge / ofxKinectv2

Kinect Common Bridge は、MSOpenTech コミュニティで開発されている Kinect for Windows SDK のラッパで、そのブランチとして 2.0 向けが開発されています。CinderやoFなどのクリエイティブコーダー向けに使いやすくするのが主目的のようです。

これを使ってoF向けにさらにラップしたのが ofxKinectv2 という addon です。これはまだ Face Tracking のフィーチャをサポートしていません。Color, Depth, Infrared, Body あたりの機能を簡単に使う分にはこれでも良さそうです。

Windows Store 向け

Channel9 (MSのデベロッパー向け広報ブログ) で、 Windows Store App 版での oF + Kinect v2 の記事が紹介されていました。この記事中で、MSOpenTech が Windows Store 向けアプリを生成する変更を加えた Project Generator 込みの oF Fork を紹介しています。もし必要があれば。

Mac

Mac + oF + Kinect v2 をやる場合は、 Theo 先生のこれが使えそうですが、試してはいません。名前かぶってますね。

Unity 使おうぜ Unity

このブログで過去に取り上げましたが、Unity Pro をお持ちならKinect v2 用の公式 UnityPackage がありますので、こちらを使うと楽ちんです。が、SDK 2.0 のフル機能を使えるわけではなさそうです(要調査) *1

さいごに

使えるようになったので、使っていきます。

*1:kaorun55 先生資料によると、FaceやSpeech、Gestureなど結構な部分が使えないようです http://www.slideshare.net/kaorun55/kinect-for-windows-v2-39610207