さっそくいじってみます。
環境は次の通りです
#include <OpenNI.h>#include <opencv2\opencv.hpp>
#include <vector>
void main()
{
try {
openni::OpenNI::initialize();
openni::Device device;
auto ret = device.open( openni::ANY_DEVICE );
if ( ret != openni::STATUS_OK ) {
throw std::runtime_error( "" );
}
openni::VideoStream colorStream;
colorStream.create( device, openni::SensorType::SENSOR_COLOR );
colorStream.start();
std::vector<openni::VideoStream*> streams;
streams.push_back( &colorStream );
cv::Mat colorImage;
while ( 1 ) {
int changedIndex;
openni::OpenNI::waitForAnyStream( &streams[0], streams.size(), &changedIndex );
if ( changedIndex == 0 ) {
openni::VideoFrameRef colorFrame;
colorStream.readFrame( &colorFrame );
if ( colorFrame.isValid() ) {
colorImage = cv::Mat( colorStream.getVideoMode().getResolutionY(),
colorStream.getVideoMode().getResolutionX(),
CV_8UC3, (char*)colorFrame.getData() );
}
cv::cvtColor( colorImage, colorImage, CV_BGR2RGB );
cv::imshow( "Color Camera", colorImage );
int key = cv::waitKey( 10 );
if ( key == 'q' ) {
break;
}
}
}
}
catch ( std::exception& ) {
std::cout << openni::OpenNI::getExtendedError() << std::endl;
}
}
OpenNIとKinect for Windows SDKの中間のような作りになっているようです。
まず openni::OpenNI::initialize() でOpenNIを初期化します。続いて、openni::Deviceクラスを定義し、openni::Device::open() でデバイスを開きます。この時、引数にはデバイスのURIを指定しますが、ここでは最初に見つけたデバイスを開きます。
続いて、openni::VideoStream クラスを定義し、openni::VideoStream::create() でストリームの作成、openni::VideoStream::start() でストリームを開始します。
メインループでは openni::OpenNI::waitForAnyStream() を呼び出してストリームの更新を待ちますが、この関数が openni::VideoStream** (openni::VideoStreamのポインタの配列)を引数にとるため、std::vector<openni::VideoStream*> を定義し、ストリームへのポインタを追加します。openni::OpenNI::waitForAnyStream()は更新されたストリームのインデックスが返すので、該当ストリームの処理を行います。ここではカラーカメラのみとなります。
更新されたカラーカメラのフレームは openni::VideoStream::readFrame()を呼び出して、openni::VideoFrameRef で受け取ることができます。openni::VideoFrameRef::isValid() でフレームの妥当性を確認し、データを取得します。カラーカメラの画像は openni::VideoFrameRef::getData()で、カラーカメラ解像度は openni::VideoStream::getVideoMode().getResolutionY()(またはgetResolutionX())で取得することができます。
OpenNI1に比べて簡潔なコードで記述でき、Kinectも設定なしで利用できるので、とても使いやすくなっています。
ちなみにもちろんXtionでも全く同じコードで動きます。ただし、解像度がデフォルトで320x240になってるみたいですね。