OpenNIからDepth情報を取得してcvGrayScaleImageに渡す
libfreenectを使っていたアプリのドライバをOpenNIに変えてみた。しかしDepthのピクセル情報を直接取得するAPIが見つからなかったので次の泥臭いコードを書いた。もうちょっとスマートに書ければいいんだけどC++難しい……。
ヘッダ宣言部
ofxOpenNIContext recordContext; ofxDepthGenerator recordDepth; unsigned char * depth_pixels; ofxCvGrayscaleImage grayImage;
Setup
recordContext.setup(); recordContext.setupUsingXMLFile(); recordDepth.setup(&recordContext); recordContext.toggleMirror(); XnMapOutputMode map_mode; map_mode.nXRes = XN_VGA_X_RES; map_mode.nYRes = XN_VGA_Y_RES; map_mode.nFPS = 30; depth_pixels = new unsigned char[map_mode.nXRes * map_mode.nYRes * 4]; memset(depth_pixels, 0, map_mode.nXRes * map_mode.nYRes * 4 * sizeof(unsigned char)); grayImage.allocate(640, 480);
Update
recordContext.update(); xn::DepthGenerator& dgen = recordDepth.getXnDepthGenerator(); xn::DepthMetaData dmd; dgen.GetMetaData(dmd); const XnDepthPixel* depth = dmd.Data(); float max_depth = dgen.GetDeviceMaxDepth(); int pos = 0; for (XnUInt16 y = dmd.YOffset(); y < dmd.YRes() + dmd.YOffset(); y++) { for (XnUInt16 x = 0; x < dmd.XRes(); x++, depth++){ depth_pixels[pos++] = (XnUInt16)(((*depth) / (max_depth / 256))); } } grayImage.setFromPixels(depth_pixels, 640, 480);
あとはOpenCVで好きな用に処理ができる。しかしメモリアクセスとかしたくないので、OpenNIのpythonバインディングを調べてみる価値はありそう。