ラベル Kinect の投稿を表示しています。 すべての投稿を表示
ラベル Kinect の投稿を表示しています。 すべての投稿を表示

2011/05/24

『Kinectセンサープログラミング』買ってきた

【同時上映: ユーザー検出でバグってみた】

今日は、世界で初めて Kinect プログラミングを解説した技術書の発売日である。

ぼくはこれがすごく気になり、予約開始とともに Amazon に注文をして発売日を今か今かと待ちわびていたほどだった。

しかし突如として Amazon は予約を一方的にキャンセル。さらに「この本はお取り扱いできません」状態が今なお続いている。


仕方なくジュンク堂書店に行ってみたところ、出来たての『Kinect センサープログラミング』が折よく品出し用のワゴンに載っていたので早速ゲットして意気揚々と帰途についた。

『Kinect センサープログラミング』 ¥3,200 (税別)

さてさて。

 Kinect に関しては、このブログでもちょこちょこ言及してきたけれど、いかんせんぼくの調べ方が適当すぎて細かい誤解がいっぱいあった。

その中でも今回は、特に致命的だった事柄について述べたいと思う。

2011/04/25

Kinectプチハック(エピソード4)

【ミッション: Kinectで立体復元に挑戦しよう】

前回奥行き情報を(一応)推定する事ができたので、そろそろ 3D にしてみようと思う。

本日のターゲットは、このどうしようもない写真。


これを、Kinect で適当に 3 次元復元して俯瞰したら、こうなった。

机上の本や PC はもちろん、部屋の隅っこの柱やパイプなどの凹凸がくっきり浮き出ている事が確認できる。

※ ちなみにぼくの隣は博士様の席なのだ。いないけど。

2011/04/22

Kinectプチハック(エピソード3)

【ミッション: Kinectから奥行き情報を推定しよう】

前回、カメラ画像に位置を合わせた深度データを取ってくる事ができたので、今回はそれを 3 次元的にマッピングしてみようと思った。

これは、椅子と机の一部の奥行きデータを3次元的にプロットした結果である。

2011/04/18

Kinectプチハック(エピソード2)

【ミッション: OpenCVでNiSimpleViewerもどきを作ろう】

前回、Kinect の深度データと RGB 画像を OpenCV の IplImage で取得する実験をしてみた。

この調子で、OpenNI Tips に載っている『デプスと画像を重ね合わせするデモのサンプルコード』を試してみよう。


…って、あれ? ずれていてうまく重ならない。なにこれダメじゃん。

どうやら、深度センサとカメラの位置が微妙にずれているため、単なるオーバレイ表示にしただけではダメらしい。

2011/04/13

Kinectプチハック

【ミッション: Kinectのカメラ映像をIplImageに変換して使おう】

前回のあらすじOpenNI を入れた

Kinect のカメラ、及び深度データを OpenCV で使うための最小限のソースコードをこの辺で見つけたので、さっそく試してみた。

自分の環境に合わせてじゃっかんソースコードを書き換えたが、概ねそのままである(下記のコードは、Visual Studio と OpenCV 2.0 のコンビネーションじゃないとうまく動かない気がする。特にライブラリのバージョンに注意)。
#include<cv.h>
#include<highgui.h>

// ※インクルードパスに
//  「C:\Program files\OpenNI\Include」
//  を追加しておこう!
#include<XnCppWrapper.h>

#pragma comment(lib,"C:/Program files/OpenNI/Lib/openNI.lib")

#define SAMPLE_XML_PATH "C:/Program Files/OpenNI/Data/SamplesConfig.xml"

int main() {
    xn::Context context;
    xn::EnumerationErrors errors;

    context.InitFromXmlFile(SAMPLE_XML_PATH);

    xn::DepthGenerator depth; // 深度コンテキスト
    context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);

    xn::ImageGenerator image; // イメージコンテキスト
    context.FindExistingNode(XN_NODE_TYPE_IMAGE, image);

    xn::DepthMetaData depthMD;
    xn::ImageMetaData imageMD;

    cv::Mat depthshow;
    cv::Mat show;
    int key = 0;
    bool isWarp=false;
    while (key!='q')
    {
        // waitとエラー処理
        context.WaitAnyUpdateAll();

        image.GetMetaData(imageMD);
        depth.GetMetaData(depthMD);

        // 画像と深度はOpenCVのMatに格納
        cv::Mat depth16(480,640,CV_16SC1,(unsigned short*)depthMD.WritableData());
        cv::Mat imni(480,640,CV_8UC3,(uchar*)imageMD.WritableData());

        // RGB色空間をBGRに変換
        cv::cvtColor(imni,show,CV_RGB2BGR);  
        
        // 11ビット画像を8ビット画像に変換
        depth16.convertTo(depthshow,CV_8U,-255/4096.0,255);

        cv::imshow("depth",depthshow);
        cv::imshow("image",show);
        key = cv::waitKey(33);
    }
    context.Shutdown();
    return 0;
}
これで、Kinect から労せずしてカメラ映像を取得する事ができるようになった。

……と見せかけて、上記のサンプルコードのままでは(僕にとって)多少問題がある

この段階で、画像データは OpenCV の汎用行列クラスである cv::Mat のオブジェクトとして扱えるようになるのだが、このページの情報によると、 cv::Mat のメンバである step の値が、4 バイト単位に調整されなくなるという不都合が残っているらしい。

以前書いたような Windows API との連携を考えた場合、画像の管理には素性がはっきりしている IplImage 構造体を用いた方が、面倒も少なくて済むだろう。

僕がてきとうに調べた限り、Kinect から取ってきた画像データを直に IplImage に変換するような先人のソースコードを見つける事はできなかった。

それでも、恐らく需要はあるかも知れないと思い、ちょっと作ってみることに。

2011/03/29

Kinectがやってきた!

先生が Kinect センサーを買ってくれた。うれしすぎる。

Kinect センサとは、昨年11月に発売された Xbox 360 用のゲームデバイスで、カメラと赤外線の奥行きセンサが搭載されているスグレモノだ。