XAML:
<Window x:Class="WpfApplicationKinectTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Unloaded="Window_Unloaded" Loaded="Window_Loaded">
<Grid>
<Image Name="Image"></Image>
</Grid>
</Window>
Code:
using Microsoft.Kinect;
using System;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WpfApplicationKinectTest2
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// 影像寬度
/// </summary>
private const float RenderWidth = 640.0f;
/// <summary>
/// 影像高度
/// </summary>
private const float RenderHeight = 480.0f;
/// <summary>
/// 關節厚度
/// </summary>
private const double JointThickness = 3;
/// <summary>
/// 身體中間厚度
/// </summary>
private const double BodyCenterThickness = 10;
/// <summary>
/// 整體區塊厚度
/// </summary>
private const double ClipBoundsThickness = 10;
/// <summary>
/// 身體刷子
/// </summary>
private readonly Brush centerPointBrush = Brushes.Blue;
/// <summary>
/// 追蹤關節筆刷
/// </summary>
private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));
/// <summary>
/// 位置的筆刷
/// </summary>
private readonly Brush inferredJointBrush = Brushes.Yellow;
/// <summary>
/// 追蹤的筆
/// </summary>
private readonly Pen trackedBonePen = new Pen(Brushes.Green, 6);
/// <summary>
/// 位置的筆
/// </summary>
private readonly Pen inferredBonePen = new Pen(Brushes.Gray, 1);
/// <summary>
/// 繪圖集合
/// </summary>
private DrawingGroup drawingGroup;
/// <summary>
/// 繪圖影像
/// </summary>
private DrawingImage imageSource;
/// <summary>
/// 感應器
/// </summary>
private KinectSensor sensor;
/// <summary>
/// Color data bytes
/// </summary>
private byte[] dataPixels = null;
/// <summary>
/// Track ID
/// </summary>
private int trackID = -1;
public MainWindow()
{
InitializeComponent();
}
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)
{
this.sensor.SkeletonStream.Enable();
this.sensor.ColorStream.Enable();
this.sensor.DepthStream.Enable();
this.sensor.SkeletonFrameReady += SensorSkeletonFrameReady;
this.sensor.ColorFrameReady += SensorColorFrameReady;
this.sensor.DepthFrameReady += sensor_DepthFrameReady;
this.sensor.Start();
}
}
private void Window_Unloaded(object sender, RoutedEventArgs e)
{
sensor.Stop();
}
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)
return;
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.DrawImage(source, new Rect(0.0, 0.0, RenderWidth, RenderHeight));
//還有資料傳入
if (skeletons.Length != 0)
{
foreach (Skeleton skel in skeletons.Where(skl => skl.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skel.TrackingState == SkeletonTrackingState.Tracked)
{
DrawBonesAndJoints(skel, dc);
LockUser(skel);
}
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));
}
}
}
private void sensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame frame = e.OpenDepthImageFrame())
{
short[] depthData = new short[frame.PixelDataLength];
frame.CopyPixelDataTo(depthData);
if (depthData == null || depthData.Length == 0)
return;
FindPalyer(ref depthData);
}
}
/// <summary>
/// Find Player ID
/// </summary>
/// <param name="depthData"></param>
private void FindPalyer(ref short[] depthData)
{
foreach (short data in depthData)
{
//ID
int id = (data & DepthImageFrame.PlayerIndexBitmask) - 1;
if (id > 0)
{
Console.WriteLine("遊戲者ID:" + id);
}
}
}
private void LockUser(Skeleton skeleton)
{
if (skeleton.Joints[JointType.Head].Position.Y < skeleton.Joints[JointType.HandRight].Position.Y)
{
if (trackID == -1)
{
trackID = skeleton.TrackingId;
if (this.sensor.SkeletonStream.AppChoosesSkeletons == false)
{
this.sensor.SkeletonStream.AppChoosesSkeletons = true;
}
this.sensor.SkeletonStream.ChooseSkeletons(trackID);
Console.WriteLine("鎖定中, ID:" + trackID);
}
else
{
trackID = -1;
if (this.sensor.SkeletonStream.AppChoosesSkeletons == true)
{
this.sensor.SkeletonStream.AppChoosesSkeletons = false;
}
Console.WriteLine("解鎖");
}
Thread.Sleep(700);
}
}
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);
}
}
}
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://msdn.microsoft.com/en-us/library/jj131025.aspx