因為自己之前在摸索kinect,下麵是參考官網已經別人寫的一些代碼,自己也模仿寫了一個深度圖像和彩色圖像疊加的代碼,代碼裡面有自己在做簡單的靜態手勢時候的一些代碼,部分我自己註釋掉了,大家註意如果不需要的話可以直接省略的。 註意的是,我用的是kinect v2和vs2013執行環境,腳本語言使用的是 ...
因為自己之前在摸索kinect,下麵是參考官網已經別人寫的一些代碼,自己也模仿寫了一個深度圖像和彩色圖像疊加的代碼,代碼裡面有自己在做簡單的靜態手勢時候的一些代碼,部分我自己註釋掉了,大家註意如果不需要的話可以直接省略的。
註意的是,我用的是kinect v2和vs2013執行環境,腳本語言使用的是c#+WPF。
註:直接就上代碼,以後有時間把kinect的安裝配置再詳細寫個文檔吧!!
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 System.IO;
using Microsoft.Kinect;//添加對Kinect對象的引用
namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
//定義相關變數
#region
private KinectSensor kinectSensor = null;
private MultiSourceFrameReader multiFrameSourceReader = null;//多源閱讀器
private WriteableBitmap Bitmap = null;
private WriteableBitmap colorBitmap = null;
private CoordinateMapper coordinateMapper = null;//坐標映射器
private const float InferredZPositionClamp = 0.1f;
//private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));
private readonly Brush trackedJointBrush = Brushes.Red;
private readonly Brush inferredJointBrush = Brushes.Blue;
private DrawingGroup drawingGroup;//DrawingGroup表示可以作為單個繪圖進行運算的繪圖集合
private DrawingImage imageSource;
private Body[] bodies = null;
private int displayWidth;
private int displayHeight;
private List<Tuple<JointType, JointType>> bones;
private List<Pen> bodyColors;
public bool Savejudge;
private Pose[] poseLibrary;//自定義手勢庫對象
ImageBrush imgBrush = new ImageBrush();
#endregion
public MainWindow()
{
this.kinectSensor = KinectSensor.GetDefault();
this.multiFrameSourceReader = this.kinectSensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Body | FrameSourceTypes.Depth);
this.multiFrameSourceReader.MultiSourceFrameArrived += this.Reader_MultiSourceFrameArrived;
this.coordinateMapper = this.kinectSensor.CoordinateMapper;
FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.FrameDescription;
this.Bitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
//color
this.displayWidth = colorFrameDescription.Width;
this.displayHeight = colorFrameDescription.Height;
//關節之間的線定義為Bone
this.bones = new List<Tuple<JointType, JointType>>();
//Torso(軀幹)
this.bones.Add(new Tuple<JointType, JointType>(JointType.Head, JointType.Neck));
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));
// Right Arm
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderRight, JointType.ElbowRight));
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));
// Left Arm
this.bones.Add(new Tuple<JointType, JointType>(JointType.ShoulderLeft, JointType.ElbowLeft));
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));
// Right Leg
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipRight, JointType.KneeRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeRight, JointType.AnkleRight));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleRight, JointType.FootRight));
// Left Leg
this.bones.Add(new Tuple<JointType, JointType>(JointType.HipLeft, JointType.KneeLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.KneeLeft, JointType.AnkleLeft));
this.bones.Add(new Tuple<JointType, JointType>(JointType.AnkleLeft, JointType.FootLeft));
//body
//每個BodyIndex一個填充顏色,
this.bodyColors = new List<Pen>();
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.kinectSensor.Open();
this.drawingGroup = new DrawingGroup();
this.imageSource = new DrawingImage(this.drawingGroup);
this.Bitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
this.DataContext = this;
this.Savejudge = false;
InitializeComponent();
PopulatePoseLibrary();
}
public struct Pose//名為Pose的結構
{//Pose存儲了一個姿勢的名稱和一個PoseAngle數組
public string Title;
public PoseAngle[] Angles;
}
public class PoseAngle//創建一個新的PoseAngle類
{
public PoseAngle(JointType startJoint, JointType angleJoint, JointType endJoint, double angle, double threshold)
{//有兩個JointType類型的成員變數用來計算角度,Angle為期望角度,Threshold 閾值
StartJoint = startJoint;
AngleJoint = angleJoint;
EndJoint = endJoint;
Angle = angle;
Threshold = threshold;
}
public JointType StartJoint { get; private set; }
public JointType AngleJoint { get; private set; }
public JointType EndJoint { get; private set; }
public double Angle { get; private set; }
public double Threshold { get; private set; }
}
private void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
{
DepthFrame depthFrame = null;
ColorFrame colorFrame = null;
BodyFrame bodyFrame = null;
//bool isBitmapLocked = false;
MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();
if (multiSourceFrame == null)
{
return;
}
try
{
depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame();
colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame();
bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame();
//Process Body
bool dataReceived = false;
if ((depthFrame == null) || (colorFrame == null) || (bodyFrame == null))
{
return;
}
if (this.bodies == null)
{
this.bodies = new Body[bodyFrame.BodyCount];//BodyFrame中的人體總數
}
bodyFrame.GetAndRefreshBodyData(this.bodies);//數據帶入
dataReceived = true;
if (this.Savejudge)
{
SaveAllJoints(this.bodies);
this.Savejudge = false;
}
if (dataReceived)
{
using (DrawingContext dc = this.drawingGroup.Open())
{
// 畫一個透明背景設置渲染的大小(繪製矩形,透明背景)
dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), 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)
{
IReadOnlyDictionary<JointType, Joint> joints = body.Joints;
Dictionary<JointType, Point> jointPoints = new Dictionary<JointType, Point>();
foreach (JointType jointType in joints.Keys)
{
CameraSpacePoint position = joints[jointType].Position;
//這個防止是照抄的相機轉深度,不知是否奏效或應該
if (position.Z < 0)
{
position.Z = 0.1f;
}
//相機點映射到彩色空間點
ColorSpacePoint colorSpacePoint = this.coordinateMapper.MapCameraPointToColorSpace(position);
jointPoints[jointType] = new Point(colorSpacePoint.X, colorSpacePoint.Y);//映射完的坐標替換舊坐標
}
this.DrawBody(joints, jointPoints, dc, drawPen);
double angle1 = GetJointAngle1(body.Joints[JointType.ShoulderRight], body.Joints[JointType.ElbowRight], body.Joints[JointType.WristRight]);
this.ProcessPosePerforming(body);
}
}
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, this.displayWidth, this.displayHeight));
}
}
// Process Color
FrameDescription colorFrameDescription = colorFrame.FrameDescription;
using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
{
this.colorBitmap.Lock();
if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.Height))
{
colorFrame.CopyConvertedFrameDataToIntPtr(
this.colorBitmap.BackBuffer,
(uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
ColorImageFormat.Bgra);//數據拷至點陣圖
this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));//更改製定點陣圖數據
}
this.colorBitmap.Unlock();
}
}
finally
{
//if (isBitmapLocked) this.bitmap.Unlock();
if (depthFrame != null) depthFrame.Dispose();
if (colorFrame != null) colorFrame.Dispose();
if (bodyFrame != null) bodyFrame.Dispose();
}
}
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],15.0, 15.0);
}
}
}
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 (joint0.TrackingState == TrackingState.NotTracked ||
joint1.TrackingState == TrackingState.NotTracked)
{
return;
}
// 除非關節已跟蹤,我們假定所有骨頭都推斷,畫筆為推斷預設色
Pen drawPen = new Pen(Brushes.Yellow, 18);
if ((joint0.TrackingState == TrackingState.Tracked) && (joint1.TrackingState == TrackingState.Tracked))
{
drawPen = drawingPen;//筆換色
}
drawingContext.DrawLine(drawPen, jointPoints[jointType0], jointPoints[jointType1]);
}
//計算三個關節所成角度的方法
private double GetJointAngle1(Joint startJoint, Joint angleJoint, Joint endJoint)
{
Console.WriteLine("開始計算角度");
Point startPoint = GetJointPointScreen(startJoint);//通過GetJointPoint方法將坐標轉換到UI界面上計算角度,方便我們進行測試
Point anglePoint = GetJointPointScreen(angleJoint);
Point endPoint = GetJointPointScreen(endJoint);
//double a;
//double b;
//double c;
double aa;
double bb;
double cc;
//三維空間計算關節角度
aa = Math.Sqrt(Math.Pow(startJoint.Position.X - angleJoint.Position.X, 2) + Math.Pow(startJoint.Position.Y - angleJoint.Position.Y, 2)+Math.Pow(startJoint.Position.Z- angleJoint.Position.Z, 2));
Console.WriteLine("aa={0}", aa);
bb = Math.Sqrt(Math.Pow(endJoint.Position.X - angleJoint.Position.X, 2) + Math.Pow(endJoint.Position.Y - angleJoint.Position.Y, 2) + Math.Pow(endJoint.Position.Z - angleJoint.Position.Z, 2));
Console.WriteLine("bb={0}", bb);
cc = Math.Sqrt(Math.Pow(startJoint.Position.X - endJoint.Position.X, 2) + Math.Pow(startJoint.Position.Y - endJoint.Position.Y, 2) + Math.Pow(startJoint.Position.Z - endJoint.Position.Z, 2));
Console.WriteLine("cc={0}", cc);
double angleRadtest = Math.Acos((aa * aa + bb * bb - cc * cc) / (2 * aa * bb));//它的返回結果是弧度,下一步需要轉換為度數
double angleDegtest = angleRadtest * 180 / Math.PI;
Console.WriteLine("angleDegtest={0}", angleDegtest);
return angleDegtest;
//UI平面計算關節角度
//a = Math.Sqrt(Math.Pow(startPoint.X - anglePoint.X, 2) + Math.Pow(startPoint.Y - anglePoint.Y, 2));
//Console.WriteLine("a={0}", a);
//b = Math.Sqrt(Math.Pow(anglePoint.X - endPoint.X, 2) + Math.Pow(anglePoint.Y - endPoint.Y, 2));
//Console.WriteLine("b={0}", b);
//c = Math.Sqrt(Math.Pow(startPoint.X - endPoint.X, 2) + Math.Pow(startPoint.Y - endPoint.Y, 2));
//Console.WriteLine("c={0}", c);
//double angleRad = Math.Acos((a * a + b * b - c * c) / (2 * a * b));//它的返回結果是弧度,下一步需要轉換為度數
//double angleDeg = angleRad * 180 / Math.PI;
//if (primaryPoint.Y < anglePoint.Y)//If語句處理角度值在180-360的情況
//{
// angleDeg = 360 - angleDeg;//餘弦定理返回的角度在0-180度內,if語句將在第三和第四象限的值調整到第一第二象限中來。
//}
//Console.WriteLine("開始輸出角度值");
//Console.WriteLine("角度是:{0}", angleRad);
//return angleDeg;
}
//計算三個關節角度面與XOZ面所成角度
private double GetJointAngle2(Joint startJoint, Joint angleJoint, Joint endJoint)
{
double x1 = startJoint.Position.X - angleJoint.Position.X;
double y1 = startJoint.Position.Y - angleJoint.Position.Y;
double z1 = startJoint.Position.Z - angleJoint.Position.Z;
double x2 = endJoint.Position.X - angleJoint.Position.X;
double y2 = endJoint.Position.Y - angleJoint.Position.Y;
double z2 = endJoint.Position.Z - angleJoint.Position.Z;
//肩膀肘關節和手腕所成面的法向量
double nx1 = (y1 * z2 - z1 * y2) * 1000;
double ny1 = (z1 * x2 - x1 * z2) * 1000;
double nz1 = (x1 * y2 - x2 * y1) * 1000;
Console.WriteLine("nx1={0}", nx1);
Console.WriteLine("ny1={0}", ny1);
Console.WriteLine("nz1={0}", nz1);
//取一個XOZ平面所成的法向量
double nx2 = 0;
double ny2 = -100;
double nz2 = 0;
double twoPlaneAngle = Math.Acos((nx1 * nx2 + ny1 * ny2 + nz1 * nz2) / ((Math.Sqrt(nx1 * nx1 + ny1 * ny1 + nz1 * nz1)) * (Math.Sqrt(nx2 * nx2 + ny2 * ny2 + nz2 * nz2))));
Console.WriteLine("twoPlaneAngle={0}", twoPlaneAngle);
double PlaneAngle = twoPlaneAngle * 180 / Math.PI;
Console.WriteLine("肩膀肘關節和手腕所成面與XOZ所成角為:{0}", PlaneAngle);
return PlaneAngle;
}
//自定義姿勢庫
private void PopulatePoseLibrary()
{
this.poseLibrary = new Pose[7];
//第一個姿勢
this.poseLibrary[0] = new Pose();
this.poseLibrary[0].Title = "舉起雙手";
this.poseLibrary[0].Angles = new PoseAngle[4];
this.poseLibrary[0].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft,JointType.WristLeft, 90, 10);
this.poseLibrary[0].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 90, 10);
this.poseLibrary[0].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
this.poseLibrary[0].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
//第二個手勢
this.poseLibrary[1] = new Pose();
this.poseLibrary[1].Title = "雙手放在胸前";
this.poseLibrary[1].Angles = new PoseAngle[4];
this.poseLibrary[1].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft,45,10);
this.poseLibrary[1].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[1].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 45, 10);
this.poseLibrary[1].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight,180, 10);
//第三個手勢
this.poseLibrary[2] = new Pose();
this.poseLibrary[2].Title = "雙手伸直放在前面";
this.poseLibrary[2].Angles = new PoseAngle[4];
this.poseLibrary[2].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[2].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 0, 10);
this.poseLibrary[2].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 180, 10);
this.poseLibrary[2].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 0, 10);
//第四個手勢
this.poseLibrary[3] = new Pose();
this.poseLibrary[3].Title = "右手舉起";
this.poseLibrary[3].Angles = new PoseAngle[4];
this.poseLibrary[3].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[3].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[3].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
this.poseLibrary[3].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
//第五個手勢
this.poseLibrary[4] = new Pose();
this.poseLibrary[4].Title = "右手抬起,左手與身成角";
this.poseLibrary[4].Angles = new PoseAngle[4];
this.poseLibrary[4].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[4].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 135, 10);
this.poseLibrary[4].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
this.poseLibrary[4].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
//第六個手勢
this.poseLibrary[5] = new Pose();
this.poseLibrary[5].Title = "雙手叉腰";
this.poseLibrary[5].Angles = new PoseAngle[4];
this.poseLibrary[5].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 110, 10);
this.poseLibrary[5].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 90, 10);
this.poseLibrary[5].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight,110, 10);
this.poseLibrary[5].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 90, 10);
//第七個手勢
this.poseLibrary[6] = new Pose();
this.poseLibrary[6].Title = "兩手與身成角";
this.poseLibrary[6].Angles = new PoseAngle[4];
this.poseLibrary[6].Angles[0] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 180, 10);
this.poseLibrary[6].Angles[1] = new PoseAngle(JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, 145, 10);
this.poseLibrary[6].Angles[2] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 180, 10);
this.poseLibrary[6].Angles[3] = new PoseAngle(JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, 145, 10);
}
private bool IsPose1(Body body,Pose pose)//判斷是否和指定的姿勢的匹配
{
bool isPose = true;
double angle1;
double poseAngle;
double poseThreshold;
double highAngle;
double lowAngle;
for(int i=0;i<pose.Angles.Length&&isPose;i=i+2)
{
poseAngle = pose.Angles[i].Angle;
poseThreshold = pose.Angles[i].Threshold;
angle1 = GetJointAngle1(body.Joints[pose.Angles[i].StartJoint], body.Joints[pose.Angles[i].AngleJoint], body.Joints[pose.Angles[i].EndJoint]);
//關節角度的一個閾值範圍
highAngle = poseAngle + poseThreshold;
lowAngle = poseAngle - poseThreshold;
//if語句用來判斷角度是否在360度範圍內,如果不在,則轉換到該範圍內。
if ( highAngle >= 180 || lowAngle < 0)
{
lowAngle = (lowAngle < 0) ? 360 + lowAngle : lowAngle;
highAngle = highAngle % 360;
isPose = !(lowAngle > angle1 && angle1 > highAngle);
}
else
{
isPose = (lowAngle <= angle1 && highAngle >= angle1);
}
}
return isPose;
}
private bool IsPose2(Body body,Pose pose)
{
bool isPose = true;
double angle2;
double poseAngle;
double poseThreshold;
double highAngle;
double lowAngle;
for (int i = 1; i < pose.Angles.Length && isPose; i = i + 2)
{
poseAngle = pose.Angles[i].Angle;
poseThreshold = pose.Angles[i].Threshold;
angle2 = GetJointAngle2(body.Joints[pose.Angles[i].StartJoint], body.Joints[pose.Angles[i].AngleJoint], body.Joints[pose.Angles[i].EndJoint]);
//關節角度的一個閾值範圍
highAngle = poseAngle + poseThreshold;
lowAngle = poseAngle - poseThreshold;
//if語句用來判斷角度是否在360度範圍內,如果不在,則轉換到該範圍內。
if (highAngle >= 180 || lowAngle < 0)
{
lowAngle = (lowAngle < 0) ? 360 + lowAngle : lowAngle;
highAngle = highAngle % 360;
isPose = !(lowAngle > angle2 && angle2> highAngle);
}
else
{
isPose = (lowAngle <= angle2 && highAngle >= angle2);
}
}
return isPose;
}
private void ProcessPosePerforming(Body body)//處理訓練者的姿勢
{
if (IsPose1(body, this.poseLibrary[0]) && IsPose2(body, this.poseLibrary[0]))
{
Console.WriteLine("左手舉起匹配");
textBox1.Text = "姿勢一匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\1.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[1]) && IsPose2(body, this.poseLibrary[1]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢二匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\2.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[2]) && IsPose2(body, this.poseLibrary[2]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢三匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\3.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[3]) && IsPose2(body, this.poseLibrary[3]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢四匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\4.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[4]) && IsPose2(body, this.poseLibrary[4]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢五匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\5.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[5]) && IsPose2(body, this.poseLibrary[5]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢六匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\6.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else if (IsPose1(body, this.poseLibrary[6]) && IsPose2(body, this.poseLibrary[6]))
{
Console.WriteLine("左手放在胸前");
textBox1.Text = "姿勢七匹配";
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\7.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
else
{
textBox1.Text = null;
imgBrush.ImageSource = new BitmapImage(new Uri(@"F:\kinetc2資料\骨骼和彩色疊加\WpfApplication1\WpfApplication1\Image\test.png", UriKind.Relative));
ellipseWithImageBrush.Fill = imgBrush;
}
}
//獲得關節點在屏幕上的坐標
private Point GetJointPointScreen(Joint oneJoint)
{
//骨骼坐標轉化為深度圖像坐標
DepthSpacePoint depthPoint = this.kinectSensor.CoordinateMapper.MapCameraPointToDepthSpace(oneJoint.Position);
//深度圖像坐標轉化為屏幕坐標
depthPoint.X = (int)((depthPoint.X * imageCoordinate.Width) / 512);
depthPoint.Y = (int)((depthPoint.Y * imageCoordinate.Height) / 424);
//返回Point類型變數
return new Point(depthPoint.X, depthPoint.Y);
}
public ImageSource BodyImageSource
{
get
{
return this.imageSource;
}
}
public ImageSource ColorImageSource
{
get
{
return this.colorBitmap;
}
}
private void Window_Closed(object sender, EventArgs e)
{
if (this.multiFrameSourceReader != null)
{
this.multiFrameSourceReader.Dispose();
this.multiFrameSourceReader = null;
}
if (this.kinectSensor != null)
{
this.kinectSensor.Close();
this.kinectSensor = null;
}
}
public void SaveAllJoints(Body[] bodies)
{
FileStream fs = new FileStream("F:\\SaveAllJoints.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
foreach (Body x in bodies)
{
for (int i = 0; i < 25; i++)
{
// The position of the joint in camera space.攝像機坐標系下的坐標
sw.WriteLine("{0}[{1},{2},{3}]", (JointType)i, x.Joints[(JointType)i].Position.X, x.Joints[(JointType)i].Position.Y, x.Joints[(JointType)i].Position.Z);
}
sw.Write("\r\n");
}
sw.Flush();
sw.Close();
fs.Close();
}
private void SaveAll_Click(object sender, RoutedEventArgs e)
{
this.Savejudge = true;
}
}
}