/// <summary> /// 距離データをカラー画像に変換する /// </summary> /// <param name="kinect"></param> /// <param name="depthFrame"></param> /// <returns></returns> private byte[] ConvertDepthColor( KinectSensor kinect, DepthImageFrame depthFrame ) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // 距離カメラのピクセルごとのデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo( depthPixel ); // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame( depthStream.Format, depthPixel, colorStream.Format, colorPoint ); byte[] depthColor = new byte[depthFrame.PixelDataLength * Bgr32BytesPerPixel]; for ( int index = 0; index < depthPixel.Length; index++ ) { // 距離カメラのデータから、プレイヤーIDと距離を取得する int player = depthPixel[index] & DepthImageFrame.PlayerIndexBitmask; int distance = depthPixel[index] >> DepthImageFrame.PlayerIndexBitmaskWidth; // 変換した結果が、フレームサイズを超えることがあるため、小さいほうを使う int x = Math.Min( colorPoint[index].X, colorStream.FrameWidth - 1 ); int y = Math.Min( colorPoint[index].Y, colorStream.FrameHeight - 1 ); int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel; if ( player != 0 ) { depthColor[colorIndex] = 255; depthColor[colorIndex + 1] = 255; depthColor[colorIndex + 2] = 255; } else { // サポート外 0-40cm if ( distance == depthStream.UnknownDepth ) { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 0; depthColor[colorIndex + 2] = 255; } // 近すぎ 40cm-80cm(default mode) else if ( distance == depthStream.TooNearDepth ) { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 255; depthColor[colorIndex + 2] = 0; } // 遠すぎ 3m(Near),4m(Default)-8m else if ( distance == depthStream.TooFarDepth ) { depthColor[colorIndex] = 255; depthColor[colorIndex + 1] = 0; depthColor[colorIndex + 2] = 0; } // 有効な距離データ else { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 255; depthColor[colorIndex + 2] = 255; } } } return depthColor; }
/// <summary> /// プレーヤーだけ表示する /// </summary> /// <param name="colorFrame"></param> /// <param name="depthFrame"></param> /// <returns></returns> private byte[] BackgroundMask( KinectSensor kinect, ColorImageFrame colorFrame, DepthImageFrame depthFrame ) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // RGBカメラのピクセルごとのデータを取得する byte[] colorPixel = new byte[colorFrame.PixelDataLength]; colorFrame.CopyPixelDataTo( colorPixel ); // 距離カメラのピクセルごとのデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo( depthPixel ); // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame( depthStream.Format, depthPixel, colorStream.Format, colorPoint ); // 出力バッファ(初期値は白(255,255,255)) byte[] outputColor = new byte[colorPixel.Length]; for ( int i = 0; i < outputColor.Length; i += Bgr32BytesPerPixel ) { outputColor[i] = 255; outputColor[i + 1] = 255; outputColor[i + 2] = 255; } for ( int index = 0; index < depthPixel.Length; index++ ) { // プレイヤーを取得する int player = depthPixel[index] & DepthImageFrame.PlayerIndexBitmask; // 変換した結果が、フレームサイズを超えることがあるため、小さいほうを使う int x = Math.Min( colorPoint[index].X, colorStream.FrameWidth - 1 ); int y = Math.Min( colorPoint[index].Y, colorStream.FrameHeight - 1 ); int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel; // プレーヤーを検出した座標だけ、RGBカメラの画像を使う if ( player != 0 ) { outputColor[colorIndex] = colorPixel[colorIndex]; outputColor[colorIndex + 1] = colorPixel[colorIndex + 1]; outputColor[colorIndex + 2] = colorPixel[colorIndex + 2]; } } return outputColor; }
/// <summary> /// 距離データをカラー画像に変換する /// </summary> /// <param name="kinect"></param> /// <param name="depthFrame"></param> /// <returns></returns> private byte[] ConvertDepthColor( KinectSensor kinect, DepthImageFrame depthFrame ) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // 距離カメラのピクセルごとのデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo( depthPixel ); // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame( depthStream.Format, depthPixel, colorStream.Format, colorPoint ); byte[] depthColor = new byte[depthFrame.PixelDataLength * Bgr32BytesPerPixel]; for ( int index = 0; index < depthPixel.Length; index++ ) { // 距離カメラのデータから、プレイヤーIDと距離を取得する int player = depthPixel[index] & DepthImageFrame.PlayerIndexBitmask; int distance = depthPixel[index] >> DepthImageFrame.PlayerIndexBitmaskWidth; // 変換した結果が、フレームサイズを超えることがあるため、小さいほうを使う int x = Math.Min( colorPoint[index].X, colorStream.FrameWidth - 1 ); int y = Math.Min( colorPoint[index].Y, colorStream.FrameHeight - 1 ); int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel; // プレイヤーがいるピクセルの場合 if ( player != 0 ) { // 有効なプレーヤーに色付けする if ( enablePlayer[player] ) { depthColor[colorIndex] = playerColor[player].B; depthColor[colorIndex + 1] = playerColor[player].G; depthColor[colorIndex + 2] = playerColor[player].R; } } } return depthColor; }
/// <summary> /// 距離データをカラー画像に変換する /// </summary> /// <param name="kinect"></param> /// <param name="depthFrame"></param> /// <returns></returns> private void HeightMeasure( KinectSensor kinect, DepthImageFrame depthFrame, SkeletonFrame skeletonFrame ) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // トラッキングされている最初のスケルトンを取得する // インデックスはプレイヤーIDに対応しているのでとっておく Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo( skeletons ); int playerIndex = 0; for ( playerIndex = 0; playerIndex < skeletons.Length; playerIndex++ ) { if ( skeletons[playerIndex].TrackingState == SkeletonTrackingState.Tracked ) { break; } } if ( playerIndex == skeletons.Length ) { return; } // トラッキングされている最初のスケルトン Skeleton skeleton = skeletons[playerIndex]; // 実際のプレイヤーIDは、スケルトンのインデックス+1 playerIndex++; // 頭、足先がトラッキングされていない場合は、そのままRGBカメラのデータを返す Joint head = skeleton.Joints[JointType.Head]; Joint leftFoot = skeleton.Joints[JointType.FootLeft]; Joint rightFoot = skeleton.Joints[JointType.FootRight]; if ( (head.TrackingState != JointTrackingState.Tracked) || (leftFoot.TrackingState != JointTrackingState.Tracked) || (rightFoot.TrackingState != JointTrackingState.Tracked) ) { return; } // 距離カメラのピクセルごとのデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo( depthPixel ); // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame( depthStream.Format, depthPixel, colorStream.Format, colorPoint ); // 頭のてっぺんを探す DepthImagePoint headDepth = depthFrame.MapFromSkeletonPoint( head.Position ); int top = 0; for ( int i = 0; (headDepth.Y - i) > 0; i++ ) { // 一つ上のY座標を取得し、プレイヤーがいなければ、現在の座標が最上位 int index = ((headDepth.Y - i) * depthFrame.Width) + headDepth.X; int player = depthPixel[index] & DepthImageFrame.PlayerIndexBitmask; if ( player == playerIndex ) { top = i; } } // 頭のてっぺんを3次元座標に戻し、足の座標(下にあるほう)を取得する // この差分で身長を測る head.Position = depthFrame.MapToSkeletonPoint( headDepth.X, headDepth.Y - top ); Joint foot = (leftFoot.Position.Y < rightFoot.Position.Y) ? leftFoot : rightFoot; // 背丈を表示する DrawMeasure( kinect, colorStream, head, foot ); }
/// <summary> /// 光学迷彩 /// </summary> /// <param name="kinect"></param> /// <param name="colorFrame"></param> /// <param name="depthFrame"></param> /// <returns></returns> private byte[] OpticalCamouflage( KinectSensor kinect, ColorImageFrame colorFrame, DepthImageFrame depthFrame ) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // RGBカメラのピクセルごとのデータを取得する byte[] colorPixel = new byte[colorFrame.PixelDataLength]; colorFrame.CopyPixelDataTo( colorPixel ); // 背景がないときは、そのときのフレームを背景として保存する if ( backPixel == null ) { backPixel = new byte[colorFrame.PixelDataLength]; Array.Copy( colorPixel, backPixel, backPixel.Length ); } // 距離カメラのピクセルごとのデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo( depthPixel ); // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame( depthStream.Format, depthPixel, colorStream.Format, colorPoint ); // 出力バッファ(初期値はRGBカメラの画像) byte[] outputColor = new byte[colorPixel.Length]; Array.Copy( colorPixel, outputColor, outputColor.Length ); for ( int index = 0; index < depthPixel.Length; index++ ) { // プレイヤーを取得する int player = depthPixel[index] & DepthImageFrame.PlayerIndexBitmask; // 変換した結果が、フレームサイズを超えることがあるため、小さいほうを使う int x = Math.Min( colorPoint[index].X, colorStream.FrameWidth - 1 ); int y = Math.Min( colorPoint[index].Y, colorStream.FrameHeight - 1 ); int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel; // プレーヤーを検出した座標は、背景画像を使う if ( player != 0 ) { outputColor[colorIndex] = backPixel[colorIndex]; outputColor[colorIndex + 1] = backPixel[colorIndex + 1]; outputColor[colorIndex + 2] = backPixel[colorIndex + 2]; } } return outputColor; }
/// <summary> /// 距離データの画像変換 /// </summary> /// <param name="kinect">Kinect センサー</param> /// <param name="depthFrame">深度フレームデータ</param> /// <returns>距離データの画像データ</returns> private byte[] _ConvertDepthColor(KinectSensor kinect, DepthImageFrame depthFrame) { ColorImageStream colorStream = kinect.ColorStream; DepthImageStream depthStream = kinect.DepthStream; // 距離カメラのピクセル毎のデータを取得する short[] depthPixel = new short[depthFrame.PixelDataLength]; depthFrame.CopyPixelDataTo(depthPixel); // 距離カメラの座標に対する RGB カメラ座標を取得する(座標合わせ) ColorImagePoint[] colorPoint = new ColorImagePoint[depthFrame.PixelDataLength]; kinect.MapDepthFrameToColorFrame(depthStream.Format, depthPixel, colorStream.Format, colorPoint); byte[] depthColor = new byte[depthFrame.PixelDataLength * Bgr32BytesPerPixel]; int pxLen = depthPixel.Length; for (int i = 0; i < pxLen; i++) { int distance = depthPixel[i] >> DepthImageFrame.PlayerIndexBitmaskWidth; // 変換した結果がフレームサイズを超えないよう、小さい方を採用 int x = Math.Min(colorPoint[i].X, colorStream.FrameWidth - 1); int y = Math.Min(colorPoint[i].Y, colorStream.FrameHeight - 1); int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel; // サポート外 0-40cm if (distance == depthStream.UnknownDepth) { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 0; depthColor[colorIndex + 2] = 255; } // 近すぎ 40cm-80cm(Default) else if (distance == depthStream.TooNearDepth) { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 255; depthColor[colorIndex + 2] = 0; } // 遠すぎ 3m(Near), 4m(Default)-8m else if (distance == depthStream.TooFarDepth) { depthColor[colorIndex] = 255; depthColor[colorIndex + 1] = 0; depthColor[colorIndex + 2] = 0; } // 有効な距離データ else { depthColor[colorIndex] = 0; depthColor[colorIndex + 1] = 255; depthColor[colorIndex + 2] = 255; } } return depthColor; }