本ページで紹介している内容のサンプルソースコードは以下からダウンロードできます.
kinect-sample.zip
1 Kinectを初期化して終了する
Kinect for Windows SDK 2.0 を使うには,Kinect.h をインクルードする.
またリンクするライブラリとして,Kinect20.lib を追加する必要がある.
Visual Studio では,プロジェクトのプロパティ > 構成プロパティ > リンカー > 入力 > 追加の依存ファイル に記述する.
2 カラー画像を取得する
カラー画像は,横1920ピクセル,縦1080ピクセルで,
1ピクセルに格納されている色情報のフォーマットは様々なものが
用意されており,一般的な赤緑青それぞれ1バイトでの出力は勿論可能である.
画角は,横方向84.1度,縦方向53.8度,対角91.9度である.
初期化の手順は以下の通り.
- Kinectを初期化する.
- Color Frame Source (IColorFrameSource) を取得する.
- Color Frame Reader (IColorFrameReader) を開く.
カラー画像の取得方法は以下の通り.
- Color Frame Reader から現在の画像を取得する.
IColorFrameReader::AcquireLatestFrame() を呼ぶ.
Color Frame (IColorFrame) が得られる.
失敗する場合もあるので注意. - Color Frame のデータをお好みのフォーマットに変換する.
IColorFrame::CopyConvertedFrameDataToArray() を呼び,
OpenCVのcv::Matのデータ実体部にコピーする.
フォーマットとして,ColorImageFormat_Bgra を指定すると,
OpenCVのCV_8UC4の並びと同じになる.
一応,cv::Matのデータ領域の連続性をチェックして,連続している場合と
不連続な場合に対応しておく. - Color Frameは不要になったらリリースする.
以上で,カラー画像をOpenCVで扱える画像(フォーマット:CV_8UC3)として
得ることができる.
3 デプス画像を取得する
デプス(距離)画像は,横512ピクセル,縦424ピクセルで,
1ピクセルに格納されている距離情報はunsigned short型(2バイト)である.
距離の範囲は0から8000と思われる.1=1mmに対応している.
参考までに,
IDepthFrame::get_DepthMinReliableDistance()および
IDepthFrame::get_DepthMaxReliableDistance()を使用すると
信頼できる距離範囲が取得できる.
テストした限りにおいては,常に信頼範囲は500から4500であった.
画角は,横方向70.6度,縦方向60.0度,対角89.5度である.
初期化の手順は以下の通り.
- Kinectを初期化する.
- Depth Frame Source (IDepthFrameSource) を取得する.
- Depth Frame Reader (IDepthFrameReader) を開く.
デプス画像の取得方法は以下の通り.
- Depth Frame Reader から現在の画像を取得する.
IDepthFrameReader::AcquireLatestFrame() を呼ぶ.
Depth Frame (IDepthFrame) が得られる.
失敗する場合もあるので注意. - 各ピクセルの距離が入っているバッファの先頭アドレスを取得する.
IDepthFrame::AccessUnderlyingBuffer() を呼ぶ. - データの実体をOpenCVのcv::Matにコピーする.
memcpy()で行う.
一応,cv::Matのデータ領域の連続性をチェックして,連続している場合と
不連続な場合に対応しておく. - Depth Frameは不要になったらリリースする.
以上で,デプス画像をOpenCVで扱える画像(フォーマット:CV_16UC1)として
得ることができる.
4 カラー画像とデプス画像の対応
MapColorFrameToDepthSpace() によって,カラー画像の各画素が,
デプス画像のどの画素に対応しているかというマッピング情報を得ることができる.
マッピング情報は DepthSpacePoint 構造体で与えられる.
typedef struct _DepthSpacePoint { float X; float Y; } DepthSpacePoint;
対応が取れない場合は,`-std::numeric_limits<float>::infinity()` が入るようだ.
XおよびYはfloat型なので,まずint型にキャスト(型変換)し,キャスト後の座標が
デプス画像内におさまっていることを確認してから,デプス値を取得する.
デプス値は UINT16 型(2バイト符号無し整数,大概は unsigned short)である.