Kinect

Kinect 人物と画像を重ねる

Kinectで人物と画像を重ねる

人物と背景との間に画像を入れたい場合を考えた。

[youtube]http://www.youtube.com/watch?v=Wxx6mi3A8n0[/youtube]

DepthImageFrameが持つ情報には、ピクセルあたりの深度と共に人物IDも格納されている。
このユーザーIDを元にピクセルを背景と人物とに切り分ける事ができれば、あとは間に何を差し込もうが自由になる。

depthFrameの1ピクセルの情報は以下のようになっていて、下位3ビットが人物IDとなっている。
0000 0000 0000 0111
上記の場合は111なので人物IDは7、深度は0となっている。

実際にデータを取り出すには、CopyPixelDataToを使う。

var depthFrame = this.kinectDevice.DepthStream.OpenNextFrame(100)
short[] _depthPixelData = new short[kinectDevice.DepthStream.FramePixelDataLength];
depthFrame.CopyPixelDataTo(_depthPixelData);
playerIndex = _depthPixelData[depthPixelIndex] & DepthImageFrame.PlayerIndexBitmask; //人のID取得

以下解説します。

kinectDevice.DepthStream.FramePixelDataLengthは画素数となる。
640×480の場合は_depthPixelData=short[307200]である。
ピクセル数分のshort配列を作成し、CopyPixelDataToで深度情報をコピーする。
depthPixelIndexを使い左上から順に_depthPixelDataを判定する。

DepthImageFrame.PlayerIndexBitmaskは下位3ビットとの演算用で7(111)が格納されているので、
これと&演算し、0以上の数値が入っていれば、depthPixelIndexが指すピクセルは人物の一部である事が判明する。

=0ならば背景(人物以外)レイヤーに、0以上ならば人物レイヤーにピクセルを描画すれば、
背景と人物との切り分けに成功する。

さらに人物の深度が必要な場合には以下のように3ビットシフトすれば深度だけを得ることができる。
_depthPixelData[depthPixelIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;

人物と背景との間に差し込みたいオブジェクトの深度を決め、
ピクセル深度とオブジェクトの深度を判定し、ピクセルのマップ先を振り分ければ、
オブジェクトの周りを人物が回るように見える処理も可能となる。

ソースはgithubにもアップ
https://github.com/sugasaki/kinect-human2

↓同じものをダウンロード
[download id=”30″]

Kinect 人物と画像を重ねる はコメントを受け付けていません