using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Microsoft.Kinect;using ...
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 get='_blank'>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 = 4000; 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 = 0; 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 = 0; 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 = 0; 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, 2) + Math.Pow(primaryPoint.Y - angelPoint.Y, 2)); b = primaryPoint.X; c = Math.Sqrt(Math.Pow(angelPoint.X - pr.X, 2) + Math.Pow(angelPoint.Y - pr.Y, 2)); double angelRed = Math.Acos((a * a + b * b - c * c) / (2 * a * b)); angel = angelRed * 180 / Math.PI; if (primaryPoint.Y < angelPoint.Y) { angel = 360 - 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 = 0; 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, 2) + Math.Pow(primaryPoint.Y - angelPoint.Y, 2)); b = Math.Sqrt(Math.Pow(angelPoint.X - pr.X, 2) + Math.Pow(angelPoint.Y - pr.Y, 2)); c = Math.Sqrt(Math.Pow(pr.X - primaryPoint.X, 2) + Math.Pow(pr.Y - primaryPoint.Y, 2)); double angelRed = Math.Acos((a * a + b * b - c * c) / (2 * a * b)); angel = angelRed * 180 / Math.PI; if (primaryPoint.Y > angelPoint.Y) { angel = 360 - 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; }
原标题:Kinect 1.8 体感开发,手势,姿态(Pose) 捕捉判断方法以及一些辅方法
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。