ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

KINECT for Windows SDK でビデオとデプス画像の位置合わせ

今までずっとKINECT for Windows SDKでは、ビデオとデプス(ユーザー含む)の画像を重ねる時のズレは仕方ないと思っていました。
しかし、今日ヘルプを見ていたら、たまたまそれっぽいメソッドを発見したので試してみたら、ビデオとデプスの画像がきれいに重なりました。

やり方

全体のコードはこちらを見てもらうとして、肝心のところだけ解説しますI(わかりやすいように若干変えてます)。

// 距離座標をカメラ座標に変換する
int videoX = 0, videoY = 0;
runtime.NuiCamera.GetColorPixelCoordinatesFromDepthPixel( ImageResolution.Resolution640x480,
        new ImageViewArea(), x, y, 0, out videoX, out videoY ); 

int videoIndex = (videoX + (videoY * video.Image.Width)) * 4;
videoIndex = Math.Min( videoIndex, video.Image.Bits.Length - 4 );
video.Image.Bits[videoIndex    ] = Color.Red.B;
video.Image.Bits[videoIndex + 1] = Color.Red.G;
video.Image.Bits[videoIndex + 2] = Color.Red.R;
GetColorPixelCoordinatesFromDepthPixel
public void GetColorPixelCoordinatesFromDepthPixel (
    ImageResolution colorResolution, // カメラの解像度(現在はResolution640x480のみサポート)
    ImageViewArea viewArea,          // ズームなどの設定。特に指定しない場合は new ImageViewArea() でOK
    int depthX,                      // デプスのX位置
    int depthY,                      // デプスのY位置
    short depthValue,                // デプスの値(特に指定しない場合は 0 でOK)
    out int videoX,                  // 指定したデプスのX位置に対応した、ビデオのX位置
    out int videoY                   // 指定したデプスのY位置に対応した、ビデオのY位置

RuntimeクラスのCameraフィールドにGetColorPixelCoordinatesFromDepthPixelという長いメソッドがあります。
(たぶん)名前のとおり、デプスピクセルからカラーピクセルを取得する。というもので、引数は上記のとおりです。

ぐぐってみたら、KINECT for Windows SDKのウォークスルーに書いてあったんですね(docファイル)


ここで出力されたvideoX、およびvideoYをビデオストリームのインデックスに使用すると、ピッタリ座標を合わせることができました。
ただし、ビデオは640x480、デプスは320x240と小さいので、ベタ塗りのようにはならず、メッシュがかったようになります。工夫次第でなんとでもなりそうですが。