【書評】C#実践開発手法を読んだ

C#実践開発手法 (マイクロソフト公式解説書)

C#実践開発手法 (マイクロソフト公式解説書)

監訳者の長沢さんに献本していただきました。ありがとうございます。

ひとことで言うと?

全編にわたり、Interfaceの使い方を中心に実践的な開発手法について解説している本です。 人生でいちばん深くInterfaceについて考えました。

読んでよかったことは?

読んでよかったなと感じたのは 自分が手探りでやっていたことにちゃんとした名前がつく、その先が示される こと、 これをやるとこういうことが起きる(だからやる/やらない)ときちんと示されている ことです。

自分が手探りでやっていたことにちゃんとした名前がつく、その先が示される

普段の業務でコードを書いていて、「なんとなくこうやったらよかった」とか「こういう作りだとうまく行かなかった」という諸々が体系だった原理原則として効果が説明され、「こうやるともっと良くなる」というガイドとともに示されている点が非常に良かったです。

「こういう風に書くとなんとなく拡張しやすい…気がする」と書いていたコードが「それはリスコフの置換原則でいうところの共変性、反変性といってな…」という風に説明されると「おおお…!」ってなりますよね。

これをやるとこういうことが起きる(だからやる/やらない)ときちんと示されている

それぞれの理論や原則に基づいたコードやそのコードを使うとどんなコードになるか?というところまで実例を交えて説明されています。実際に自分が書いたコードとGithubのサンプルコードを見比べながら読んでいきましたが、自分が考慮できていなかったところが浮き彫りになって非常につらい面白かったです。

どんな人に勧めるか?

日常的にC#でコードを書いている人はだいたい読んだらいいと思います。最初から通して読むよりも、表紙をみて自分が一番気になる部分から読み始めるのが適した本であると感じています。

おまけ

Kindle版も出ていました。物理本もそんなに分厚いわけではないので好みのものを買ったら良いのでは。

C#実践開発手法 デザインパターンとSOLID原則によるアジャイルなコーディング

C#実践開発手法 デザインパターンとSOLID原則によるアジャイルなコーディング

Ionicがすごく進化しててとても良い

さいきんはPhoneGapでiOSアプリケーションのモックアップをお仕事をしています。 生のPhoneGapで作成するのはやはりちょっとツライので昔の記憶を頼りに色々とフレームワークを検証していたらIonicがすごく良くなっていたので紹介します。

Ionicってなに?

Ionic: Advanced HTML5 Hybrid Mobile App Framework

IonicはAngularJSをベースにしたPhoneGapアプリケーション用のフレームワークです。 この記事はIonic 1.0.0向けに書いています。

Ionicってどんな感じ

前述の通りAngularJSをベースにモバイルアプリケーション向けにカスタマイズされたAPIを提供しています。特徴としては以下の様な感じです。

  • iOS, Android両対応のフレームワーク
  • パフォーマンスチューニングされており、雑に書いてもそれなりにヌルヌル動く
  • CLI, Preview用のアプリケーション, フォーラムなど開発周りで必要になるものがひと通り揃えられている

特にCLIやPreview用アプリケーションのあたりが(モックをガシガシ開発するには)非常に良かったので後述します。

Getting started

ドキュメントを見てください。という感じですがざっと書いておきます。 ちなみにNode.jsのインストールが必要です。僕は node v0.12.2 で開発しました。

$ npm install -g cordova ionic ios-sim
$ cd path/to/develop
$ ionic --help
start [options] <PATH> [template] .........  Starts a new Ionic project in the specified PATH
                                             [options] any flags for the command
                                             <PATH> directory for the new project
                                             [template] Template name, ex: tabs, sidemenu, blank
                                                        Codepen url, ex: http://codepen.io/ionic/pen/odqCz
                                                        Defaults to Ionic "tabs" starter template
      [--appname|-a]  .....................  Human readable name for the app (Use quotes around the name)
      [--id|-i]  ..........................  Package name for <widget id> config, ex: com.mycompany.myapp
      [--no-cordova|-w]  ..................  Create a basic structure without Cordova requirements
      [--sass|-s]  ........................  Setup the project to use Sass CSS precompiling
      [--list|-l]  ........................  List starter templates available
      [--io-app-id]  ......................  The Ionic.io app ID to use

# 長いので割愛

$ ionic start myApp tabs # => myAppディレクトリにテンプレートが展開される
$ cd myAPp
$ ionic serve # => ブラウザ上でプレビューが表示される
$ ionic emulate ios => エミュレータが立ち上がってアプリケーションがプレビューされる, 要Xcode

プレビューアプリがすごくいい

プレビューアプリがすごくいいです。iOSの場合はionic viewというアプリが提供されています。先にダウンロードして起動し、アカウントを登録しておきましょう。

ionic viewでionic.ioのアカウントを作ったら、先ほど作成したアプリケーションをアップロードしてみましょう。

$ cd path/to/myApp
$ ionic upload # => 先にログインしろと言われた場合は ionic login を実行してください

こんだけです。しばらく待つとionic view上にアプリケーションが表示されます。
こんな感じです。
f:id:weathercook:20150611231758p:plain

タップするとプレビューすることができます。
f:id:weathercook:20150611231331p:plain

初回の場合はモジュールをダウンロードするのに多少時間がかかります。 また、新たに ionic upload した場合は "Sync to latest" をタップすることで最新版をダウンロードできます。

CIと組み合わせるともっと楽

毎回 ionic upload するのは非常にだるいのでリポジトリにプッシュしたら自動的にアップロードするようにしましょう。今回は諸般の事情でプレイベートリポジトリが必要だったのでwerckerを使いました。無料でプライベートリポジトリからチェックアウトできるので非常に捗ります。

リポジトリと連携したビルドセッティングの方法などは他の記事を参考にしてください。 今回はwercker.ymlに以下のようなビルドステップを追加しました。

  steps:
    # ionicにデプロイするためのステップを追加した
    - script:
        name: deploy to ionic
        code: |
          npm install cordova ionic
          node node_modules/ionic/bin/ionic login --email [ionic.ioに登録したメールアドレス] --password [登録したパスワード]
          node node_modules/ionic/bin/ionic upload

スクリプトにパスワードを入れるとか、マジでやめましょうね。。。 これでリポジトリにプッシュすると自動的にionic previewで最新バージョンのビルドを確認できるようになりました。

ハマりどころ

  • ionic upload だけ、なぜかproxyの設定が効きません。proxy環境下で作業しているエンタープライズ諸氏は何らかの対策が必要になります。
  • 賞賛したionic previewですが、アプリをプレビュー起動した後に一覧画面に戻る方法がありません。いったんionic preview自体を完全に終了すると一覧画面に戻ることができます。
  • ionicでプロジェクトを作成するとデフォルトで組み込まれるkeyboard-attachプラグインですが、他の入力系プラグインと干渉する場合があります。具体的にはangular-elasticでkeyboard-attachもangular-elascticもキーボードの位置を調整する処理が走った結果、テキスト入力エリアが画面の上端まで移動してしまうという問題が発生しました。特に必要がない場合はkeyboard-attachは無効にしてもいいかもしれません。

全体的に使い勝手がいい

開発周りの面倒な部分がいい感じにフォローされていて気持よく開発ができています。
非常に雑なコードで開発していますが、iPhone5, 6でそこそこヌルヌル動くものが作れているのでモックアップ作成には特にいいのではないでしょうか :)

How to Track Fingers in V2

元ネタ

KINECTでHandGestureをやりたいんだが…

KINECTv2ではVisual Gesture Builderという仕組みが導入されたことで体を使ったジェスチャの検知が非常に簡単に行えるようになりました。 一方で、手のジェスチャに関してはグーチョキパーが組み込みの機能として判別できるものの、それよりも細かいジェスチャを検知しようとすると自分で組み込む必要があります。

Visual Gesture Builderで手のジェスチャを検知しようとしたけれどもできない。どうしたらいいだろう?というのが今回の質問です。

実は幾つか方法がある

KINECTで手のジェスチャ」というのは結構前から話題になっていまして、実はいくつか実現のための選択肢があります。

  1. Aiolos for Kinect v2を利用する

Aiolos for Kinect v2はKinect Hachathonで開発されたライブラリで、Metrilus社が開発を行っています。 以下の様な機能が提供されているとともにデモビデオではOKサインを識別するなどのデモを行っています。

  • それぞれの指を別々に認識できる
  • 指の第1〜第3関節を識別できる

現在はalphaリリースということであくまで experimental 品質であること、 60日 の限定ライセンスであることに同意すればtrial versionを利用することができます。 申し込みページはこちら

  1. MS Researchの論文を利用する

当然といえば当然ですが、MicrosoftKINECT(というか深度センサー)を利用してHand Detectionを実現できないか研究しています。 実際に幾つか論文や実装が出ており、以下のようなリソースが利用可能です。

Realtime and Robust Hand Tracking from Depth (2014)のデモ

デモの見た目としては2015年の論文の方が洗練されていますが、原理的にはどちらも深度センサーを利用したHand Detectionであることが伺えます。 2014年のものは論文も出ていますので、時間が許すのであれば自分で実装してみるのもいいような気がします。 *1

KINECTを利用した手のジェスチャについて調べました。製品レベルのものはまだ存在しないようなのでOSSとかで開発できればバズりそうな感じがしますね :)

*1:2015年の論文は4月頃に公開されるようです

FaceShapeDeformations and Action Units

元ネタ

FaceShapeDeformationsプロパティが表す意味はなに?

Kinect HD Face APIでは顔の形状や動きをプロパティとして取得することができます。実際のプロパティには以下の様なものがあります。

Quaternionはそのまま回転のプロパティとして使えばいいのですが、3つあるEnumプロパティの内、FaceShapeAnimation, FaceShapeDeformationsではドキュメントのDescriptionが空欄のままであり、どんな意味合いを持つのか分かりません。特に FaceShapeDeformations プロパティは PCA01, PCA02など、どんな意味合いを持つのか推測も難しいため、「どうやって使うのか」「他のプロパティとの関連性はなんなのか」といったことが分からない!という投稿になっています。 *1

「そうだよな…。すまんかった」という回答

回答ではドキュメントが分かりにくいことは理解している、今後この辺りのドキュメントを改善していく予定である旨が告げられています。 また、各プロパティの詳細については Confused about face tranking, points and animationsのスレッドで紹介されているので、そこを参照するようにというアドバイスでした。

で、結局プロパティの意味は?

※ここから先は自信がないのであまり信用しないでください。

FaceShapeDeformations, FaceShapeAnimationsはそれぞれShape Unit(SU), Animation Unit(AU)をプロパティとして持っています。

SUはその名の通り顔の形状を表すプロパティでKINECTのセンサによって検知された顔の3Dモデルの形状的特徴を表してます。従って、トラッキングされている間、もしくは顔の3Dモデルが再度ビルドされるまでの間はSUの値が変化することはありません。

一方でAUは顔の動きを表すプロパティですので、毎フレーム値が変化する可能性があります。また、あくまでも顔の形状変化に基づくプロパティであるため、全く別のSUを持つような顔の3Dモデルが与えられた場合には(例えば口角が非常に下がった顔モデルと非常に上がった顔モデルが与えられた場合には)、全く同じように顔のパーツを変形させたとしても同じような表情を検知するというわけではありません。

また、HighDetailFacePointはモデル中に存在する顔の頂点1347個の内、特に意味合いが強いものに絞ったインデックスを提供します。このEnumからアクセス出来ない頂点にもアクセスする方法は存在します。

まとめ

というわけでなかなか複雑ですが、FaceShapeは顔の形状的特徴、FaceAnimationは顔の動き的特徴を表すということを抑えておけば大丈夫そうです。

*1:ちなみにPCAは Principal Component Analysisの略で、顔認識などで用いられるアルゴリズムの一種です

VGB classifier features and learning parameters - details please

元ネタ

VGBで実行している機械学習の詳細が知りたい!

VGBの機械学習ロジックの詳細が知りたい!というトピックが投稿されていました。 かなり突っ込んだ内容まで聞こうとしていますが、果たして中の人は答えてくれるのでしょうか!?

VGBは筋肉の力の入り方とかねじりとか考慮して機械学習をしているんだろうけど、詳細を教えてくれない?

  • それぞれの機能はどんなふうに計算されているの?各方式の詳細を説明した論文とかはないの?
    生理学とかに基づいたアプローチであれば運動力学とかその辺を考慮して計算をしているんだよね?
  • 個別の機能をSDKから呼び出すことができるようにする予定はないのかな?たとえばある筋肉のねじりが必要である場合に、その算出をSDKでサポートしてくれるとかね
  • 学習する識別子の上限が1000で設定されているけれど、今後この値が拡張されたり変更できるようになったりするのかな?
  • 推定された関節の情報が識別子として利用されたり、利用されなかったりしているけど、どういった基準でその判断をしているのだろう?
    これはVGBのログで表示される Top 10 contributing weak classifiers をみて気がついたんだけどさ。

VGBが利用しているのは関節の位置情報だけ

KINECT SDKがサポートしていない機能(筋肉の捻じりとか)は当然VGBでも利用できないのでVGBで利用しているのは関節の位置情報だけだよ。という回答が付いています。

これに対して質問者は以下の様なツッコミをしていますが、

じゃあVGBのビルドステップに表示される Feature: MuscleForceX とかは何なの?

中の人としては

機械学習の詳細を公開したり変更したりする予定はないんだ

ということで詳細は明かせない。という結論でした。

とはいえVGBのDetection Technologiesには利用しているプロパティや果たす役割について詳細に記述されていますので、この辺りをみるともう少し詳しいことが理解できるのかもしれません。

Kinect for windows sensor does not start when using remote WMI

元ネタ

KINECTで取得したデータを保存するアプリケーションを多数のクライアントに配布して実行してみたら正常に動作しなかったという投稿です。

具体的には以下の様な現象が起こっています。

  1. KINECTのデータを取得するためのアプリケーションを作成した
  2. Windows 8.1のマシンにアプリケーションを配布し、 WMIアーキテクチャを利用してWindows 7のマシンからリモート実行する
  3. アプリケーションが実行されていることは確認できたけど、データが保存されていない
  4. kinectsensor.openが実行されてもsensor.IsAvailableがfalseのまま変わらない

Kinect for windows SDKはユーザセッションがないと動作しない

実は関連する投稿がいくつかあります。

つまりユーザセッションがない場合はKINECT SDK(と言うかKINECT Service)を使ってKINECTを動作させることはできない、ということです。

クライアントに配布したKINECTアプリケーションを実行するといえば、先日発表されたMicrosoft Cube SDKのDeploy Toolには配布したExeファイルを実行・制御する機能があると記載されていました。

Microsoft Cube SDKが公開されました - ハードコイルド・ワンダーランド

これはどうやって実現しているのか気になるところです(KINECTのデータを受け取るだけでSDKを利用していないのかもしれませんが)が、現状ではリモートデスクトップ接続などでクライアントに接続した状態でしかKINECTv2を動作させる術はありませんでした。

Microsoft Cube SDKが公開されました

複数KINECTで発生したデータを複数のPCに公開・ハンドリングさせる機能を持ったMicrosoft Cube SDKが公開されました。ソースコードGitHubに公開されていますがライセンスは明記されていません。

このSDKに含まれているKINECT Transportを利用するとTCPを経由することで最大5台のPC、4台のKINECTを用いたDepthデータ、スケルトンデータの送受信を実現することができます。

Microsoft Cubeってなに?

KINECTを利用したプレゼンテーションの一例として発表されたデモンストレーションです。くわしくは以下の動画を参照してください。


Kinect-Powered Cube Unveiled at Decibel Festival ...

Microsoft Cube SDKの構造

SDKはおおまかに以下のような構成になっています。

SDK
     - Common
     - Kinect Transport
     - Deploy Tool
     - Samples
         - Cinder Sample
         - NodeJS Sample
         - Unity Sample

Common

CommonパッケージはKINECTからのデータ取得、データの変換 *1KINECTのデータをサーバに送信する責務を担っています。

Kinect Transport

Kinect Transportパッケージは複数PC間でのデータ送受信の制御や設定をする責務を担っているようです。以下、READMEから引用します。

KinectTransport is designed to push Kinect2 data from one machine to one or many other machines over a ethernet network.

Kinect Transport自体はSDKとして利用するものではなく、KINECTのデータを送信/受信したいPC上で実行させ、どこに対してどのような情報を送信するかを設定するGUIを提供するためのものになっています。

Deploy tool

Deploy toolパッケージは中央サーバから接続されたクライアントに対して実行可能なプログラムを配布し、プログラムの開始・終了を制御する責務を担っています。こちらもREADMEから引用すると以下のようになります。

Additionally the Deploy Tool provides a method for automatically pushing builds from a centralized server to each side of the cube and starting and stopping the application.

Samples

NodeJS, Cinder, Unityのサンプルがリポジトリに含まれています。詳しく見ていませんが、KINECTのデータを配布するためのTCPサーバはNodeJSで実装されているようです。

早くもGitHub IssueにはUnityのサンプルが動かないバグが公開されていますが、チュートリアルはNodeJSなので大丈夫でしょう…たぶん。

インストール方法

まだ試していませんが、READMEそのままを日本語訳したメモです。

  1. このリポジトリをcloneする
  2. NodeJSをインストールしていない場合はインストールする
  3. NodeJSSample ディレクトリに移動して npm install

サンプルの実行方法

  1. KINECTを接続し、KINECT Transportを実行します
  2. NodeJSSample ディレクトリに移動して server.bat を実行します
  3. ブラウザで http://localhost:8000 を開いてKINECTからデータが送信されていることを確認します

MS Cube SDK雑感まとめ

KINECTのデータをネットワーク越しに利用したい、複数台のKINECTのデータをまとめて制御したいという要望はKINECT v1の時点から多くありました。

ちゃんと調べたわけではありませんが、TCPソケットやWebSocketを利用してネットワーク経由でKINECTのデータを扱う実装はすでに多くあると思われます。 *2

現状で感じられるMS Cube SDKの価値は以下の様な点でしょうか。

  • SDKの形としてまとまっている
  • 複数台でアプリケーションを構成する前提としてバイナリ配布のツール(Deploy Tool)もちゃんと付いている

MS Cube SDK自体は恐らくこの状態から大きく進化することはないでしょうが、このすぐ先には複数KINECTから取得した点群の合成やフレーム合わせが待っているわけです。楽しみですね(だれが実装するかは置いておいて) : )

*1:データを圧縮するためにバイナリに変換しているようです

*2:私も2013年の前半にWebSocketで、2014年にMQTTで実装しています