资料
硬件部分连接上即可,SDK从微软官网下载,for windows 2.0 ,安装完毕后一定要重启
运行SDK Browser v2.0 (Kinect for Windows) 检查设备
运行Kinect Studio v2.0演示效果和 查看文档。
c#文档
vs2015中建立WPF APPLICATION 注意x:Class="xxxx.yyyyy"
xxxx = namespace名称 ,yyyyy = class名称
注意添加kinect presentioncore
资料
WPF中窗口添加对应事件
多源使用时 要用multsource
打开 kinectsensor 建立reader 建立description framearrived += 订阅事件
WPF中 <Image x:Name="image1" Height="731" Width="170" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Visible" RenderTransformOrigin="0.494,0.472" Margin="10,10,0,0"/>
修改Name 的名称,对应修改 image1.Source 即可添加第二个image
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using System.ComponentModel;
using System.Diagnostics;
namespace 同时显示
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//体感器设备
private KinectSensor sensor = null;
//彩色帧读取变量
private MultiSourceFrameReader reader;
/// <summary>///////////////////////////
/// 彩色变量定义///////////////////////////
/// </summary>////////////////////////////////
//彩色帧描述
private FrameDescription colorFrameDescription = null;
//位图对象
private WriteableBitmap colorBitmap;
//存放一帧彩色图像的矩形框
private Int32Rect colorBitmapRect;
//步长,一维彩色像素数组转化为矩形框的步长。
private int colorBitmapStride;
//存放一帧彩色图像像素
private Byte[] colorPixelData;
/// <summary>///////////////////////////////
/// ///深度变量定义///////////////////////////
/// </summary>//////////////////////////////
private FrameDescription depthFrameDescription = null;
private WriteableBitmap depthBitmap;
//存放一帧深度图像的矩形框
private Int32Rect depthBitmapRect;
//深度像素数组转化为矩形框的长度
private int depthStride;
//深度图像像素数据
private ushort[] depthPixelData;
/// <summary>//////////////////////////////////////////////////
/// ///骨骼变量定义////////////////////////////////////////////
/// </summary>////////////////////////////////////////////////
private FrameDescription bodyFrameDescription = null;
private const double HandSize = 30; //手部圆圈大小
/// <summary>
/// Thickness of drawn joint lines
/// </summary>
private const double JointThickness = 3;//关节点圆圈大小
/// <summary>
/// Thickness of clip edge rectangles
/// </summary>
private const double ClipBoundsThickness = 20;//视野边界 警告区域
/// <summary>
/// Constant for clamping Z values of camera space points from being negative
/// </summary>
private const float InferredZPositionClamp = 0.1f;
/// <summary>
/// Brush used for drawing hands that are currently tracked as closed
/// </summary>
private readonly Brush handClosedBrush = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));//手掌闭合 颜色显示
/// <summary>
/// Brush used for drawing hands that are currently tracked as opened
/// </summary>
private readonly Brush handOpenBrush = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0));//手掌打开 颜色显示
/// <summary>
/// Brush used for drawing hands that are currently tracked as in lasso (pointer) position
/// </summary>
private readonly Brush handLassoBrush = new SolidColorBrush(Color.FromArgb(128, 0, 0, 255)); //不懂!!!!
/// <summary>
/// Brush used for drawing joints that are currently tracked
/// </summary>
private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));//关节点 颜色
/// <summary>
/// Brush used for drawing joints that are currently inferred
/// </summary>
private readonly Brush inferredJointBrush = Brushes.Yellow;
/// <summary>
/// Pen used for drawing bones that are currently inferred
/// </summary>
private readonly Pen inferredBonePen = new Pen(Brushes.Gray, 1);
/// <summary>
/// Drawing group for body rendering output
/// </summary>
private DrawingGroup drawingGroup;
/// <summary>
/// Drawing image that we will display
/// </summary>
private DrawingImage imageSource;
/// <summary>
/// Coordinate mapper to map one type of point to another
/// </summary>
private CoordinateMapper coordinateMapper = null;
/// <summary>
/// Reader for body frames
/// </summary>
private BodyFrameReader bodyFrameReader = null;
/// <summary>
/// Array for the bodies
/// </summary>
private Body[] bodies = null;
/// <summary>
/// definition of bones
/// </summary>
private List<Tuple<JointType, JointType>> bones;
/// <summary>
/// Width of display (depth space)
/// </summary>
private int displayWidth;
/// <summary>
/// Height of display (depth space)
/// </summary>
private int displayHeight;
/// <summary>
/// List of colors for each body tracked
/// </summary>
private List<Pen> bodyColors;
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
this.sensor = KinectSensor.GetDefault();
this.coordinateMapper = this.sensor.CoordinateMapper;
this.reader = this.sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Depth | FrameSourceTypes.Color | FrameSourceTypes.Body);
this.depthFrameDescription = this.sensor.DepthFrameSource.FrameDescription;
this.colorFrameDescription = this.sensor.ColorFrameSource.FrameDescription;
this.bodyFrameDescription = this.sensor.DepthFrameSource.FrameDescription;
this.reader.MultiSourceFrameArrived += this.Reader_MultiSourceFrameArrived;
this.displayWidth = this.bodyFrameDescription.Width;
this.displayHeight = this.bodyFrameDescription.Height;
///////////////////// 彩色 /////////////////////////////////////
this.colorPixelData = new Byte[colorFrameDescription.LengthInPixels * 4];
this.colorBitmap = new WriteableBitmap(this.colorFrameDescription.Width,
this.colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgra32, null);
this.colorBitmapRect = new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight);
this.colorBitmapStride = this.colorFrameDescription.Width * 4;
image1.Source = this.colorBitmap;
///////////////////// 深度 /////////////////////////////////////
this.depthPixelData = new ushort[this.depthFrameDescription.LengthInPixels];
this.depthBitmap = new WriteableBitmap(this.depthFrameDescription.Width, this.depthFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray16, null);
this.depthBitmapRect = new Int32Rect(0, 0, this.depthBitmap.PixelWidth, this.depthBitmap.PixelHeight);
this.depthStride = this.depthFrameDescription.Width * 2;
image2.Source = this.depthBitmap;
///////////////////// 骨骼 /////////////////////////////////////
this.bones = new List<Tuple<JointType, JointType>>(); //关节点之间画线
this.bones.Add(new Tuple<JointType, JointType>(JointType.Head, JointType.Neck)); // Torso
this.bones.Add(new Tuple<JointType, JointType>(JointType.Neck, JointType.SpineShoulder));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineShoulder, JointType.SpineMid));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineMid, JointType.SpineBase));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineShoulder, JointType.ShoulderRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineShoulder, JointType.ShoulderLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineBase, JointType.HipRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.SpineBase, JointType.HipLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderRight, JointType.ElbowRight)); // Right Arm
this.bones.Add(new Tuple<JointType, JointType>(JointType.ElbowRight, JointType.WristRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristRight, JointType.HandRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HandRight, JointType.HandTipRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristRight, JointType.ThumbRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderLeft, JointType.ElbowLeft)); // Left Arm
this.bones.Add(new Tuple<JointType, JointType>(JointType.ElbowLeft, JointType.WristLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristLeft, JointType.HandLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HandLeft, JointType.HandTipLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.WristLeft, JointType.ThumbLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipRight, JointType.KneeRight)); // Right Leg
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeRight, JointType.AnkleRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleRight, JointType.FootRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipLeft, JointType.KneeLeft)); // Left Leg
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeLeft, JointType.AnkleLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleLeft, JointType.FootLeft));
this.bodyColors = new List<Pen>(); // populate body colors, one for each BodyIndex
this.bodyColors.Add(new Pen(Brushes.Red, 6));
this.bodyColors.Add(new Pen(Brushes.Orange, 6));
this.bodyColors.Add(new Pen(Brushes.Green, 6));
this.bodyColors.Add(new Pen(Brushes.Blue, 6));
this.bodyColors.Add(new Pen(Brushes.Indigo, 6));
this.bodyColors.Add(new Pen(Brushes.Violet, 6));
this.drawingGroup = new DrawingGroup();
image3.Source = new DrawingImage(this.drawingGroup);
this.sensor.Open();
}
public ImageSource ImageSource
{
get //可删除
{
return this.imageSource;
}
}
private void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
//////////////////////////////////////骨骼事件处理
bool dataReceived = false;
MultiSourceFrameReference frameReference = e.FrameReference;
MultiSourceFrame multiSourceFrame = null;
multiSourceFrame = frameReference.AcquireFrame();
using (BodyFrame bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame())///这里是关键
{
if (bodyFrame != null)
{
if (this.bodies == null)
{
this.bodies = new Body[bodyFrame.BodyCount];
}
// The first time GetAndRefreshBodyData is called, Kinect will allocate each Body in the array.
// As long as those body objects are not disposed and not set to null in the array,
// those body objects will be re-used.
bodyFrame.GetAndRefreshBodyData(this.bodies);
dataReceived = true;
}
}
if (dataReceived)
{
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, this.displayWidth, this.displayHeight));
int penIndex = 0;
foreach (Body body in this.bodies)
{
Pen drawPen = this.bodyColors[penIndex++];
if (body.IsTracked)
{
this.DrawClippedEdges(body, dc);
IReadOnlyDictionary<JointType, Joint> joints = body.Joints;
// convert the joint points to depth (display) space
Dictionary<JointType, Point> jointPoints = new Dictionary<JointType, Point>();
foreach (JointType jointType in joints.Keys)
{
// sometimes the depth(Z) of an inferred joint may show as negative
// clamp down to 0.1f to prevent coordinatemapper from returning (-Infinity, -Infinity)
CameraSpacePoint position = joints[jointType].Position;
if (position.Z < 0)
{
position.Z = InferredZPositionClamp;
}
DepthSpacePoint depthSpacePoint = this.coordinateMapper.MapCameraPointToDepthSpace(position);
jointPoints[jointType] = new Point(depthSpacePoint.X, depthSpacePoint.Y);
}
this.DrawBody(joints, jointPoints, dc, drawPen);
this.DrawHand(body.HandLeftState, jointPoints[JointType.HandLeft], dc);
this.DrawHand(body.HandRightState, jointPoints[JointType.HandRight], dc);
}
}
// prevent drawing outside of our render area
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, this.displayWidth, this.displayHeight));
}
//////////////////////////////彩色 深度事件处理/////////////////////////
DepthFrame depthFrame = null;
ColorFrame colorFrame = null;
if (multiSourceFrame != null)
{
ColorFrameReference colorFrameReference = multiSourceFrame.ColorFrameReference;
DepthFrameReference depthFrameReference = multiSourceFrame.DepthFrameReference;
colorFrame = colorFrameReference.AcquireFrame();
depthFrame = depthFrameReference.AcquireFrame();
if ((depthFrame != null) && (colorFrame != null))
{
colorFrame.CopyConvertedFrameDataToArray(this.colorPixelData, ColorImageFormat.Bgra);
this.colorBitmap.WritePixels(this.colorBitmapRect, this.colorPixelData, this.colorBitmapStride, 0);
depthFrame.CopyFrameDataToArray(this.depthPixelData);
this.depthBitmap.WritePixels(this.depthBitmapRect, this.depthPixelData, this.depthStride, 0);
}
}
if (depthFrame != null)
{
depthFrame.Dispose();
depthFrame = null;
}
//个人理解为,清楚帧内存,不清楚的话只会显示第一帧就卡住了
if (colorFrame != null)
{
colorFrame.Dispose();
colorFrame = null;
}
//if (multiSourceFrame != null)
//{
// multiSourceFrame = null;
//}
}
}
/// <summary>
/// Draws a body
/// </summary>
/// <param name="joints">joints to draw</param>
/// <param name="jointPoints">translated positions of joints to draw</param>
/// <param name="drawingContext">drawing context to draw to</param>
/// <param name="drawingPen">specifies color to draw a specific body</param>
private void DrawBody(IReadOnlyDictionary<JointType, Joint> joints, IDictionary<JointType, Point> jointPoints, DrawingContext drawingContext, Pen drawingPen)
{
// Draw the bones
foreach (var bone in this.bones)
{
this.DrawBone(joints, jointPoints, bone.Item1, bone.Item2, drawingContext, drawingPen);
}
// Draw the joints
foreach (JointType jointType in joints.Keys)
{
Brush drawBrush = null;
TrackingState trackingState = joints[jointType].TrackingState;
if (trackingState == TrackingState.Tracked)
{
drawBrush = this.trackedJointBrush;
}
else if (trackingState == TrackingState.Inferred)
{
drawBrush = this.inferredJointBrush;
}
if (drawBrush != null)
{
drawingContext.DrawEllipse(drawBrush, null, jointPoints[jointType], JointThickness, JointThickness);
}
}
}
/// <summary>
/// Draws one bone of a body (joint to joint)
/// </summary>
/// <param name="joints">joints to draw</param>
/// <param name="jointPoints">translated positions of joints to draw</param>
/// <param name="jointType0">first joint of bone to draw</param>
/// <param name="jointType1">second joint of bone to draw</param>
/// <param name="drawingContext">drawing context to draw to</param>
/// /// <param name="drawingPen">specifies color to draw a specific bone</param>
private void DrawBone(IReadOnlyDictionary<JointType, Joint> joints, IDictionary<JointType, Point> jointPoints, JointType jointType0, JointType jointType1, DrawingContext drawingContext, Pen drawingPen)
{
Joint joint0 = joints[jointType0];
Joint joint1 = joints[jointType1];
// If we can't find either of these joints, exit
if (joint0.TrackingState == TrackingState.NotTracked ||
joint1.TrackingState == TrackingState.NotTracked)
{
return;
}
// We assume all drawn bones are inferred unless BOTH joints are tracked
Pen drawPen = this.inferredBonePen;
if ((joint0.TrackingState == TrackingState.Tracked) && (joint1.TrackingState == TrackingState.Tracked))
{
drawPen = drawingPen;
}
drawingContext.DrawLine(drawPen, jointPoints[jointType0], jointPoints[jointType1]);
}
/// <summary>
/// Draws a hand symbol if the hand is tracked: red circle = closed, green circle = opened; blue circle = lasso
/// </summary>
/// <param name="handState">state of the hand</param>
/// <param name="handPosition">position of the hand</param>
/// <param name="drawingContext">drawing context to draw to</param>
private void DrawHand(HandState handState, Point handPosition, DrawingContext drawingContext)
{
switch (handState)
{
case HandState.Closed:
drawingContext.DrawEllipse(this.handClosedBrush, null, handPosition, HandSize, HandSize);
break;
case HandState.Open:
drawingContext.DrawEllipse(this.handOpenBrush, null, handPosition, HandSize, HandSize);
break;
case HandState.Lasso:
drawingContext.DrawEllipse(this.handLassoBrush, null, handPosition, HandSize, HandSize);
break;
}
}
/// <summary>
/// Draws indicators to show which edges are clipping body data
/// </summary>
/// <param name="body">body to draw clipping information for</param>
/// <param name="drawingContext">drawing context to draw to</param>
private void DrawClippedEdges(Body body, DrawingContext drawingContext)
{
FrameEdges clippedEdges = body.ClippedEdges;
if (clippedEdges.HasFlag(FrameEdges.Bottom))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, this.displayHeight - ClipBoundsThickness, this.displayWidth, ClipBoundsThickness));
}
if (clippedEdges.HasFlag(FrameEdges.Top))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, 0, this.displayWidth, ClipBoundsThickness));
}
if (clippedEdges.HasFlag(FrameEdges.Left))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(0, 0, ClipBoundsThickness, this.displayHeight));
}
if (clippedEdges.HasFlag(FrameEdges.Right))
{
drawingContext.DrawRectangle(
Brushes.Red,
null,
new Rect(this.displayWidth - ClipBoundsThickness, 0, ClipBoundsThickness, this.displayHeight));
}
}
}
}