人体姿态识别-左肩和左肘的定位识别

对于传统的人体动作识别方法来说,分为三类:基于人体模型的方法;基于全局特征的方法,基于特征的方法,人体动作丰富多样,不同的动作具有不同的含义。这里我选择基于特征的方法来识别人体某个部位的动作,即用一组特征向量来标识这个动作,一旦条件满足这个特征向量,就判定该动作被识别。

基于kinect硬件设备来说,其功能强大无比,其中骨骼帧的三维立体坐标都被进入在一帧的数据里面,三维坐标的方向如下:

空间坐标原点为深度摄像头的位置,以kinect深度摄像头的右侧为X轴正向,以kinect深度摄像头的上侧为y轴的正向,以kinect深度摄像头的前侧为Z轴的正向:如图一

图一

明白坐标系的位置及方向之后,就可以对人体25个关节点进行处理了,在这之前,我测试了下kinect的25个关节点的坐标,并将其保存在txt文档中,其数据如下:其中每一个数据都是人体关节点到深度摄像头的距离,每一行代表一个关节点的三维坐标,次序依次为:"头部", "脖子", "左肩", "左肘", "左腕", "左手", "左食指指尖", "右大拇指", "右肩", "右肘", "右腕", "右手", "右食指指尖", "右大拇指","肩部脊椎" ,"脊椎中心","脊椎尾部","左髋骨","左膝盖","左脚踝","左脚","右髋骨","右膝盖","右脚踝","右脚"

-0.123703  0.5555432  1.213775
-0.1285025  0.410982  1.259488
-0.2830234  0.2892215  1.260633
-0.314623  0.04511343  1.274519
-0.3590705  -0.1259917  1.18842
-0.3480108  -0.1867286  1.165522
-0.3350937  -0.2386908  1.130128
-0.2930106  -0.1850984  1.147
0.05812442  0.2823356  1.26813
0.1852455  0.1324079  1.256844
0.2263555  0.3260264  1.083552
0.2250388  0.3909267  1.044129
0.2356904  0.4620195  1.008516
0.1589416  0.3914632  1.121333
-0.1286564  0.335746  1.264128
-0.1283216  0.09956012  1.268763
-0.127224  -0.2318419  1.261028
-0.1983761  -0.2175556  1.219764
-0.1852868  -0.5608031  0.9363578
-0.1887519  -0.6600102  1.225695
-0.2521433  -0.6028567  1.14585
-0.0489066  -0.2327119  1.228814
-0.1435885  -0.5741755  0.9622245
-0.01206919  -0.6697052  1.225347

-0.03818841  -0.5850864  1.135253

这里我只列出两个关节点之间的距离关系,是相对于深度摄像头的坐标系来说的,关于空间中的两点的距离关系我们可以用欧氏距离公式来求:,两点之间的夹角,我们可以用余弦公式来求:

接下来我们开始定义姿势了:pa= {p1,p2,,}  ,特征向量,以关节点p1为中心点,关节点p2与X轴上的角度为;为设定的角度阈值。即为理想角度与实际角度的误差,只要不超过这一阈值,都被判定为这一姿势。为此我们定义这三种姿势:

开始姿势: = {180,180,-90,-90,15}

举起左手: = {90,180,-90,-90,15}

左手向右: = {0,180,-90,-90,15}

测试的数据表格如下:

动作:阈值15

人数

测试人数

正确识别次数

识别率%

开始姿势

5

10

50

100

左手举起

5

10

50

100

左手向右

5

10

50

100

表1

动作:阈值10

人数

测试人数

正确识别次数

识别率%

开始姿势

5

10

45

90

左手举起

5

10

46

92

左手向右

5

10

39

78

表2

动作:阈值20

人数

测试人数

正确识别次数

识别率%

开始姿势

5

10

48

96

左手举起

5

10

46

92

左手向右

5

10

44

88

表3

代码如下:

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.IO;namespace 人体姿态识别
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{#region Member Variables//体感器设备private KinectSensor _KinectDevice;//骨骼图像//骨骼帧读取变量private MultiSourceFrameReader multireader = null;private FrameDescription colorframedecrition = null;private WriteableBitmap colorbitmap = null;private Byte[] colordata;//玩家数据private Body[] _Bodies;private static int k = 0;//画骨架图颜色uint[]private Brush[] ColorBody = new Brush[]{Brushes.Red,Brushes.Green,Brushes.Pink,Brushes.Blue,Brushes.Black,Brushes.Orange//用不同颜色的刷子出人的骨骼};//关节点两两相连private JointType[] _JointType = new JointType[]{JointType.Head,JointType.Neck,JointType.ShoulderLeft,JointType.ElbowLeft,JointType.WristLeft,JointType.HandLeft,JointType.HandTipLeft,JointType.ThumbLeft,JointType.ShoulderRight,JointType.ElbowRight,JointType.WristRight,JointType.HandRight,JointType.HandTipRight,JointType.ThumbRight,JointType.SpineShoulder,JointType.SpineMid,JointType.SpineBase,JointType.HipLeft,JointType.KneeLeft,JointType.AnkleLeft,JointType.FootLeft,JointType.HipRight,JointType.KneeRight,JointType.AnkleRight,JointType.FootRight};static string[] jointname = { "头部", "脖子", "左肩", "左肘", "左腕", "左手", "左食指指尖", "右大拇指", "右肩", "右肘", "右腕", "右手", "右食指指尖", "右大拇指","肩部脊椎" ,"脊椎中心","脊椎尾部","左髋骨","左膝盖","左脚踝","左脚","右髋骨","右膝盖","右脚踝","右脚"};public List<ulong> trackedIds = new List<ulong>();#endregion Member Variables#region Constructorpublic MainWindow(){InitializeComponent();//获取默认的连接的体感器this._KinectDevice = KinectSensor.GetDefault();//多种帧读取初始化this.multireader = this._KinectDevice.OpenMultiSourceFrameReader(FrameSourceTypes.Color|FrameSourceTypes.Body);//触发骨骼帧处理事件this.multireader.MultiSourceFrameArrived += multireader_MultiSourceFrameArrived;this.colorframedecrition = this._KinectDevice.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);this.colordata = new Byte[this.colorframedecrition.LengthInPixels*4];this.colorbitmap = new WriteableBitmap(this.colorframedecrition.Width,this.colorframedecrition.Height,96.0,96.0,PixelFormats.Bgra32,null);colorfr.Source = this.colorbitmap;//玩家骨骼数组长度为6this._Bodies = new Body[6];//启动体感器this._KinectDevice.Open();}#endregion Construtor#region Methods//骨骼帧处理事件void multireader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e){Joint leftshoulder, leftelbow, leftwrist, rightshoulder, rightelbow, rightwrist;float rad1, rad2, rad3, rad4;float temp1,temp2,temp3,temp4;MultiSourceFrame msf = e.FrameReference.AcquireFrame();//获取一帧骨骼if (msf != null){using (BodyFrame bodyFrame = msf.BodyFrameReference.AcquireFrame()){using (ColorFrame colorframe = msf.ColorFrameReference.AcquireFrame()){if (bodyFrame != null&&colorframe!=null){//玩家骨骼保存到数组里面bodyFrame.GetAndRefreshBodyData(this._Bodies);foreach(Body body in _Bodies){if(body.IsTracked){Joint headpoint = body.Joints[JointType.Head];Point headpoint1 = getjointpointscreen(headpoint);Ellipse headcircle = new Ellipse() { Width = 150, Height = 150, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };Layout2.Children.Add(headcircle);Canvas.SetLeft(headcircle, headpoint1.X - 75);Canvas.SetTop(headcircle, headpoint1.Y - 75);leftshoulder = body.Joints[JointType.ShoulderLeft];leftelbow = body.Joints[JointType.ElbowLeft];leftwrist = body.Joints[JointType.WristLeft];rightshoulder = body.Joints[JointType.ShoulderRight];rightelbow = body.Joints[JointType.ElbowRight];rightwrist = body.Joints[JointType.WristRight];temp1 = ((leftshoulder.Position.Z - leftelbow.Position.Z) * (leftshoulder.Position.Z - leftelbow.Position.Z) + (leftshoulder.Position.Y - leftelbow.Position.Y) * (leftshoulder.Position.Y - leftelbow.Position.Y) + (leftshoulder.Position.X - leftelbow.Position.X) * (leftshoulder.Position.X - leftelbow.Position.X) + (leftshoulder.Position.Z - leftelbow.Position.Z) * (leftshoulder.Position.Z - leftelbow.Position.Z) + (leftshoulder.Position.X - leftelbow.Position.X) * (leftshoulder.Position.X - leftelbow.Position.X) - (leftshoulder.Position.Y - leftelbow.Position.Y) * (leftshoulder.Position.Y - leftelbow.Position.Y)) / (float)(2 * System.Math.Sqrt((leftshoulder.Position.Z - leftelbow.Position.Z) * (leftshoulder.Position.Z - leftelbow.Position.Z) + (leftshoulder.Position.Y - leftelbow.Position.Y) * (leftshoulder.Position.Y - leftelbow.Position.Y) + (leftshoulder.Position.X - leftelbow.Position.X) * (leftshoulder.Position.X - leftelbow.Position.X)) * System.Math.Sqrt((leftshoulder.Position.Z - leftelbow.Position.Z) * (leftshoulder.Position.Z - leftelbow.Position.Z) + (leftshoulder.Position.X - leftelbow.Position.X) * (leftshoulder.Position.X - leftelbow.Position.X)));if (leftelbow.Position.X < leftshoulder.Position.X) temp1 = -temp1;rad1 = (float)((float)System.Math.Acos((double)temp1)*180/System.Math.PI);//tex.Text = "角度为"+ rad1.ToString();if (System.Math.Abs(180 - rad1) < 15){tex.Text ="左肘和左肩水平";BitmapImage suit = new BitmapImage();suit.BeginInit();suit.UriSource = new Uri(@"D:\c++课程\人体姿态识别\水平.jpg", UriKind.RelativeOrAbsolute);sta.Source = suit;suit.EndInit();}else if (System.Math.Abs(90 - rad1) < 15) {tex.Text = "左肘和左肩垂直";BitmapImage suit = new BitmapImage();suit.BeginInit();suit.UriSource = new Uri(@"D:\c++课程\人体姿态识别\垂直.jpg", UriKind.RelativeOrAbsolute);sta.Source = suit;suit.EndInit();}else if(System.Math.Abs(0 - rad1) < 15){tex.Text = "左肘和左肩向左";BitmapImage suit = new BitmapImage();suit.BeginInit();suit.UriSource = new Uri(@"D:\c++课程\人体姿态识别\向左.jpg", UriKind.RelativeOrAbsolute);sta.Source = suit;suit.EndInit();}else {tex.Text = " ";//sta = null;}}}//骨骼网格清空//判断//匹配//foreach (Body body in this._Bodies)//{//    if (body.IsTracked == true)//    {//        trackedIds.Add(body.TrackingId);//        tt.Text = body.TrackingId.ToString();//    }//}//画骨架colorframe.CopyConvertedFrameDataToArray(this.colordata, ColorImageFormat.Bgra);this.colorbitmap.WritePixels(new Int32Rect(0, 0, this.colorbitmap.PixelWidth, this.colorbitmap.PixelHeight), this.colordata, this.colorbitmap.PixelWidth * 4, 0);Layout.Children.Clear();DrawBodies();}}}}}private Point getjointpointscreen(Joint headpoint){ColorSpacePoint colorpoint = this._KinectDevice.CoordinateMapper.MapCameraPointToColorSpace(headpoint.Position);colorpoint.X = (int)((colorpoint.X * Layout2.Width) / 1920);colorpoint.Y = (int)((colorpoint.Y * Layout2.Height) / 1080);return new Point(colorpoint.X, colorpoint.Y);}//画骨架,六个人private void DrawBodies(){//遍历6个玩家for (int i = 0; i < this._Bodies.Length; i++){//如果跟踪到玩家if (this._Bodies[i].IsTracked == true){//根据编号选择一种骨架的颜色Brush color = ColorBody[i % 6];Body oneBody = this._Bodies[i]; //通过循环将关节点两两连接,for (int j = 0; j < this._JointType.Length; j ++){//起点的屏幕坐标和终点的屏幕坐标Point StartP = GetJointPointScreen(oneBody.Joints[this._JointType[j]]);Ellipse sp = new Ellipse();sp.Width = 15;sp.Height = 15;sp.HorizontalAlignment = HorizontalAlignment.Left;sp.VerticalAlignment = VerticalAlignment.Top;sp.Fill = Brushes.Red;sp.Margin = new Thickness(StartP.X - sp.Width / 2, StartP.Y - sp.Height / 2, 0, 0);//设置起点、终点的坐标//把起点、终点及连接添加到网格中。Layout.Children.Add(sp);}//writedate(_Bodies[i]);//将某一帧的数据写入文件}}}//骨骼坐标转化为彩色图像坐标,再转化为屏幕坐标private Point GetJointPointScreen(Joint oneJoint){//骨骼坐标转化为彩色图像坐标ColorSpacePoint colorPoint = this._KinectDevice.CoordinateMapper.MapCameraPointToColorSpace(oneJoint.Position);//彩色图像坐标转化为屏幕坐标colorPoint.X = (int)((colorPoint.X * Layout.Width) / 1920);colorPoint.Y = (int)((colorPoint.Y * Layout.Height) / 1080);//返回Point类型变量return new Point(colorPoint.X, colorPoint.Y);}//窗口关闭处理事件private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e){//骨骼帧关闭处理if (this.multireader != null){this.multireader.Dispose();this.multireader = null;}//体感器关闭处理if (this._KinectDevice != null){this._KinectDevice.Close();this._KinectDevice = null;}}#endregion Methods}
}

运行效果:

不过,该实验的骨骼点抖动太大,不知道各位有什么好的方法来消除抖动没有。

人体姿态识别-左肩和左肘的定位识别相关推荐

  1. 人体姿态识别研究综述(详细归纳!)(转载)

    一,人体姿态识别数据集 1,2D数据集: LSP 地址:http://sam.johnson.io/research/lsp.html 样本数:2K 关节点个数:14 全身,单人 FLIC 地址:ht ...

  2. [论文评析]基于人体姿态识别的立定跳远 动作智能评估系统

    基于人体姿态识别的立定跳远 动作智能评估系统 论文信息 背景 方法 系统总体设计 立定跳远动作智能评估系统 标准动作库子系统 动作采集子系统 人体姿态动作评估子系统 人体姿态评估模型 立定跳远关键帧匹 ...

  3. 2D人体姿态识别-Human3.6M与COCO数据集中,各人体骨骼关键点可视化及对应关节标注顺序(heatmap可视化,热力图和原图融合显示)

    003-2.processData 文章目录 前言 一.最终结果展示 1. Human3.6M数据集中32个人体关键点可视化及含义 2. COCO数据集中19个人体关键点可视化及含义 3. Human ...

  4. 【姿态识别】基于HOG特征提取和GRNN广义回归神经网络的人体姿态识别matlab仿真

    1.软件版本 matlab2013b 2.本算法理论知识 GRNN广义回归神经网络的理论基础是非线性核回归分析,非独立变量y相对于独立变量x的回归分析实际上是计算具有最大概率值的y.设随机变量x和y的 ...

  5. tfpose与openpose区别_人体姿态识别--Openpose+Tensorflow

    目的复现代码 完成视频中的人体姿态识别 复现过程 视频来源:https://www.youtube.com/watch?v=cMhWNGBW1Xg​www.youtube.com 视频动图 检测结果下 ...

  6. python人体识别_Github开源人体姿态识别项目OpenPose中文文档

    OpenPose人体姿态识别项目是美国卡耐基梅隆大学(CMU)基于卷积神经网络和监督学习并以caffe为框架开发的开源库.可以实现人体动作.面部表情.手指运动等姿态估计.适用于单人和多人,具有极好的鲁 ...

  7. MATLAB差影法的人体姿态识别

    GUI框架源码: https://download.csdn.net/download/weixin_44748303/12682348 该课题为基于MATLAB差影法的人体姿态识别.带有一个GUI可 ...

  8. 3D人体姿态识别数据集

    最近看3D人体姿态识别方面论文,在数据处理阶段,3D比2D复杂很多.2D人体姿态识别在dataset和model方面都比3D成熟,2Dmodel也有很多户外,自然界的dataset,但是3D的data ...

  9. python人体动作识别_人体姿态识别--Openpose+Tensorflow

    目的复现代码 完成视频中的人体姿态识别 复现过程

  10. 论文解读《PScL-HDeep:基于图像的蛋白质利用集成在人体组织中的亚细胞预测定位》

    论文解读<PScL-HDeep:基于图像的蛋白质利用集成在人体组织中的亚细胞预测定位> 期刊名: BRIEFINGS IN BIOINFORMATICS 期刊名缩写:BRIEF BIOIN ...

最新文章

  1. 如何使用MatPlotLib绘制出具有两个 Y 轴的曲线图?
  2. springboot学习笔记(二)
  3. ai保存web格式没有html,存储技巧,讲解AI存储为WEB所用格式的一些知识
  4. 互利网上数字金融典型场景: 网络支付
  5. azure机器学习_如何集成SQL Server和Azure机器学习
  6. kafka的connect实现数据写入到kafka和从kafka写出
  7. 计算机管理系统权限申请审批表,开通权限申请书范文
  8. html:optionscollection 默认值,关于html:options collection= /的使用
  9. python eel + vue开发桌面应用
  10. 服装扣件行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  11. 腾讯云修改邮箱登录方式
  12. win10锁屏聚集图片不更新,右上角没有出现喜欢的按钮,怎么办?
  13. 七步带你认识计算机视觉(Computer Vision)
  14. 为什么大学还在教过时的软件技术,程序员:只能说你根本不懂软件
  15. 2022年2月视频行业用户洞察:冬奥吸引全民关注拉动平台出圈,综合视频用户规模回升
  16. Spark RDD的窄依赖和宽依赖
  17. 局域网无法访问发布的网站问题解决
  18. java applet的生命周期_Java Applet的生命周期是什么?生命周期方法介绍
  19. license生成工具
  20. 几百万的资金在股市会被主力盯上吗?

热门文章

  1. 随机信号分析学习笔记(6)
  2. 「 Matlab 」矩阵运算讲解
  3. NB-IoT移远BC95使用小结
  4. Navicat Premiumx64 使用注册机激活
  5. JAVA中this三种方法详解
  6. Windows 7 系统的旧版IE浏览器升级到IE11
  7. 江苏省公安厅交管高速公路硬件扩容备份一体机项目
  8. 进行桌面共享软件开发的市场前景如何
  9. shiro安全框架 面试题
  10. Overleaf 指南:30 分钟 LaTeX 入门