カテゴリ:Kinect( 5 )

Microsoft HoloLens

1ヵ月も空いてしまった。

MSのHoloLens、気になりますね

AR、VRに続いてMR(Mixed Reality)を提唱してるけど、まぁ形式的にはARになるんだろうね。

先日このHoloの開発キットが発売されたけど、お値段は約37万円。

うーん、個人で買うには少々キツイレベル。

(LEAPMOTIONくらいなら自腹で購入出来たんだけど)

プレステ2の開発機も30万ぐらいしたとか聞いてるし、まぁこういったdevキットってそもそもこれくらいするもんなんでしょう。

Kinect v2のDev版(確か10万弱)が安い部類に入ってたんだな、知らなかったよ。

本題のHoloはKinectと親和性が高い!という売り文句があったけど、確かにそれはホントそう思う。

開発環境としてもVisualStudioベースになるだろうから、Kinectの開発してた人はより入りやすいんだろうなぁ。


で、新しいモノってのは性能はもちろん、活用方法についてが今後の課題になってくる。

Kinectも機能的にはかなり優秀なデバイスではあったけど、いかんせん用途が貧弱でなかなか表舞台で目立てなかった。

実際これまで案件としてKinectが採用されたのは、片手で数えて余るくらいだと思う。

MSのマーケティングもアピールが全然ないから知らない人も多い。(MSのこの辺の能力はホント弱小企業レベル)

Holoも然り、イベントや展示会に導入するには、回転率が悪すぎてクライアントに魅力を感じさせることが出来るかというと疑問。

一般販売する前にここにHoloあり!って存在感を示せる使い方を技術者も考えていかないと。

まぁ家庭用でその人生終えるだけでいいならいいけど、そりゃ最新技術の持ち腐れですよ、MSさん・・・。

[PR]
by onigirism | 2015-11-17 12:28 | Kinect | Comments(0)

ColorFrameReader その2

夏休みを挟んで久々に再開

前回の続きです。
最後にこうなってましたね。

public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;

kinect = KinectSensor.GetDefault();
cReader = kinect.ColorFrameSource.OpenReader();
cDesc = kinect.ColorFrameSource.FrameDescription;
cBuff = new byte[cDesc.Width * cDesc.Height * 4];
wBitmap = new WriteableBitmap(cDesc.Width, cDesc.Height, 96.0, 96.0, PixelFormats.Bgra32, null);

cReader.FrameArrived += cReader_FrameArrived;
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
kinect.Open.();
}

private void cReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{

}

さて、この段階でアプリを実行すると、画面上には何も出ないけど
一応Kinectは起動すると思います。
何も出ないのは当然、Kinectが取得するデータに何にも手を付けてないからです。

ということで手を付けます。
カラーデータを毎フレーム取得するイベントハンドラが登録されていますね。(一番下のproc)
ここに色々書いていきます。

まずKinectのデータ取得についてのお約束として
毎回フレームデータを取得⇒使い終わったら破棄
という流れを覚えておきましょう。
それを踏まえて以下のように書きます。

using ( ColorFrame cFrame = e.FrameReference.AcquireFrame() )
{
if ( cFrame != null )
{

}
}

IDisposableオブジェクトであるColorFrameはusingステートメントを使うことで
記述をおもっくそ簡略化出来ますね、最後にDisposeとかやらんでも勝手にやってくれます。
一時データとして取得したcFrameを使ってデータを加工します。

次、

if ((cDesc.Width == wImage.PixelWidth) && (cDesc.Height == wImage.PixelHeight))
{
if (cFrame.RawColorImageFormat == ColorImageFormat.Bgra)
{
cFrame.CopyRawFrameDataToArray(cBuff);
}
else
{
cFrame.CopyConvertedFrameDataToArray(cBuff, ColorImageFormat.Bgra);
}
}

バッファにcFrameのデータをコピーします。
ここでフレームのColorImageFormatの場合分けをしてますが、意図的にイジりでもしない限り、
あるいはIDEがVisualStudioである限りはBGRA形式で渡ってきます。
これがUnityの場合だとyuv(だっけ?)で来ちゃうのでBytesPerPixelがRGBAと違ってエラーになります。
念のため的な処置ですがデータコピーにはこういう手順を踏んでおきましょう。

あとはWriteableBitmapに取得したデータをオラオラするだけです。
wImage.WritePixels(
new Int32Rect(0, 0, wImage.PixelWidth, wImage.PixelHeight),
cBuff,
wImage.PixelWidth * (int)bpp,
0
);
オフセットって言うのがイマイチよく分かってません、ごめんなさい。
ただ、0から1にしたりするとエラーを吐くのでそういうもんなんでしょう(適当)
書き込み始める位置の調整なのかな?

さて、長々書きましたが全体でこうなります。

public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;

kinect = KinectSensor.GetDefault();
cReader = kinect.ColorFrameSource.OpenReader();
cDesc = kinect.ColorFrameSource.FrameDescription;
cBuff = new byte[cDesc.Width * cDesc.Height * 4];
wBitmap = new WriteableBitmap(cDesc.Width, cDesc.Height, 96.0, 96.0, PixelFormats.Bgra32, null);

cReader.FrameArrived += cReader_FrameArrived;
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
kinect.Open.();
}

private void cReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
using ( ColorFrame cFrame = e.FrameReference.AcquireFrame() )
{
if ( cFrame != null )
{
if ((cDesc.Width == wImage.PixelWidth) && (cDesc.Height == wImage.PixelHeight))
{
if (cFrame.RawColorImageFormat == ColorImageFormat.Bgra)
{
cFrame.CopyRawFrameDataToArray(cBuff);
}
else
{
cFrame.CopyConvertedFrameDataToArray(cBuff, ColorImageFormat.Bgra);
}

wImage.WritePixels(
new Int32Rect(0, 0, wImage.PixelWidth, wImage.PixelHeight),
cBuff,
wImage.PixelWidth * (int)bpp,
0
);
}
}
}
}

これで出来る限り最小のカメラ画像取得ロジックの完成

ではないです。

wImageにデータを書き込んだはいいがそれをコントロール側に渡していませんね。
この辺はちょっとジャンルの違う話になってくるのでテキトーですいません。

public ImageSource cameraImg
{
get { return wImage; }
}

こんな感じでcameraImgをXAML側にバインドすれば完成です。
あぁ長かった。

[PR]
by onigirism | 2015-09-02 11:35 | Kinect | Comments(0)

ColorFrameReader

発売から約2年ぐらい経ったv2、最近の動向はどうなんだろう
ニュース検索してもめっきり話題が少ない気がしてちょっと悲しい・・。

けどこれからv2のプログラミングを始める人もいるだろうから
ちょっとずつではあるけど自分の得た知識・知恵を書き連ねていこうと思う。
ちなみに自分はWPFで制作してるのでC++に関してはさっぱりです。

いい歳してCとC++、果てはjavaまでもよく分かってないんでちょっと将来が心配。。。

さて今回はもっとも基本となるColorFrameReaderについて。
RGB映像を出力するのに必要なFrameReader、色情報だけなので扱い方もすぐ覚えられます。
極力少ないロジックでRGBカメラを起動させましょう。

■用意するもの
・当たり前だけどKinect
・今回の主役ColorFrameReader
・一応のFrameDescription
・カラーデータを退避させるバッファ領域の配列byte[]
・WriteableBitmap

上から順にこう。
private static KinectSensor kinect = null;
private ColorFrameReader cReader = null;
private FrameDescription cDesc = null;
private byte[] cBuff = null;
private WriteableBitmap wBitmap = null;


まずはKinectをスタートさせる前に下準備としてもろもろ定義しておく。
FrameDescriptionはメモリへの負荷と言う面でFrameArrived内で毎回読み出すのはナンセンスのようなので、
自分はいつもWindowのコンストラクタかLoaded時にやってます。
(むしろ固定値でも構わないとすら思ってるけど・・・)

kinect = KinectSensor.GetDefault();
cReader = kinect.ColorFrameSource.OpenReader();
cDesc = kinect.ColorFrameSource.FrameDescription;
cBuff = new byte[cDesc.Width * cDesc.Height * 4];
wBitmap = new WriteableBitmap(cDesc.Width, cDesc.Height, 96.0, 96.0, PixelFormats.Bgra32, null);


1つ1つ解説しておくと
kinect はいいでしょう、インスタンスを得るためのおまじない。
cReader はカラーデータを取得するためのおまじない。
cDesc はカラーフレームソースの定義情報を得るためのおまじない。
cBuff はカラーデータを入れる領域を確保してるわけだけど、自分は最初「4」ってなんやねんって思った。
これは色情報が1ピクセル/4バイトだから1920*1080の画角にはその4倍のバイトデータがあるってことだね、そりゃそうだね。
wBitmap はまぁそのまま、描画する大きさをちゃんと定義すればおk。

定義が済んだらこれらを操作するプロシージャを用意する。
cReader.FrameArrived += cReader_FrameArrived;

こうすることでColorFrameReaderが毎フレームデータを取得してくるので
その度にフレームごとの操作をしてあげればよい。

KinectをOpenするのを忘れずに。
Kinect.Open.();

ここまで通して書くとこうなる。
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;

kinect = KinectSensor.GetDefault();
cReader = kinect.ColorFrameSource.OpenReader();
cDesc = kinect.ColorFrameSource.FrameDescription;
cBuff = new byte[cDesc.Width * cDesc.Height * 4];
wBitmap = new WriteableBitmap(cDesc.Width, cDesc.Height, 96.0, 96.0, PixelFormats.Bgra32, null);

cReader.FrameArrived += cReader_FrameArrived;
}

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
kinect.Open.();
}

private void cReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{

}


さて、思ったより長くなったので次回へ続く・・・笑
(捕捉)
kinect.Openのところですが、Exciteブログの仕様なのか
Openメソッドとして記述するとエラーが起こり投稿出来ませんでした。
多分jsの記述とバッティングするのを防ぐためだろうけど。
エスケープかなんかすればいいんだろうけど調べるのがめんどいので
Openと()の間にドットを入れてます。

[PR]
by onigirism | 2015-08-25 11:34 | Kinect | Comments(0)

暑いよー

昔はこんなに暑かったのかなぁ

今日はPointCloud風にDepth画像をBodyIndexのみで抜き出す小技

基本的にはBodyIndexもほぼDepthのようなもんなので大して難しくない

これにColorFrameを当ててBodyIndexベースのGreenScreenを作りたい

というか既に試してみたけどうまくいかない

やっぱりImageBufferを何やらするやつをやらないとダメなのかな・・・


e0349767_17251205.png

[PR]
by onigirism | 2015-07-27 17:26 | Kinect | Comments(0)

もたつくCoordinateMapper

v2のCoordinateMapperのサンプル

Runで動かした時は問題ないのに、いざ自分でビルドしてみると

カックカクでお話にならないことがある。

そんな時はプロジェクトのプロパティ→「ビルド」にある

コードの最適化

にチェックが入っているか見てみよう。

ここにチェックを入れてリビルドすればサンプルと同様の動きになるようだ。

[PR]
by onigirism | 2015-06-29 18:25 | Kinect | Comments(0)