private static void DrawEllipse( KinectSensor kinect, Graphics g, SkeletonPoint position ) { const int R = 5; ColorImagePoint point = kinect.MapSkeletonPointToColor( position, kinect.ColorStream.Format ); g.DrawEllipse( new Pen( Brushes.Red, R ), new Rectangle( point.X - R, point.Y - R, R * 2, R * 2 ) ); }
public static Vector2 Convert(KinectSensor sensor, SkeletonPoint position) { float width = 0; float height = 0; float x = 0; float y = 0; if (sensor.ColorStream.IsEnabled) { var colorPoint = sensor.MapSkeletonPointToColor(position, sensor.ColorStream.Format); x = colorPoint.X; y = colorPoint.Y; switch (sensor.ColorStream.Format) { case ColorImageFormat.RawYuvResolution640x480Fps15: case ColorImageFormat.RgbResolution640x480Fps30: case ColorImageFormat.YuvResolution640x480Fps15: width = 640; height = 480; break; case ColorImageFormat.RgbResolution1280x960Fps12: width = 1280; height = 960; break; } } else if (sensor.ColorStream.IsEnabled) { var depthPoint = sensor.MapSkeletonPointToDepth(position, sensor.DepthStream.Format); x = depthPoint.X; y = depthPoint.Y; switch (sensor.DepthStream.Format) { case DepthImageFormat.Resolution80x60Fps30: width = 80; height = 60; break; case DepthImageFormat.Resolution320x240Fps30: width = 320; height = 240; break; case DepthImageFormat.Resolution640x480Fps30: width = 640; height = 480; break; } } else { width = 1; height = 1; } return new Vector2(x / width, y / height); }
/// <summary> /// ジョイントの円を描く /// </summary> /// <param name="kinect"></param> /// <param name="position"></param> private void DrawEllipse( KinectSensor kinect, SkeletonPoint position ) { const int R = 5; // スケルトンの座標を、RGBカメラの座標に変換する ColorImagePoint point = kinect.MapSkeletonPointToColor( position, kinect.ColorStream.Format ); // 座標を画面のサイズに変換する point.X = (int)ScaleTo( point.X, kinect.ColorStream.FrameWidth, canvasSkeleton.Width ); point.Y = (int)ScaleTo( point.Y, kinect.ColorStream.FrameHeight, canvasSkeleton.Height ); // 円を描く canvasSkeleton.Children.Add( new Ellipse() { Fill = new SolidColorBrush( Colors.Red ), Margin = new Thickness( point.X - R, point.Y - R, 0, 0 ), Width = R * 2, Height = R * 2, } ); }
/// <summary> /// トラッキングされているスケルトンのジョイントを描画する /// </summary> /// <param name="kinect"></param> /// <param name="joints"></param> private void DrawSkeleton( KinectSensor kinect, Joint[] joints ) { // 描画する円の半径 const int R = 5; // キャンバスをクリアする canvasSkeleton.Children.Clear(); // ジョイントを描画する foreach ( Joint joint in joints ) { // ジョイントがトラッキングされていなければ次へ if ( joint.TrackingState != JointTrackingState.Tracked ) { continue; } // スケルトンの座標を、RGBカメラの座標に変換して円を書く ColorImagePoint point = kinect.MapSkeletonPointToColor( joint.Position, kinect.ColorStream.Format ); canvasSkeleton.Children.Add( new Ellipse() { Fill = new SolidColorBrush( Colors.Red ), Margin = new Thickness( point.X - R, point.Y - R, 0, 0 ), Width = R * 2, Height = R * 2, } ); } }
private void DrawMain(KinectSensor kinectSensor, ColorImageFrame colorImageFrame, List<SkeletonPoint> hipCenterPointList) { this.DrawRGBImage(colorImageFrame); this.barArray[0].isActive = true; this.barArray[1].isActive = (hipCenterPointList.Count > 1) ? true : false; if (!this.barArray[1].isActive) { this.barArray[1].x = -Bar.width; } if (hipCenterPointList.Count > 0) { for (int i = 0; i < hipCenterPointList.Count; i++) { ColorImagePoint hipCenterColorImagePoint = kinectSensor.MapSkeletonPointToColor( hipCenterPointList[i], ColorImageFormat.RgbResolution640x480Fps30); this.barArray[i].Move(hipCenterColorImagePoint.X); } } this.barArray[0].Draw(this.mainImageBuffer); if (this.barArray[1].isActive) this.barArray[1].Draw(this.mainImageBuffer); this.ball.Move(); if (this.ball.CheckGameOver()) { this.gameState = GameState.GameOver; this.gameOverDateTime = DateTime.Now; this.sound.gameOverSound.Play(); for (int i = 0; i < this.barArray.Length; i++) this.barArray[i].ResetPosition(); this.ball.Reset(); return; } this.ball.CheckCollisionWithWall(); this.ball.CheckCollisionWithBar(); this.ball.CheckCollisionWithBlock(); if (this.ball.CheckGameClear()) { this.gameState = GameState.GameClear; this.gameClearDateTime = DateTime.Now; this.sound.gameClearSound.Play(); for (int i = 0; i < this.barArray.Length; i++) this.barArray[i].ResetPosition(); this.ball.Reset(); } this.ball.Draw(this.mainImageBuffer); for (int i = 0; i < this.blockArray.Length; i++) this.blockArray[i].Draw(this.mainImageBuffer); this.score.DrawScoreOnMainWindow(this.textBlockScore); }
/// <summary> /// Returns the 2D position of the provided 3D SkeletonPoint. /// The result will be in in either Color coordinate space or Depth coordinate space, depending on /// the current value of this.ImageType. /// Only those parameters associated with the current ImageType will be used. /// </summary> /// <param name="sensor">The KinectSensor for which this mapping is being performed.</param> /// <param name="imageType">The target image type</param> /// <param name="renderSize">The target dimensions of the visualization</param> /// <param name="skeletonPoint">The source point to map</param> /// <param name="colorFormat">The format of the target color image, if imageType is Color</param> /// <param name="colorWidth">The width of the target color image, if the imageType is Color</param> /// <param name="colorHeight">The height of the target color image, if the imageType is Color</param> /// <param name="depthFormat">The format of the target depth image, if the imageType is Depth</param> /// <param name="depthWidth">The width of the target depth image, if the imageType is Depth</param> /// <param name="depthHeight">The height of the target depth image, if the imageType is Depth</param> /// <returns>Returns the 2D position of the provided 3D SkeletonPoint.</returns> private static Point Get2DPosition( KinectSensor sensor, ImageType imageType, Size renderSize, SkeletonPoint skeletonPoint, ColorImageFormat colorFormat, int colorWidth, int colorHeight, DepthImageFormat depthFormat, int depthWidth, int depthHeight) { try { switch (imageType) { case ImageType.Color: if (ColorImageFormat.Undefined != colorFormat) { var colorPoint = sensor.MapSkeletonPointToColor(skeletonPoint, colorFormat); // map back to skeleton.Width & skeleton.Height return new Point( (int)(renderSize.Width * colorPoint.X / colorWidth), (int)(renderSize.Height * colorPoint.Y / colorHeight)); } break; case ImageType.Depth: if (DepthImageFormat.Undefined != depthFormat) { var depthPoint = sensor.MapSkeletonPointToDepth(skeletonPoint, depthFormat); return new Point( (int)(renderSize.Width * depthPoint.X / depthWidth), (int)(renderSize.Height * depthPoint.Y / depthHeight)); } break; } } catch (InvalidOperationException) { // The stream must have stopped abruptly // Handle this gracefully } return new Point(); }
/// <summary> /// 背丈を表示する /// </summary> /// <param name="kinect"></param> /// <param name="colorStream"></param> /// <param name="head"></param> /// <param name="foot"></param> private void DrawMeasure( KinectSensor kinect, ColorImageStream colorStream, Joint head, Joint foot ) { // 頭と足の座標の差分を身長とする(メートルからセンチメートルに変換する) int height = (int)(Math.Abs( head.Position.Y - foot.Position.Y ) * 100); // 頭と足のスケルトン座標を、RGBカメラの座標に変換する ColorImagePoint headColor = kinect.MapSkeletonPointToColor( head.Position, colorStream.Format ); ColorImagePoint footColor = kinect.MapSkeletonPointToColor( foot.Position, colorStream.Format ); // RGBカメラの座標を、表示する画面の座標に変換する Point headScalePoint = new Point( ScaleTo( headColor.X, colorStream.FrameWidth, canvasMeasure.Width ), ScaleTo( headColor.Y, colorStream.FrameHeight, canvasMeasure.Height ) ); Point footScalePoint = new Point( ScaleTo( footColor.X, colorStream.FrameWidth, canvasMeasure.Width ), ScaleTo( footColor.Y, colorStream.FrameHeight, canvasMeasure.Height ) ); const int lineLength = 50; const int thickness = 10; canvasMeasure.Children.Clear(); // 頭の位置 canvasMeasure.Children.Add( new Line() { Stroke = new SolidColorBrush( Colors.Red ), X1 = headScalePoint.X, Y1 = headScalePoint.Y, X2 = headScalePoint.X + lineLength, Y2 = headScalePoint.Y, StrokeThickness = thickness, } ); // 足の位置 canvasMeasure.Children.Add( new Line() { Stroke = new SolidColorBrush( Colors.Red ), X1 = footScalePoint.X, Y1 = footScalePoint.Y, X2 = headScalePoint.X + lineLength, Y2 = footScalePoint.Y, StrokeThickness = thickness, } ); // 頭と足を結ぶ線 canvasMeasure.Children.Add( new Line() { Stroke = new SolidColorBrush( Colors.Red ), X1 = headScalePoint.X + lineLength, Y1 = headScalePoint.Y, X2 = headScalePoint.X + lineLength, Y2 = footScalePoint.Y, StrokeThickness = thickness, } ); // 身長の表示Y位置 double Y = Math.Abs( headScalePoint.Y + footScalePoint.Y ) / 2; canvasMeasure.Children.Add( new TextBlock() { Margin = new Thickness( headScalePoint.X + lineLength, Y, 0, 0 ), Text = height.ToString(), Height = 36, Width = 60, FontSize = 24, FontWeight = FontWeights.Bold, Background = new SolidColorBrush( Colors.White ), } ); }
/// <summary> /// スケルトンを描画する /// </summary> /// <param name="kinect"></param> /// <param name="skeletonFrame"></param> /// <param name="source"></param> /// <returns></returns> private RenderTargetBitmap DrawSkeleton( KinectSensor kinect, SkeletonFrame skeletonFrame, ImageSource source ) { // スケルトンのデータを取得する Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo( skeletons ); DrawingVisual drawingVisual = new DrawingVisual(); using ( DrawingContext drawingContext = drawingVisual.RenderOpen() ) { // ImageSourceを描画する drawingContext.DrawImage( source, new Rect( 0, 0, source.Width, source.Height ) ); // トラッキングされているスケルトンのジョイントを描画する const int R = 5; foreach ( var skeleton in skeletons ) { // スケルトンがトラッキングされていなければ次へ if ( skeleton.TrackingState != SkeletonTrackingState.Tracked ) { continue; } // ジョイントを描画する foreach ( Joint joint in skeleton.Joints ) { // ジョイントがトラッキングされていなければ次へ if ( joint.TrackingState != JointTrackingState.Tracked ) { continue; } // スケルトンの座標を、RGBカメラの座標に変換して円を書く ColorImagePoint point = kinect.MapSkeletonPointToColor( joint.Position, kinect.ColorStream.Format ); drawingContext.DrawEllipse( new SolidColorBrush( Colors.Red ), new Pen( Brushes.Red, 1 ), new Point( point.X, point.Y ), R, R ); } } } // 描画可能なビットマップを作る RenderTargetBitmap bitmap = new RenderTargetBitmap( (int)source.Width, (int)source.Height, 96, 96, PixelFormats.Default ); bitmap.Render( drawingVisual ); return bitmap; }
/// <summary> /// 交差点の描画 /// </summary> /// <param name="kinect"></param> /// <param name="skeletonFrame"></param> private void DrawCrossPoint( KinectSensor kinect, SkeletonFrame skeletonFrame ) { // 描画する円の半径 const int R = 5; // キャンバスをクリアする canvas.Children.Clear(); // スケルトンから4か所の座標を取得(左肘・手、右肘・手) var joints = GetFourSkeletonPosition( skeletonFrame, JointType.ElbowLeft, JointType.HandLeft, JointType.ElbowRight, JointType.HandRight ); if ( joints == null ) { return; } // スケルトン座標をRGB画像の座標に変換し表示する ColorImagePoint[] jointImagePosition = new ColorImagePoint[4]; for ( int i = 0; i < 4; i++ ) { jointImagePosition[i] = kinect.MapSkeletonPointToColor( joints[i].Position, kinect.ColorStream.Format ); canvas.Children.Add( new Ellipse() { Fill = new SolidColorBrush( Colors.Yellow ), Margin = new Thickness( jointImagePosition[i].X - R, jointImagePosition[i].Y - R, 0, 0 ), Width = R * 2, Height = R * 2, } ); } // 腕がクロスしているかチェック bool isCross = CrossHitCheck( joints[0].Position, joints[1].Position, joints[2].Position, joints[3].Position ); if ( isCross ) { // クロスしている点を計算して円を表示する ColorImagePoint crossPoint = GetCrossPoint( jointImagePosition[0], jointImagePosition[1], jointImagePosition[2], jointImagePosition[3] ); CrossEllipse.Margin = new Thickness( crossPoint.X - CrossEllipse.Width / 2, crossPoint.Y - CrossEllipse.Height / 2, 0, 0 ); CrossEllipse.Visibility = System.Windows.Visibility.Visible; canvas.Children.Add( CrossEllipse ); } else { CrossEllipse.Visibility = System.Windows.Visibility.Hidden; } }
// RGBカメラの画像情報に顔の位置にマスクを上書きして描画する private void fillBitmap(KinectSensor kinect, ColorImageFrame imgFrame, List<SkeletonPoint> headList) { // 描画の準備 var drawContext = drawVisual.RenderOpen(); int frmWidth = imgFrame.Width; int frmHeight = imgFrame.Height; // 画像情報をバッファにコピー imgFrame.CopyPixelDataTo(pixelBuffer); // カメラの画像情報から背景のビットマップを作成して描写 var bgImg = new WriteableBitmap(frmWidth, frmHeight, 96, 96, PixelFormats.Bgr32, null); bgImg.WritePixels(new Int32Rect(0, 0, frmWidth, frmHeight), pixelBuffer, frmWidth * 4, 0); drawContext.DrawImage(bgImg, new Rect(0, 0, frmWidth, frmHeight)); // getHeadPointsで取得した各頭部(の位置)毎にループ for (int idx = 0; headList != null && idx < headList.Count; ++idx) { //骨格の座標から画像情報の座標に変換 ColorImagePoint headPt = kinect.MapSkeletonPointToColor(headList[idx], rgbFotmat); // 頭の位置にマスク画像を描画 Rect rect = new Rect(headPt.X - 64, headPt.Y - 64, 128, 128); drawContext.DrawImage(maskImage, rect); } //画像に表示するビットマップに描画 drawContext.Close(); bmpBuffer.Render(drawVisual); }