使用kinect检测身体关节角度(检查时间间隔)

2024-01-21

正如您在图片中看到的(链接如下),当左手举起时,它会显示一个角度 我想要的是。一个人应该握住他的手臂 5 秒(如图所示的位置),并且如果该人改变其手臂位置(这意味着角度低于 70 度或高于 80 度) 5 秒内应显示一些消息,将手臂放回同一位置,然后计时器重新启动!

http://postimage.org/image/hpfl41nzp/ http://postimage.org/image/hpfl41nzp/


Mainwindow.xaml 文件

    <Window x:Class="shoulder_joint.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="511" Width="525" Loaded="Window_Loaded"    
     Closing="Window_Closing" >
     <Grid Height="479" Width="510">
     <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="6*" />
        <ColumnDefinition Width="497*" />
    </Grid.ColumnDefinitions>
    <Image Height="479" HorizontalAlignment="Left" Name="frame_image" Stretch="Fill"   
    VerticalAlignment="Top" Width="503" Grid.Column="1" Grid.ColumnSpan="2" />

   <Image Height="131" Margin="14,14,319,0" Name="Color_image" Stretch="Fill" 
   VerticalAlignment="Top" Grid.Column="2" />
</Grid>
</Window>

主窗口.xaml.cs

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using Microsoft.Xna.Framework;
 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;


 namespace shoulder_joint
 {

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    bool flag = false;
    angle angle1 = new angle();
    Draw_joint draw = new Draw_joint();

    int joint_thick =10;
    private readonly Brush detect_brush = Brushes.GreenYellow;
    private readonly Brush inferred_brush = Brushes.Indigo;
    private readonly Pen detect_pen = new Pen( Brushes.Black,6);
    private readonly Pen inferred_pen = new Pen (Brushes.DarkOliveGreen,2);

    KinectSensor sensor;
    Skeleton[] skelton;
    int width =491;
    int height =470;
    DrawingGroup drawing_group;
    DrawingImage draw_image;
    byte[] color_pixel;
    WriteableBitmap bitmap;
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        foreach (var potential_sensor in KinectSensor.KinectSensors)
        {
            if (potential_sensor.Status == KinectStatus.Connected)
            {
                sensor = potential_sensor;
                break;

            }
        }

        sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
        sensor.SkeletonStream.Enable();
        color_pixel = new byte [sensor.ColorStream.FramePixelDataLength];
        bitmap = new  WriteableBitmap(sensor.ColorStream.FrameWidth,
        sensor.ColorStream.FrameHeight,96,96,PixelFormats.Bgr32,null);
        Color_image.Source = bitmap;


        drawing_group = new DrawingGroup();
        draw_image = new DrawingImage(drawing_group);
        frame_image.Source = draw_image;

        sensor.SkeletonFrameReady += SensorSkeltonFrameReady;
        sensor.ColorFrameReady += SensorColorFrameReady;
        sensor.Start();

       }

   private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (sensor != null)
        {
            sensor.Stop();
        }
    }

    private void SensorColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
    {
        ColorImageFrame color_frame;
        using (color_frame = e.OpenColorImageFrame())
        {
            if (color_frame != null)
            {
                color_frame.CopyPixelDataTo(color_pixel);

                bitmap.WritePixels(new Int32Rect(0, 
                 0,bitmap.PixelWidth,bitmap.PixelHeight),
                   this.color_pixel, 
                    this.bitmap.PixelWidth* sizeof(int), 
                    0);

            }
        }
    }

    private void SensorSkeltonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
    {

        SkeletonFrame skelton_frame;


        using (skelton_frame = e.OpenSkeletonFrame())
        {
            if (skelton_frame != null)
            {

            skelton = new Skeleton[skelton_frame.SkeletonArrayLength];
           skelton_frame.CopySkeletonDataTo(skelton);

                using (DrawingContext dc = drawing_group.Open())
                {
                    dc.DrawRectangle(Brushes.Gray, null, new Rect(0, 0, width, 
                     height));
                    if (skelton != null)
                    {
                        foreach (Skeleton skel in skelton)
                        {
                            if (skel.TrackingState == SkeletonTrackingState.Tracked)
                            {
                                this.find_pos_joints(skel, dc);
                               // this.angle_between(dc);
                            }
                        }
                    }

                    drawing_group.ClipGeometry = new RectangleGeometry(new 
                     Rect(0,0,width,height));

                }
            }
        }


    }

    private void find_pos_joints(Skeleton sk, DrawingContext draw_contex)
    {
       draw.Draw_joint1(sk, draw_contex, JointType.ShoulderCenter, 
       JointType.ShoulderRight, 

       JointType.ElbowRight,JointType.WristRight,
       JointType.ShoulderLeft,JointType.ElbowLeft,JointType.WristLeft,
       JointType.Head,JointType.HipCenter,JointType.HipLeft,
       JointType.KneeLeft,JointType.AnkleLeft,
        detect_brush,inferred_brush,joint_thick,inferred_pen,detect_pen,sensor);


        angle1.angle_between_right_shoulder(sk,  
        draw_contex,JointType.Head,JointType.Spine ,JointType.ShoulderCenter,
        JointType.ShoulderRight,JointType.ElbowRight,sensor);

        angle1.angle_between_left_shoulder(sk, draw_contex,  JointType.ShoulderCenter, 
        JointType.ShoulderLeft, JointType.ElbowLeft, sensor);
        angle1.angle_between_left_leg(sk,    
        draw_contex,JointType.HipLeft,JointType.KneeLeft,JointType.AnkleLeft,sensor);
    }


   }
   }

绘制关节类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using System.Windows.Media;

namespace shoulder_joint
{
class Draw_joint
{
    angle angle1 = new angle();

    public void Draw_joint1(Skeleton sk1, DrawingContext dc1, JointType joint1,    
    JointType joint2,
        JointType joint3, JointType joint4, JointType joint5, JointType joint6, 
        JointType joint7,
        JointType joint8 ,JointType joint9,JointType joint100,JointType joint101, 
        JointType joint102
        ,Brush det_brush,
        Brush infer_brush,int thick, Pen det_pen,Pen infer_pen,KinectSensor sensor)
    {
        Joint joint11 = sk1.Joints[joint1];
        Joint joint22 = sk1.Joints[joint2];
        Joint joint33 = sk1.Joints[joint3];
        Joint joint44 = sk1.Joints[joint4];
        Joint joint55 = sk1.Joints[joint5];
        Joint joint66 = sk1.Joints[joint6];
        Joint joint77 = sk1.Joints[joint7];
        Joint joint88 = sk1.Joints[joint8];
        Joint joint99 = sk1.Joints[joint9];
        Joint joint10 = sk1.Joints[joint100];
        Joint joint1011 = sk1.Joints[joint101];
        Joint joint1022 = sk1.Joints[joint102];


        if (joint11.TrackingState == JointTrackingState.Tracked &&
            joint22.TrackingState == JointTrackingState.Tracked &&
            joint33.TrackingState == JointTrackingState.Tracked &&
            joint44.TrackingState == JointTrackingState.Tracked &&
            joint55.TrackingState == JointTrackingState.Tracked &&
            joint66.TrackingState == JointTrackingState.Tracked &&
            joint77.TrackingState == JointTrackingState.Tracked &&
            joint88.TrackingState == JointTrackingState.Tracked &&
            joint99.TrackingState == JointTrackingState.Tracked &&
            joint10.TrackingState == JointTrackingState.Tracked &&
            joint1011.TrackingState == JointTrackingState.Tracked &&
            joint1022.TrackingState == JointTrackingState.Tracked 
            )
        {

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint11.Position,  
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint22.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint33.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint44.Position,              
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint55.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint66.Position,  
            sensor), thick, thick);

           dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint77.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint88.Position,               
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint99.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, angle1.point_toScreen(joint10.Position, 
            sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen,   
            angle1.point_toScreen(joint1011.Position, sensor), thick, thick);

            dc1.DrawEllipse(det_brush, det_pen, 
            angle1.point_toScreen(joint1022.Position, sensor), thick, thick);


            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint11.Position, sensor),          
            angle1.point_toScreen(joint22.Position, sensor));

            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint11.Position, sensor), 
            angle1.point_toScreen(joint88.Position, sensor));

             dc1.DrawLine(infer_pen, angle1.point_toScreen(joint11.Position, sensor),  
              angle1.point_toScreen(joint99.Position, sensor));

          dc1.DrawLine(infer_pen, angle1.point_toScreen(joint22.Position, sensor), 
           angle1.point_toScreen(joint33.Position, sensor));

            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint33.Position, sensor), 
              angle1.point_toScreen(joint44.Position, sensor));

            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint11.Position, sensor), 
            angle1.point_toScreen(joint55.Position, sensor));


            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint55.Position, sensor), 
            angle1.point_toScreen(joint66.Position, sensor));

          dc1.DrawLine(infer_pen, angle1.point_toScreen(joint66.Position, sensor), 
            angle1.point_toScreen(joint77.Position, sensor));


            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint99.Position, sensor), 
            angle1.point_toScreen(joint10.Position, sensor));

            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint10.Position, sensor),  
            angle1.point_toScreen(joint1011.Position, sensor));

            dc1.DrawLine(infer_pen, angle1.point_toScreen(joint1011.Position, sensor), 
            angle1.point_toScreen(joint1022.Position, sensor));





        }
      }

    }
  }

角度.cs 类

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.Kinect;
 using System.Windows.Media;
 using Microsoft.Xna.Framework;
 using System.Windows;

 namespace shoulder_joint
 {
 class angle
 {

    public void angle_between_left_shoulder(Skeleton sk1, DrawingContext draw, 
    JointType Shoulder_cntre, 

    JointType Shoulder_left, JointType Elbow_left, KinectSensor sen)
    {
        Joint sh_cntr = sk1.Joints[Shoulder_cntre];
        Joint sh_left = sk1.Joints[Shoulder_left];
        Joint elb_left = sk1.Joints[Elbow_left];

        Vector3 v_shoulder = new Vector3(sh_cntr.Position.X, sh_cntr.Position.Y, 
        sh_cntr.Position.Z);

        Vector3 v_should_l = new Vector3(sh_left.Position.X, sh_left.Position.Y, 
         sh_left.Position.Z);

       Vector3 v_elbow_l = new Vector3(elb_left.Position.X, elb_left.Position.Y,    
       elb_left.Position.Z);

        Vector3 va = v_shoulder - v_should_l;
        Vector3 vb = v_elbow_l - v_should_l;

        va = Vector3.Normalize(va);
        vb = Vector3.Normalize(vb);

        float len_prod = va.Length() * va.Length();
        float dot_pro = Vector3.Dot(va, vb);
        double angle = Math.Acos(dot_pro);

        angle = angle * 180 / Math.PI;
        angle = 180 - angle;

        System.Windows.Point shoul_l = this.point_toScreen(sh_left.Position, sen);
        draw.DrawText(new FormattedText(angle.ToString("0"), new 
         System.Globalization.CultureInfo("en-us"),
         FlowDirection.LeftToRight,
         new Typeface("Verdana"), 16, Brushes.WhiteSmoke),
         new System.Windows.Point(shoul_l.X+10, shoul_l.Y +20));
    }


    public void angle_between_right_shoulder(Skeleton sk1, DrawingContext draw, 
     JointType head, JointType spine, 

     JointType Shoulder_cntre, JointType Shoulder_right, JointType 
      Elbow_right,KinectSensor sen)
    {
        Joint sh_cntr = sk1.Joints[Shoulder_cntre];
        Joint sh_right = sk1.Joints[Shoulder_right];
        Joint elb_right = sk1.Joints[Elbow_right];

        Vector3 v_shoulder = new Vector3(sh_cntr.Position.X, sh_cntr.Position.Y, 
        sh_cntr.Position.Z);

         Vector3 v_should_r = new Vector3(sh_right.Position.X, sh_right.Position.Y,  
         sh_right.Position.Z);

          Vector3 v_elbow_r = new Vector3(elb_right.Position.X, elb_right.Position.Y, 
          elb_right.Position.Z);

        Vector3 newv1 =v_shoulder - v_should_r ;
        Vector3 newv2 = v_elbow_r - v_should_r;

        newv1 = Vector3.Normalize(newv1);
        newv2 = Vector3.Normalize(newv2);

        float len_prod = newv1.Length() * newv2.Length();
        float dot_pro = Vector3.Dot(newv1, newv2);
        double angle = Math.Acos(dot_pro);

        angle = angle * 180 / Math.PI;
        angle = 180 - angle;


        System.Windows.Point shoul_r = this.point_toScreen(sh_right.Position, sen);
        draw.DrawText(new FormattedText(angle.ToString("0"), new
          System.Globalization.CultureInfo("en-us"),
         FlowDirection.LeftToRight,
         new Typeface("Verdana"), 16, Brushes.WhiteSmoke),
         new System.Windows.Point(shoul_r.X-15, shoul_r.Y+20));


    }

    public System.Windows.Point point_toScreen(SkeletonPoint point,KinectSensor sensor)
    {

       DepthImagePoint depth_point = sensor.MapSkeletonPointToDepth(point,    
        DepthImageFormat.Resolution640x480Fps30);
        return new System.Windows.Point(depth_point.X, depth_point.Y);
    }

   public void angle_between_left_leg(Skeleton sk, DrawingContext draw_contex, 
     JointType hip_l, JointType knee_l,

     JointType ankle_l,KinectSensor sen)
     {
       Joint Hl = sk.Joints[hip_l];
       Joint kl = sk.Joints[knee_l];
       Joint Al = sk.Joints[ankle_l];

        Vector3 hip_left = new Vector3(Hl.Position.X,Hl.Position.Y,Hl.Position.Z);
        Vector3 knee_left = new Vector3(kl.Position.X, kl.Position.Y, kl.Position.Z);
        Vector3 ankle_left = new Vector3(Al.Position.X, Al.Position.Y, Al.Position.Z);

        Vector3 va = hip_left - knee_left;
        Vector3 vb = ankle_left - knee_left;

        float len_prod = va.Length() * vb.Length();
        float dot_pro = Vector3.Dot(va, vb);
        double angle = Math.Acos(dot_pro/len_prod);

        angle = angle * 180 / Math.PI;
        angle = 180 - angle;

        System.Windows.Point shoul_r = this.point_toScreen(kl.Position, sen);
        draw_contex.DrawText(new FormattedText(angle.ToString("0"), new 
         System.Globalization.CultureInfo("en-us"),
         FlowDirection.LeftToRight,
         new Typeface("Verdana"), 16, Brushes.WhiteSmoke),
         new System.Windows.Point(shoul_r.X - 15, shoul_r.Y + 20));
   }

}

}



简单地使用 DispatchTimer 进行倒计时就能完成您想要做的事情吗?

伪代码如下:

private int isArmUpCounter = 5;
private bool isArmUp = false;

private void OnSkeletonReady() {
  if (myArm.Angle > 70 && myArm.Angle < 80)
  {
    if (isArmUp == false)
    {
      isArmUp = true;
      isArmUpCounter = 5;
      armUpTimer.Start();
    }
  }
  else
  {
    if (isArmUp == true && isArmUpCounter > 0)
    {
      Console.WriteLine("You dropped your arm too soon!");
    }

    isArmUp = false;
    armUpTimer.Stop();
  }
}

private void OnArmUpTimerTick() {
    // one a 1 second tick
    isArmUpCounter--;
}

当然需要对代码进行一些调整。但这个概念能达到您的要求吗?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用kinect检测身体关节角度(检查时间间隔) 的相关文章

  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • EventHandler 应该始终用于事件吗?

    我一直在愉快地使用自定义委托类型和通用编写事件Action委托类型 没有真正考虑我在做什么 我有一些很好的扩展助手Action and EventHandler这使我倾向于使用那些预定义的委托类型而不是我自己的委托类型 但除此之外 除了惯例
  • libtool 在 Ubuntu 13.04 上构建 thrift 0.9.1 时出错

    在 Ubuntu 13 04 上构建 thrift 0 9 1 支持 C C java C perl python 时出现此错误 configure 不带任何选项运行 make 不带任何选项运行 Making all in test mak
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 如何对STL向量进行排序?

    我想排序一个vector vector
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • 在 mvc4 中创建通用 mvc 视图

    我以前也提过类似的问题 没有得到答案 如何创建一个通用的 mvc4 视图 该视图可以显示传递给它的模型列表或单个模型 模型可以是个人 组织或团体 无论传递给它的是什么 如果您正在寻找类似的东西 model MyViewModel
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 用数组或向量实现多维数组

    我想使用单个数组或向量实现多维数组 可以像通常的多维数组一样访问它 例如 a 1 2 3 我陷入困境的是如何实施 操作员 如果数组的维数为 1 则 a 1 应该返回位于索引 1 处的元素 但是如果维数大于一怎么办 对于嵌套向量 例如 3 维
  • 初始化列表在 VC10 中不起作用

    我在 VC 2010 中编写了这个程序 class class1 public class1 initializer list
  • 使用 IdentityDbContext 和 Code First 自动迁移表位置和架构的实体框架?

    我正在尝试使用 IdentityDbContext 类设置自动迁移更新 并将更改传播到整个数据库的实际 DbContext 在进入代码之前 在使用自动迁移实现 IdentityDbContext 时 我收到此错误 影响迁移历史系统表位置的自
  • Unity,c++ 本机插件字节数组不匹配

    在我的 C 本机插件中 我有一个调用 vector
  • 如何知道 HTTP 请求标头值是否存在

    我确信这很简单 但是却让我感到厌烦 我在 Web 应用程序中使用了一个组件 它在 Web 请求期间通过添加标头 XYZComponent true 来标识自身 我遇到的问题是 如何在视图中检查此组件 以下内容不起作用 if Request
  • 如何在 Razor 编辑视图中显示选中的单选按钮 Asp net core mvc

    尽管 Razor 视图中的 Asp 网络核心代码 model List

随机推荐