Kinect 1.8 体感开发,手势,姿态(Pose) 捕捉判断方法以及一些辅方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Kinect;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Timers; namespace DEV
{
public class KinectHelper
{
#region 成员
//体感设备
private KinectSensor kinectDriver;
//骨架数据
private Skeleton[] frameSkeletons;
//姿势库
private readonly Brush[] _SkeletonBrushes = new Brush[] { Brushes.Black, Brushes.Crimson, Brushes.Indigo, Brushes.DodgerBlue, Brushes.Purple, Brushes.Pink };
Window minWindow;
bool isOK = false;
bool isKinectControl = false;
double MoveX;
double MoveY;
double Zoon;
Vector4 handLeft2;
Vector4 handRight2; Timer KinectTimer; #endregion 成员 #region 构造函数
public KinectHelper(KinectSensor kin, Window win)
{
try
{
kinectDriver = kin; if (kinectDriver != null)
{
minWindow = win;
//设置平滑参数
TransformSmoothParameters smoothParameters = new TransformSmoothParameters();
// 设置处理骨骼数据帧时的平滑量,接受一个0-1的浮点值,值越大,平滑的越多。0表示不进行平滑。
smoothParameters.Smoothing = .5f;
// 接受一个从0-1的浮点型,值越小,修正越多
smoothParameters.Correction = .9f;
// 抖动半径,单位为m,如果关节点“抖动”超过了设置的这个半径,将会被纠正到这个半径之内
smoothParameters.JitterRadius = 0.05f;
// 用来和抖动半径一起来设置抖动半径的最大边界,任何超过这一半径的点都不会认为是抖动产生的,而被认定为是一个新的点。该属性为浮点型,单位为米
smoothParameters.MaxDeviationRadius = 0.1f;
kinectDriver.SkeletonStream.Enable(smoothParameters);
kinectDriver.SkeletonFrameReady += kinectDriver_SkeletonFrameReady;
frameSkeletons = new Skeleton[kinectDriver.SkeletonStream.FrameSkeletonArrayLength];
kinectDriver.Start();
}
KinectTimer = new Timer();
KinectTimer.Interval = ;
KinectTimer.Elapsed += KinectTimer_Elapsed; }
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message);
} } void KinectTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (isOK == false)
{
isOK = true;
}
else
{
isOK = false;
}
} /// <summary>
/// 体感设备捕捉到骨架事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void kinectDriver_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
try
{
using (SkeletonFrame fram = e.OpenSkeletonFrame())
{
if (fram == null) return;
(this.minWindow.FindName("mess") as TextBlock).Text = "骨架流开始了";
fram.CopySkeletonDataTo(frameSkeletons);
//获取第一位置骨架
Skeleton skeleton = GetPrimarySkeleton(frameSkeletons);
if (skeleton != null)
{ ProcessPosePerForming2(skeleton); } for (int i = ; i < frameSkeletons.Length; i++)
{
DrawSkeleton(this.frameSkeletons[i], this._SkeletonBrushes[i]);
}
}
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message);
}
}
#endregion #region 方法 /// <summary>
/// 获取第一位置骨架
/// </summary>
/// <param name="frameSkeletons">骨架流</param>
/// <returns></returns>
private Skeleton GetPrimarySkeleton(Skeleton[] frameSkeletons)
{
Skeleton ske = null;
try
{
for (int i = ; i < frameSkeletons.Length; i++)
{
if (frameSkeletons[i].TrackingState == SkeletonTrackingState.Tracked)
{
if (ske == null)
{
ske = frameSkeletons[i];
(this.minWindow.FindName("mess") as TextBlock).Text = "捕捉到骨架了";
}
else
{
if (ske.Position.Z > frameSkeletons[i].Position.Z)
{
ske = frameSkeletons[i];
}
}
}
}
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message);
}
(minWindow.FindName("mess") as TextBlock).Text = "捕捉到骨架";
return ske; }
/// <summary>
/// 空间坐标和界面二维坐标转换
/// </summary>
/// <param name="joint"><关节/param>
/// <param name="offset"></param>
/// <returns></returns>
public Point GetJointPoint(Joint joint, Point offset)
{
//得到节点在UI主界面上的空间位置
DepthImagePoint point = kinectDriver.CoordinateMapper.MapSkeletonPointToDepthPoint(joint.Position, kinectDriver.DepthStream.Format);
point.X = (int)(point.X - offset.X);
point.Y = (int)(point.Y - offset.Y);
return new Point(point.X, point.Y);
}
/// <summary>
/// 计算2骨骼之间的角度
/// </summary>
/// <param name="centerJoint">中心关节点</param>
/// <param name="angleJoint">角度关节点</param>
/// <returns></returns>
public double GetJointAngle(Joint centerJoint, Joint angleJoint)
{
double angel = ;
double a, b, c;
Point primaryPoint = GetJointPoint(centerJoint, new Point());
Point angelPoint = GetJointPoint(angleJoint, new Point());
Point pr = new Point(primaryPoint.X + angelPoint.X, primaryPoint.Y);
try
{
a = Math.Sqrt(Math.Pow(primaryPoint.X - angelPoint.X, ) + Math.Pow(primaryPoint.Y - angelPoint.Y, ));
b = primaryPoint.X;
c = Math.Sqrt(Math.Pow(angelPoint.X - pr.X, ) + Math.Pow(angelPoint.Y - pr.Y, ));
double angelRed = Math.Acos((a * a + b * b - c * c) / ( * a * b));
angel = angelRed * / Math.PI;
if (primaryPoint.Y < angelPoint.Y)
{
angel = - angelRed;
}
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message);
} return angel;
}
/// <summary>
/// 通过3个关节点计算角度
/// </summary>
/// <param name="leftJoint">边关节</param>
/// <param name="centerJoint">中心关节</param>
/// <param name="rightJoint">边关节</param>
/// <returns></returns>
public double GetJointAngle(Joint leftJoint, Joint centerJoint, Joint rightJoint)
{
double angel = ;
double a, b, c;
Point primaryPoint = GetJointPoint(leftJoint, new Point());
Point angelPoint = GetJointPoint(centerJoint, new Point());
Point pr = GetJointPoint(rightJoint, new Point());
try
{
a = Math.Sqrt(Math.Pow(primaryPoint.X - angelPoint.X, ) + Math.Pow(primaryPoint.Y - angelPoint.Y, ));
b = Math.Sqrt(Math.Pow(angelPoint.X - pr.X, ) + Math.Pow(angelPoint.Y - pr.Y, ));
c = Math.Sqrt(Math.Pow(pr.X - primaryPoint.X, ) + Math.Pow(pr.Y - primaryPoint.Y, ));
double angelRed = Math.Acos((a * a + b * b - c * c) / ( * a * b));
angel = angelRed * / Math.PI;
if (primaryPoint.Y > angelPoint.Y)
{
angel = - angelRed;
}
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message);
} return angel;
}
/// <summary>
/// 将捕捉到的人体的空间坐标(3维)点转换为计算机界面坐标(2维)
/// </summary>
/// <param name="joint">人体关节</param>
/// <returns></returns>
private Point GetJointPoint(Joint joint)
{
Grid layoutRoot = (minWindow.FindName("mian") as Grid);
DepthImagePoint point = this.kinectDriver.CoordinateMapper.MapSkeletonPointToDepthPoint(joint.Position, kinectDriver.DepthStream.Format);
point.X *= (int)layoutRoot.ActualWidth / kinectDriver.DepthStream.FrameWidth;
point.Y *= (int)layoutRoot.ActualHeight / kinectDriver.DepthStream.FrameHeight;
return new Point(point.X, point.Y);
}
/// <summary>
/// 获取关节的4维坐标
/// </summary>
/// <param name="joint">关节</param>
/// <returns></returns>
private Vector4 GetJointVector4(Joint joint)
{
Vector4 v4 = new Vector4();
Grid layoutRoot = (minWindow.FindName("mian") as Grid);
DepthImagePoint point = this.kinectDriver.CoordinateMapper.MapSkeletonPointToDepthPoint(joint.Position, kinectDriver.DepthStream.Format);
point.X *= (int)layoutRoot.ActualWidth / kinectDriver.DepthStream.FrameWidth;
point.Y *= (int)layoutRoot.ActualHeight / kinectDriver.DepthStream.FrameHeight;
v4.X = point.X;
v4.Y = point.Y;
v4.Z = joint.Position.Z;
return v4;
}
KinectHelp
Kinect 关节对应
姿势判断
/// <summary>
/// 根据人体各种姿态的生理数据判断姿态
/// 通过关节之间角度,关节之间的相关位置判断姿态
/// </summary>
/// <param name="sk">骨架数据</param>
private void ProcessPosePerForming2(Skeleton sk)
{
string mess = "";
//T型姿态
//double angelLeft = GetJointAngle(sk.Joints[JointType.ElbowLeft],sk.Joints[JointType.ShoulderLeft]);
//double angelRight = GetJointAngle(sk.Joints[JointType.ElbowRight],sk.Joints[JointType.ShoulderRight]);
#region 获取数据
double angelLeft = GetJointAngle(sk.Joints[JointType.ShoulderLeft], sk.Joints[JointType.ElbowLeft], sk.Joints[JointType.WristLeft]);
double angelRight = GetJointAngle(sk.Joints[JointType.ShoulderRight], sk.Joints[JointType.ElbowRight], sk.Joints[JointType.WristRight]); //胸关节空间位置
Vector4 shoulderCenter = GetJointVector4(sk.Joints[JointType.ShoulderCenter]);
Vector4 handLeft = GetJointVector4(sk.Joints[JointType.HandLeft]);
Vector4 handRight = GetJointVector4(sk.Joints[JointType.HandRight]);
Vector4 spine = GetJointVector4(sk.Joints[JointType.Spine]); double leftCentZ = Math.Round((shoulderCenter.Z - handLeft.Z), );
double rightCenterZ = Math.Round((shoulderCenter.Z - handRight.Z), ); double leftAndRightX = Math.Round(Math.Abs((handRight.X - handLeft.X)), );
double leftAndRightY = Math.Round(Math.Abs((handRight.Y - handLeft.Y)), ); #endregion #region 姿势判断
//T型姿势
if (leftAndRightX >= && leftAndRightY <= && isOK == false)
{
mess = "T型姿势";
KinectTimer.Start();
isKinectControl = true;
(minWindow.FindName("gridMainMenu") as Grid).Visibility = Visibility.Collapsed;
(minWindow.FindName("gridPose") as Grid).Visibility = Visibility.Visible;
(minWindow.FindName("gridTuch") as Grid).Visibility = Visibility.Collapsed;
if ((this.minWindow as MainMenu).mainWindow != null)
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
} }
else
//左手举起,右手放下
if (leftAndRightY > && handLeft.Y < handRight.Y && isOK)
{
mess = "左手举起,右手放下";
(minWindow.FindName("gridMainMenu") as Grid).Visibility = Visibility.Collapsed;
(minWindow.FindName("gridPose") as Grid).Visibility = Visibility.Collapsed;
(minWindow.FindName("gridTuch") as Grid).Visibility = Visibility.Visible;
}
else
//右手举起,左手放下
if (leftAndRightY > && handLeft.Y > handRight.Y && isOK)
{
mess = "右手举起,左手放下"; }
else
//双手交叉
if ((handRight.X - handLeft.X) < && handLeft.Y < && handRight.Y < && isOK) //handLeft.Y<spine.Y&&handRight.Y<spine.Y
{
mess = "双手交叉";
KinectTimer.Stop();
isKinectControl = false;
(minWindow.FindName("gridMainMenu") as Grid).Visibility = Visibility.Visible;
(minWindow.FindName("gridPose") as Grid).Visibility = Visibility.Collapsed;
(minWindow.FindName("gridTuch") as Grid).Visibility = Visibility.Collapsed;
if ((this.minWindow as MainMenu).mainWindow != null)
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,GUI_FUNC_225_鼠标左键按下");
} }
else
//双手高举
if ((angelRight >= && angelRight <= ) && (angelLeft >= && angelLeft <= ))
{
mess = "双手高举";
}
#endregion #region 测试用例
(minWindow.FindName("leftX") as TextBlock).Text = "左手X:" + handLeft.X;
(minWindow.FindName("leftY") as TextBlock).Text = "左手Y:" + handLeft.Y;
(minWindow.FindName("leftZ") as TextBlock).Text = "左手Z:" + handLeft.Z; (minWindow.FindName("rightX") as TextBlock).Text = "右手X:" + handRight.X;
(minWindow.FindName("rightY") as TextBlock).Text = "右手Y:" + handRight.Y;
(minWindow.FindName("rightZ") as TextBlock).Text = "右手Z:" + handRight.Z; (minWindow.FindName("centerX") as TextBlock).Text = "中心X:" + shoulderCenter.X;
(minWindow.FindName("centerY") as TextBlock).Text = "中心Y:" + shoulderCenter.Y;
(minWindow.FindName("centerZ") as TextBlock).Text = "中心Z:" + shoulderCenter.Z;
//(minWindow.FindName("leftAndCenter") as TextBlock).Text = "(脊椎Y-左手Y)=:(" + spine.Y + "-" + handLeft.Y + ")=" + Math.Round((spine.Y - handLeft.Y), 2);
//(minWindow.FindName("rightAndCenter") as TextBlock).Text = "(脊椎Y-右手Y)=:(" + spine.Y + "-" + handRight.Y + ")=" + Math.Round((spine.Y - handRight.Y), 2);
//(minWindow.FindName("leftAndCenter") as TextBlock).Text = "(中心Z-左手Z)=:(" + shoulderCenter.Z + "-" + handLeft.Z + ")=" + Math.Round((shoulderCenter.Z - handLeft.Z), 2);
//(minWindow.FindName("rightAndCenter") as TextBlock).Text = "(右手Z-中心Z)=:(" + shoulderCenter.Z + "-" + handRight.Z + ")=" + Math.Round((shoulderCenter.Z - handRight.Z), 2);
//(minWindow.FindName("rightAndRightX") as TextBlock).Text = "(左手X-右手X)=:(" + handRight.X + "-" + handLeft.X + ")=" + Math.Round((handRight.X - handLeft.X), 2);//Math.Round(Math.Abs((handRight.X - handLeft.X)), 2);
//(minWindow.FindName("rightAndLeftY") as TextBlock).Text = "(左手Y-右手Y)绝对值=:(" + handRight.Y + "-" + handLeft.Y + ")=" + Math.Round(Math.Abs((handRight.Y - handLeft.Y)), 2); //(minWindow.FindName("leftCenterY") as TextBlock).Text = "(中心Y-左手Y)绝对值=:(" + shoulderCenter.Y + "-" + handLeft.Y + ")=" + Math.Abs(Math.Round((shoulderCenter.Y - handLeft.Y), 2));
//(minWindow.FindName("rightCenterY") as TextBlock).Text = "(中心Y-右手Y)绝对值=:(" + shoulderCenter.Y + "-" + handLeft.Y + ")=" + Math.Abs(Math.Round((shoulderCenter.Y - handLeft.Y), 2)); (minWindow.FindName("els") as Ellipse).Width = Math.Abs((handRight.X - handLeft.X));
(minWindow.FindName("els") as Ellipse).Height = Math.Abs((handRight.Y - handLeft.Y));
(minWindow.FindName("mess") as TextBlock).Text = mess;
#endregion #region 判断姿势执行函数
string function = "";
bool isSheck = true;
if (handRight2 == null)
{ handRight2 = handRight; } #region 计算平滑度
double maxX;
double maxY;
(minWindow.FindName("rightAndCenter") as TextBlock).Text = "(右手X1-是右手X2)=:(" + handRight.X+ "-" + handRight2.X + ")=" + Math.Abs((handRight.X - handRight2.X));
(minWindow.FindName("rightAndLeftY") as TextBlock).Text = "(左手Y1-右手Y2)绝对值=:(" + handRight.Y + "-" + handRight2.Y + ")=" + Math.Abs((handRight.Y - handRight2.Y)); maxX = Math.Abs((handRight.X - handRight2.X));
maxY = Math.Abs((handRight.Y - handRight2.Y)); if (maxX > || maxY>)
{
isSheck = false;
(minWindow.FindName("leftCenterY") as TextBlock).Text = "滑动了";
}
else
{
(minWindow.FindName("leftCenterY") as TextBlock).Text = "抖动";
isSheck = true;
} #endregion //左手控制
if (isKinectControl && leftCentZ > 0.4 && rightCenterZ < 0.4)
{
double movX = MoveX - handLeft.X;
double movY = MoveY - handLeft.Y;
if ((this.minWindow as MainMenu).mainWindow != null)
{
if (movX < )//向右
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 3");
}
else if (movX > )//向左
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 4");
}
if (movY > )//向上
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 1"); }
else if (movY < )//向下
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 2");
}
} function = "右手控制地图移动X方向:" + handRight.X + "右手控制地图移动Y方向:" + handRight.Y;
MoveY = handLeft.Y;
MoveX = handLeft.X;
function = "左手控制地图移动X方向:" + handLeft.X + "左手控制地图移动Y方向:" + handLeft.Y;
}
//右手控制
if (isKinectControl && leftCentZ < 0.4 && rightCenterZ > 0.4 && !isSheck)
{
(minWindow.FindName("moveX") as TextBlock).Text = "手移动X" + MoveX + "-" + handRight.X + "=" + (MoveX - handRight.X).ToString();
(minWindow.FindName("moveY") as TextBlock).Text = "手移动Y" + MoveY + "-" + handRight.Y + "=" + (MoveY - handRight.Y).ToString();
double movX = MoveX - handRight.X;
double movY = MoveY - handRight.Y;
if ((this.minWindow as MainMenu).mainWindow != null)
{
if (movX < )//向右
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 3");
}
else if (movX > )//向左
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 4");
}
if (movY > )//向上
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 1"); }
else if (movY < )//向下
{
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("相机移动控制, 0, 2");
}
} function = "右手控制地图移动X方向:" + handRight.X + "右手控制地图移动Y方向:" + handRight.Y;
MoveY = handRight.Y;
MoveX = handRight.X;
}
if (isKinectControl && leftCentZ < && rightCenterZ < )
{
function = "地图复位";
}
//地图缩放
if (isKinectControl && leftCentZ < && rightCenterZ > )
{
function = "地图缩放右手控制:" + rightCenterZ;
}
if (isKinectControl && leftCentZ > && rightCenterZ < )
{
function = "地图缩放左手控制:" + rightCenterZ;
}
//双手X放大
if (isKinectControl && leftCentZ > && leftCentZ < 0.3 && rightCenterZ > && rightCenterZ < 0.3 && leftAndRightX > && !isSheck)
{
if ((this.minWindow as MainMenu).mainWindow != null)
{
if (MoveX - leftAndRightX > )//缩小
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 2";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2); }
if (MoveX - leftAndRightX < )//放大
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 1";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2);
}
} (minWindow.FindName("moveX") as TextBlock).Text = "双手放大X" + MoveX + "-" + leftAndRightX + "=" + (MoveX - leftAndRightX).ToString(); MoveX = leftAndRightX;
}
//双手Y放大
if (isKinectControl && leftCentZ > && leftCentZ < 0.3 && rightCenterZ > && rightCenterZ < 0.3 && leftAndRightY > && !isSheck)
{
function = "地图放大双手控制Y:" + leftAndRightX;
if ((this.minWindow as MainMenu).mainWindow != null)
{
if (MoveY - leftAndRightY > )// 缩小
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 2";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2);
}
if (MoveY - leftAndRightY < )//放大
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 1";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2);
}
}
(minWindow.FindName("moveY") as TextBlock).Text = "双手缩放Y" + MoveY + "-" + leftAndRightY + "=" + (MoveY - leftAndRightY).ToString();
MoveY = leftAndRightY;
}
//双手放大
if (isKinectControl && leftCentZ > 0.4 && rightCenterZ > 0.4 && leftAndRightY > && !isSheck)
{
if ((this.minWindow as MainMenu).mainWindow != null)
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 1";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2);
}
function = "地图缩小控制X:" + leftAndRightY;
}
//双缩小
if (isKinectControl && leftCentZ > 0.4 && rightCenterZ > 0.4 && leftAndRightX > )
{
if ((this.minWindow as MainMenu).mainWindow != null)
{
string fun1 = "设置相机只能水平移动, 0";
string fun2 = "相机移动控制, 0, 2";
// (this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript("执行内部函数,funReset");
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun1);
(this.minWindow as MainMenu).mainWindow.VRPControl.ExecuteVrpScript(fun2);
}
}
(minWindow.FindName("ctiveInfo") as TextBlock).Text = function;
#endregion handRight2 = handRight; }
/// <summary>
/// 绘画人体当前骨架
/// </summary>
/// <param name="skeleton">骨架数据</param>
/// <param name="brush">画笔</param>
private void DrawSkeleton(Skeleton skeleton, Brush brush)
{
Grid SkeletonsPanel = (minWindow.FindName("SkeletonsPanel") as Grid);
SkeletonsPanel.Children.Clear();
if (skeleton != null && skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
//绘制头部和躯干部
Polyline figure = CreateFigure(skeleton, brush, new[] { JointType.Head, JointType.ShoulderCenter, JointType.ShoulderLeft, JointType.Spine,
JointType.ShoulderRight, JointType.ShoulderCenter, JointType.HipCenter,
JointType.HipLeft, JointType.Spine, JointType.HipRight, JointType.HipCenter});
SkeletonsPanel.Children.Add(figure);
//绘画左脚
figure = CreateFigure(skeleton, brush, new[] { JointType.HipLeft, JointType.KneeLeft, JointType.AnkleLeft, JointType.FootLeft });
SkeletonsPanel.Children.Add(figure); //画右脚
figure = CreateFigure(skeleton, brush, new[] { JointType.HipRight, JointType.KneeRight, JointType.AnkleRight, JointType.FootRight });
SkeletonsPanel.Children.Add(figure); //h画左臂
figure = CreateFigure(skeleton, brush, new[] { JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, JointType.HandLeft });
SkeletonsPanel.Children.Add(figure); //画右臂
figure = CreateFigure(skeleton, brush, new[] { JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, JointType.HandRight });
SkeletonsPanel.Children.Add(figure);
}
}
/// <summary>
/// 根据人体骨架绘制多线段
/// </summary>
/// <param name="skeleton">骨架数据</param>
/// <param name="brush">画笔</param>
/// <param name="joints">关节</param>
/// <returns>多线段</returns>
private Polyline CreateFigure(Skeleton skeleton, Brush brush, JointType[] joints)
{
Polyline figure = new Polyline(); figure.StrokeThickness = ;
figure.Stroke = brush; for (int i = ; i < joints.Length; i++)
{
figure.Points.Add(GetJointPoint(skeleton.Joints[joints[i]]));
} return figure;
}
#endregion
}
}
Kinect 1.8 体感开发,手势,姿态(Pose) 捕捉判断方法以及一些辅方法的更多相关文章
- Kinect+unity 实现体感格斗闯关小游戏
文章目录 项目地址 1 项目概况 1.1 项目简介 1.2 项目目的 1.3 主要技术 2 设计 2.1 基本概念 2.2 框架 2.3 算法 2.4 模型 2.5 调查问卷 3 实现 3.1 技术难 ...
- 使用HTML5开发Kinect体感游戏
一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决, ...
- OpenNI结合Unity3D Kinect进行体感游戏开发(转)
OpenNI结合Unity3D Kinect进行体感游戏开发(转) 楼主# 更多 发布于:2012-07-17 16:42 1. 下载安装Unity3D(目前版本为3.4)2. 下载OpenN ...
- C#开发体感游戏 Kinect应用知识
Kinect首先是一个XBox 360外接体感设备,通过无线方式捕捉动作感知.由PrimeSense提供Range Camera技术,同类产品如任天堂Wii.Play Station Move,必须让 ...
- Kinect外包团队(长年承接微软Kinect体感项目外包,有大型Kinect案例)
承接Kinect体感企业项目.游戏项目外包 北京公司.专业团队,成员为专业WPF产品公司一线开发人员,有大型产品开发经验: 提供优质的售后服务,保证产品质量,轻量级产品可以提供规范清晰的源代码,有业务 ...
- Kinect用体感来实现UI控件的点击
用体感来实现UI控件的点击,如点击按钮. 做法:用一个图片表示左手手掌,图片位置追踪左手手掌移动,当手掌位于UI控件的矩形内时,握拳表示点击该控件. using UnityEngine; using ...
- Kinect外包-就找北京动点飞扬软件(长年承接微软Kinect体感项目外包,有大型Kinect案例)
承接Kinect体感企业项目.游戏项目外包 有丰富案例提供演示,可公对公签正规合同,开发票. 我们是北京的公司.专业团队,成员为专业WPF产品公司一线开发人员,有大型产品开发经验: 提供优质的售后服务 ...
- 制作Kinect体感控制小车教程 <一>
转载请注明出处:http://blog.csdn.net/lxk7280 Kinect体感控制小车 Kine ...
- U3D外包公司—北京动点(公司性质)承接U3D、Kinect、VR虚拟现实,增强现实,体感互动,大屏互动等各类外包
unity3d外包就找动点软件承接虚拟现实项目外包 承接U3D.Kinect.VR虚拟现实,增强现实,体感互动,大屏互动等各类外包 联系请加QQ:372900288 联系电话:13911652504 ...
随机推荐
- 多个springboot项目部署在同一tomcat上,出现jmx错误
多个springboot项目部署在同一tomcat上,出现jmx错误 原因:因为jmx某些东西重复,禁用jmx就可以了 endpoints.jmx.unique-names=true
- 新手学习selenium路线图(老司机亲手绘制)-学前篇【转载】
前言: 本来这篇是只在微信公众号(yoyoketang)上发布的,最近一搜,发现本很多人copy(copy公众号的,图片是加载不出来的)了,还没注明出处,不想多说什么,博客上也同步更新这篇吧! 最近群 ...
- cmake 同时编译多个cpp文件
cmake_minimum_required(VERSION 2.8) project(coding) file(GLOB_RECURSE EXTRA_FILES */*) add_custom_ta ...
- Oracle SQL*Loader commit point tips
http://www.dba-oracle.com/t_sql_loader_commit_frequency.htm - Question: Can I control the commit fr ...
- 微信小程序开发教程(四)线程架构与开发步骤
线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...
- 洛谷 P1452 Beauty Contest
题目背景 此处省略1W字^ ^ 题目描述 贝茜在牛的选美比赛中赢得了冠军”牛世界小姐”.因此,贝西会参观N(2 < = N < = 50000)个农场来传播善意.世界将被表示成一个二维平面 ...
- [xsy2164]theory
又积累了一个网络流模型:最大权闭合子图,相关证明去看论文,感觉自己不是很懂证明,但现在还是先把建模记下来再说吧 枚举一个点,硬点它一定要被选中,那么以它为根,如果选了$x$就必须要选$fa_x$,这就 ...
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...
- 【转载】【bitset】C++ STL bitset 使用总结
C++ bitset类的使用与简介 有些程序要处理二进制位的有序集,每个位可能包含的是0(关)或1(开)的值.位是用来保存一组项或条件的yes/no信息(有时也称标志)的简洁方法.标准库提供了bits ...
- @requestBody注解的使用(上)
1.@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是ap ...