kinectセンサーから任意の範囲の深度マップ抽出

深度マップ

  • kinectセンサーがサポートする850〜4000の範囲で深度の検出を行う。
  • それ以外は白で表示しない。
  • 基本的の深度データの操作の方法は、Working with Depth Dataより。

implementation

  • 深度を検出する関数
    • byte[] 配列で深さを表現し、1ピクセルに2バイトを使うため、それぞれに対応するビットシフトオペレーターを、タイプに応じて使う必要がある。
    • Depthタイプを使う場合
      • 2つめのみを8ビット左に
Distance (0,0) = (int)(Bits[0] | Bits[1] << 8 );
    • DepthAndPlayerIndexタイプを使う場合
      • 1つめを3ビット右に(プレイヤーインデックスをスキップ)、2つめを5ビット左に
Distance (0,0) =(int)(Bits[0] >> 3 | Bits[1] << 5);
    • 今回の例は、PlayerIndexは使わないため以下
private int GetDistance(byte firstFrame, byte secondFrame)
{
    int distance = (int)(firstFrame | secondFrame << 8);
    return distance;
}

深度マップのカラー設定

  • 範囲の設定には2つのスライダーを使用。
  • スライダーの関数の例
private void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    if (slider2.Value <= slider1.Value) //minがmaxを越えないためのチェック
        slider2.Value = slider1.Value + 10;
    maxRange = slider2.Value;

}
  • スライダーで指定した最大深度max、最小深度minの差から範囲を決定し、色の濃さを決定

255 * (distance - min)/(max - min)

  • それ以外の場所は白で表示
private byte[] GenerateColoredBytes(ImageFrame imageFrame)
{
    int height = imageFrame.Image.Height;
    int width = imageFrame.Image.Width;

    //Depth data for each pixel
    Byte[] depthData = imageFrame.Image.Bits;

    //colorFrame contains color information for all pixels in image
    //Height x Width x 4 (Red, Green, Blue, empty byte)
    Byte[] colorFrame = new byte[imageFrame.Image.Height * imageFrame.Image.Width * 4];

    //hardcoded locations to Blue, Green, Red (BGR) index positions   
    const int BlueIndex = 0;
    const int GreenIndex = 1;
    const int RedIndex = 2;

    var depthIndex = 0;
    double range = maxRange - minRange;
    for (var y = 0; y < height; y++)
    {
        var heightOffset = y * width;


        for (var x = 0; x < width; x++)
        {
            var index = ((width - x - 1) + heightOffset) * 4;

            var distance = GetDistance(depthData[depthIndex], depthData[depthIndex + 1]);

            if (distance <= minRange || distance >= maxRange)
            {
                colorFrame[index + BlueIndex] = 255;
                colorFrame[index + GreenIndex] = 255;
                colorFrame[index + RedIndex] = 255;
            }
            else
            {
                byte tmp = (byte)(255 * (distance - minRange) / range);
                colorFrame[index + BlueIndex] = tmp;
                colorFrame[index + GreenIndex] = tmp;
                colorFrame[index + RedIndex] = 10;
            }


            //jump two bytes at a time
            depthIndex += 2;
        }
    }

    return colorFrame;
}

例:

  • 手前の椅子に範囲を

  • 後ろのツボに範囲を

  • 背景のカーテンに範囲を

データのcsv出力

using Microsoft.Win32;
  • 上記のライブラリーを参照し、その時点での深度マップをcsvで出力し保存


続き