「やってみよう!kinectアプリ開発」の第二回目レビューを記載させていただきたいと思います。今回の課題は下記のようになっておりました。
これらの課題について、第4回、第5回をまとめてレビューさせていただき、そのあとで第6回、第7回をまとめてレビューさせていただきます。
第4,5回 課題について
この回は、画面に映った人物の場所をプログラム上で取得することをメインにしています。第4回では人物の場所に加えて頭や手、足などのパーツがどの場所にあり、どちらの方向を向いているかについて基本的な事項を理解する事をメインとしていると思います。また、第5回では画面に表示されている画像のうち、人物の映っている部分とそれ以外の背景の部分を視覚的に認識し、その状態を具体的にイメージとして画面に表示することを目的としているように思いました。
具体的なコーディング内容については、各講座を参照いただくとして、ここではその実行結果とプログラムの概略的な仕組みについてレビューしていきたいと思います。
いきなりですが、こちら2回分の課題についてプログラムを記載し実行した結果の画面を下記に掲載します。
プログラムを行った内容としては、第4回の講座で、取得した骨格情報に基づいて頭部と認識されている部分に別途読み込んだ画像を重ねて表示し、さらに第5回の講座で人物と認識していない部分を青色で塗りつぶして画面を描画しています。
画像の周囲に塗りつぶされていない部分がありますが、こちらはkinectでは深度情報を取得できないエリアとなっているそうです。
前回のレビューでメインのプログラムの詳細な説明を行いましたので、今回は追加したプログラムをメインにプログラムの全体を踏まえた内容を説明していきたいと思います。
内容の説明に入る前に、プログラムの基本的な考え方について簡単にご説明させていただきます。
プログラムを作成する場合、すべての処理を単純に並べる訳ではなく、処理の塊ごとに関数というものを作成します。プログラムの中に処理の塊となる関数を複数記述し、メインのプログラムからそれらの関数を呼び出すことで全体の処理を実現していきます。
下の図を利用して、その関数ごとにそれぞれの関数がどのような関連性を持って動いているかを説明していきいます。
この図においてほぼ全体を囲んでいるpublic partial class MainWindow:Windowが表示するウィンドウに関するプログラム全体を表しています。その中には、左側に並べたような、そのプログラムの中だけで有効な変数が準備されています。この変数は、プログラムの中に記載されている関数の中でも使用可能となります。逆に、各関数の中に記載された変数については、その関数の中だけで有効となるため、他の関数では利用することができません。
それでは、それぞれの関数の内容とそれぞれの関連した動作について説明してみます。
[A]WindowsLoaded
この関数はアプリケーションが起動されてウィンドウが表示された際に自動的に呼び出されます。この中では、各種変数の初期値の代入や関数の起動タイミングなどを設定しています。
こちらのプログラムでは、[B]AllFramesReadyを[α]Microsoft.Kinectのデータ受信タイミングに合わせて呼び出すような設定を行っています。
[B]AllFramesReady
Kinectからデータを受信した際に呼び出され、[C]getHeadPointsを呼び出して頭部の位置を取得し、Kinectから受信した画像、頭部の位置、深度情報を[D]fillBitmapに渡します。
[C]getHeadPoints
上位の[B]AllFramesReadyから呼び出され、Kinectから得た情報から頭部のある位置を探し出して登録していきます。
[D]fillBitmap
上位の[B]AllFramesReadyから呼び出され、渡されたKinectから得られた画像の頭部にあらかじめ表示用として準備した画像を重ねて書き込み、さらに深度情報より人物では無い部分を青色で塗りつぶして[V]MainWindow.xamlに描画します。
[V]MainWindow.xaml
パソコンに実際に表示されるウィンドウです。このウィンドウ内に設置された描画エリアに対して[D]fillBitmapによって画像が書き込まれます。
このように、複数のプログラム(関数)が連携して動作することによって最初に張り付けている画面の表示を実現しています。
○プログラムのバグについて
講座の中で記載されているプログラムについては以上ですが、私の環境で実行している際にかなりの確率でエラーが発生しておりました。実際、この講座ではエラー処理などはほとんど入っておらず、必要最低限の処理のみを記述しているので、想定していない値などがKinectから送られてきたり、データが正常に取得できなかった場合にエラーが発生してしまう事があると思われます。
実際に私の環境で発生したエラーは主に次の2つとなります。
この2つのエラーはどちらもメモリーに関するエラーで、元々用意していた箱よりも大きなデータを入れようとしたり、0を入れてはいけない場所に0を入れてしまったりした場合に発生することが多くなっています。
このようなエラーの回避のためには、通常try~catchというエラーを横取りする関数を使用するかと思うのですが、まだ、C#に不慣れのためうまく実装することができませんでしたので、今後の課題とさせていただきたいと思います。
第6,7回 課題について
この回は、今までの内容とは少し異なり音声に関するプログラムを作成していきます。Kinectでは映像だけでなく、音声の方向を取得する事も可能となっており、その方向から映像として捉えている複数の人物のうち、どの人物が発した音声なのかを識別することが可能となっています。また、Microsoft Speech Platform Software Development Kit というAPIを利用することによって、音声認識を行うことも可能です。
それらを講座の内容に従ってプログラムに追加し、実行した結果が下記の画像となります。
顔の画像の大きさや吹き出しの透過処理、位置の調整、文字表示のフォントサイズの調整などを一切行っていない状態ではありますが、とりあえず吹き出しと文字を表示することには成功しました。
それでは、前回と同様に下の図を利用して、その関数ごとにそれぞれの関数がどのような関連性を持って動いているかを説明していきいます。
主要な関数については、前に説明した内容とほぼ同一となるため、前回と異なる部分のみご説明させていただきます。
[A]WindowsLoaded
前回説明した内容に加えて、こちらのプログラムでは、[E]SoundSrcAngleChanged、[F]SpeechRecognized、[G]InitSpeechEngineの3つの関数を呼び出します。それぞれの内容については次からの項目で説明します。
[E]SoundSrcAngleChanged
音声を認識した際に、音声の方向を登録します。
[F]SpeechRecognized
音声を認識した際に、あらかじめ登録された文字列と比較し、一致した場合にその文字列を登録します。
[G]InitSpeechEngine
音声認識のプログラムに対して、言語の設定や認識する単語を登録する初期化処理を行います。
[D]fillBitmap
前回の内容に加えて、[E]SoundSrcAngleChangedで取得した角度に人物の画像があった場合、その右上の部分に吹き出しの画像を表示させます。さらに、[F]SpeechRecognizedで登録された文字列と一致したという情報がある場合には、その吹き出しに単語を追加した状態で画像を表示させる処理が追加されています。
このように、単純な処理を行う関数を複数組み合わせることで様々な表現を可能とすることが可能なのがプログラムです。
今後は、吹き出しに対する透過処理を追加し、より吹き出しっぽく表示させると共に、文字のフォントサイズを調整し適切な表示ができるように変更していきたいと思います。
講座の内容としては、以上で網羅しておりますが今後もオリジナルで作成する予定のプログラムに対して応用が可能な部分も多くありますので、活用させていただきたいと思います。
あすてあさん
2012/08/01
ガトーさん
2012/08/01
コメントありです!
「 夢 の 印 税 生 活 」
ムリムリムリムリムリムリムリムリムリムリ
某支配人@名古屋定住@イベント行きたいさん
2012/08/01
フォントサイズの項を16にしたら、おさまりが良くなりました。
ガトーさん
2012/08/01
コメントありです!
デフォルトのままのフォントサイズだと、かなり大きめの画像を準備(ひょっとしたらプログラム内でサイズを指定してるかもですが)しないといけないような(;´∀`)
フォントサイズを変えたらいいってのはすぐにわかったんですが・・・・ゴメンナサイ手抜きです(;^ω^)
これとは別にオリジナルの方も並行して進めているせいで、課題分のプログラムがかなーり手抜きになってしまっているのは事実です(;´Д`)