也就是將骨架結合影像,順便來衝篇數XDDD
結合後可以幹嗎?就可以用一把光劍啊,或者讓使用者測試衣服是否符合自己的需求等等的功能
using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using Microsoft.Kinect; namespace WpfApplication3 { /// <summary> /// MainWindow.xaml 的互動邏輯 /// </summary> public partial class MainWindow : Window { //影像寬度 private const float RenderWidth = 640.0f; //影像高度 private const float RenderHeight = 480.0f; //關節厚度 private const double JointThickness = 3; //身體中間厚度 private const double BodyCenterThickness = 10; //整體區塊厚度 private const double ClipBoundsThickness = 10; //身體刷子 private readonly Brush centerPointBrush = Brushes.Blue; //追蹤關節筆刷 private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68)); //位置的筆刷 private readonly Brush inferredJointBrush = Brushes.Yellow; //追蹤的筆 private readonly Pen trackedBonePen = new Pen(Brushes.Green, 6); //位置的筆 private readonly Pen inferredBonePen = new Pen(Brushes.Gray, 1); //繪圖集合 private DrawingGroup drawingGroup; //繪圖影像 private DrawingImage imageSource; //感應器 private KinectSensor sensor; private byte[] dataPixels = null; public MainWindow() { InitializeComponent(); } #region 表單載入 private void Window_Loaded(object sender, RoutedEventArgs e) { //Refresh drawingGroup = new DrawingGroup(); imageSource = new DrawingImage(drawingGroup); Image.Source = this.imageSource; sensor = KinectSensor.KinectSensors[0]; if (sensor != null) { sensor.SkeletonStream.Enable(); sensor.ColorStream.Enable(); sensor.SkeletonFrameReady += SensorSkeletonFrameReady; sensor.ColorFrameReady += SensorColorFrameReady; sensor.Start(); } } #endregion 表單載入 #region 結束程式 private void Window_Unloaded(object sender, RoutedEventArgs e) { sensor.Stop(); } #endregion 結束程式 #region 處理超過邊界的事件 private void RenderClippedEdges(Skeleton skeleton, DrawingContext drawingContext) { //超過最底,則會紅線 if (skeleton.ClippedEdges.HasFlag(FrameEdges.Bottom)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(0, RenderHeight - ClipBoundsThickness, RenderWidth, ClipBoundsThickness)); } //超過最頂端,則顯示紅線 if (skeleton.ClippedEdges.HasFlag(FrameEdges.Top)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(0, 0, RenderWidth, ClipBoundsThickness)); } //超過最左邊,則顯示紅線 if (skeleton.ClippedEdges.HasFlag(FrameEdges.Left)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(0, 0, ClipBoundsThickness, RenderHeight)); } //超過最右邊,則顯示紅線 if (skeleton.ClippedEdges.HasFlag(FrameEdges.Right)) { drawingContext.DrawRectangle( Brushes.Red, null, new Rect(RenderWidth - ClipBoundsThickness, 0, ClipBoundsThickness, RenderHeight)); } } #endregion 處理超過邊界的事件 #region 感應器接收資料 private void SensorColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) { using (ColorImageFrame frame = e.OpenColorImageFrame()) { if (frame != null) { dataPixels = new byte[frame.PixelDataLength]; frame.CopyPixelDataTo(dataPixels); } } } private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { Skeleton[] skeletons = new Skeleton[0]; using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()) { if (skeletonFrame != null) { skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo(skeletons); } } //取得目前背景 using (DrawingContext dc = this.drawingGroup.Open()) { BitmapSource source = BitmapSource.Create((int)RenderWidth, (int)RenderHeight, 96, 96, PixelFormats.Bgr32, null, dataPixels, 640 * 4); //將背景重畫 //dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight)); dc.DrawImage(source, new Rect(0.0, 0.0, RenderWidth, RenderHeight)); //還有資料傳入 if (skeletons.Length != 0) { foreach (Skeleton skel in skeletons) { RenderClippedEdges(skel, dc); if (skel.TrackingState == SkeletonTrackingState.Tracked) { DrawBonesAndJoints(skel, dc); } else if (skel.TrackingState == SkeletonTrackingState.PositionOnly) { dc.DrawEllipse( centerPointBrush, null, SkeletonPointToScreen(skel.Position), BodyCenterThickness, BodyCenterThickness); } } } // prevent drawing outside of our render area drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight)); } } #endregion 感應器接收資料 #region 畫出骨頭與關節 private void DrawBonesAndJoints(Skeleton skeleton, DrawingContext drawingContext) { // Render Torso DrawBone(skeleton, drawingContext, JointType.Head, JointType.ShoulderCenter); DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderLeft); DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderRight); DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.Spine); DrawBone(skeleton, drawingContext, JointType.Spine, JointType.HipCenter); DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipLeft); DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipRight); // Left Arm DrawBone(skeleton, drawingContext, JointType.ShoulderLeft, JointType.ElbowLeft); DrawBone(skeleton, drawingContext, JointType.ElbowLeft, JointType.WristLeft); DrawBone(skeleton, drawingContext, JointType.WristLeft, JointType.HandLeft); // Right Arm DrawBone(skeleton, drawingContext, JointType.ShoulderRight, JointType.ElbowRight); DrawBone(skeleton, drawingContext, JointType.ElbowRight, JointType.WristRight); DrawBone(skeleton, drawingContext, JointType.WristRight, JointType.HandRight); // Left Leg DrawBone(skeleton, drawingContext, JointType.HipLeft, JointType.KneeLeft); DrawBone(skeleton, drawingContext, JointType.KneeLeft, JointType.AnkleLeft); DrawBone(skeleton, drawingContext, JointType.AnkleLeft, JointType.FootLeft); // Right Leg DrawBone(skeleton, drawingContext, JointType.HipRight, JointType.KneeRight); DrawBone(skeleton, drawingContext, JointType.KneeRight, JointType.AnkleRight); DrawBone(skeleton, drawingContext, JointType.AnkleRight, JointType.FootRight); // Render Joints foreach (Joint joint in skeleton.Joints) { Brush drawBrush = null; if (joint.TrackingState == JointTrackingState.Tracked) //追蹤中 { drawBrush = this.trackedJointBrush; } else if (joint.TrackingState == JointTrackingState.Inferred) //大概位置 { drawBrush = this.inferredJointBrush; } //如果畫筆有被設置,畫出關節為橢圓形 if (drawBrush != null) { drawingContext.DrawEllipse(drawBrush, null, SkeletonPointToScreen(joint.Position), JointThickness, JointThickness); } } } #endregion 畫出骨頭與關節 private Point SkeletonPointToScreen(SkeletonPoint skelpoint) { DepthImagePoint depthPoint = this.sensor.CoordinateMapper.MapSkeletonPointToDepthPoint(skelpoint, DepthImageFormat.Resolution640x480Fps30); return new Point(depthPoint.X, depthPoint.Y); } private void DrawBone(Skeleton skeleton, DrawingContext drawingContext, JointType jointType0, JointType jointType1) { Joint joint0 = skeleton.Joints[jointType0]; Joint joint1 = skeleton.Joints[jointType1]; //找不到任何追蹤的點就不動作 if (joint0.TrackingState == JointTrackingState.NotTracked || joint1.TrackingState == JointTrackingState.NotTracked) { return; } //找不到任何位置就不動作 if (joint0.TrackingState == JointTrackingState.Inferred && joint1.TrackingState == JointTrackingState.Inferred) { return; } //兩者都有就畫出位置 Pen drawPen = this.inferredBonePen; if (joint0.TrackingState == JointTrackingState.Tracked && joint1.TrackingState == JointTrackingState.Tracked) { drawPen = trackedBonePen; } //畫出關節與關節的線 drawingContext.DrawLine(drawPen, SkeletonPointToScreen(joint0.Position), SkeletonPointToScreen(joint1.Position)); } } }
參考資料:
http://writecodepeople.blogspot.tw/2013/05/cnet-kinect.html
http://writecodepeople.blogspot.tw/2013/05/cnet-wpfkinect.html