続いて、DepthカメラのIR画像を表示します。
基本的なコードはOpenNI2(Beta) 入門(1) :Colorカメラの画像を表示すると同じです。
// IR画像を表示する#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_IR );
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() ) {
if ( colorFrame.getVideoMode().getPixelFormat() ==
openni::PixelFormat::PIXEL_FORMAT_GRAY16 ) {
// XitonのIRのフォーマットは16bitグレースケール
// 実際は255諧調らしく、CV_8Uに落とさないと見えない
colorImage = cv::Mat( colorStream.getVideoMode().getResolutionY(),
colorStream.getVideoMode().getResolutionX(),
CV_16U, (char*)colorFrame.getData() );
colorImage.convertTo( colorImage, CV_8U );
}
else {
// KinectのIRのフォーマットは8bitグレースケール
colorImage = cv::Mat( colorStream.getVideoMode().getResolutionY(),
colorStream.getVideoMode().getResolutionX(),
CV_8U, (char*)colorFrame.getData() );
}
cv::imshow( "IR Image", colorImage );
}
}
int key = cv::waitKey( 10 );
if ( key == 'q' ) {
break;
}
}
}
catch ( std::exception& ) {
std::cout << openni::OpenNI::getExtendedError() << std::endl;
}
}
openni::VideoStream::create() で openni::SensorType::SENSOR_IR を指定して開くと、IR画像を取得することができます。
表示もピクセルフォーマット以外ほぼ同じなのですが、Kinectの場合はGray8bit 640x480に対して、Xtionの場合は、Gray16bit 320x240になりますので、それに合わせます。ただし、XtionはGray16bitといいつつ、実質Gray8bit相当のデータのようで、8bitデータに変換しないとデータを確認できませんでした(これについては、仕様なのかバグなのか不明です)。
なお、おそらくPrimeSense系デバイスの使用みたいなのですが、Colorカメラの画像と、IR画像は排他になるようです。
- Kinectでの実行結果
- Xtionでの実行結果