对着书上敲得,从中体会kinect骨骼识别与深度识别的原理。大体原理是懂了,但有些细节还没有完全弄明白。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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; namespace KinectMeasure
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private KinectSensor kinect;
public MainWindow()
{
InitializeComponent();
}
private void startKinect()
{
if (KinectSensor.KinectSensors.Count > 0)
{
kinect = KinectSensor.KinectSensors[0];
kinect.DepthStream.Enable();
kinect.SkeletonStream.Enable();
kinect.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(kinect_DepthFrameReady);
kinect.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinect_SkeletonFrameReady);
kinect.Start();
}
}
private void stopKinect()
{
if (kinect != null)
{
if (kinect.Status == KinectStatus.Connected)
{
kinect.Stop();
}
}
}
Skeleton GetClosetSkeleton(SkeletonFrame frame)
{
frame.CopySkeletonDataTo(allSkeletons);
Skeleton closestSkeleton = (from s in allSkeletons
where s.TrackingState == SkeletonTrackingState.Tracked && s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked
select s).OrderBy(s => s.Joints[JointType.Head].Position.Z).FirstOrDefault();//这……这是what?
return closestSkeleton;
}
void kinect_SkeletonFrameReady(object sensor, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame SFrame = e.OpenSkeletonFrame())
{
if (SFrame == null)
return;
Skeleton s = GetClosetSkeleton(SFrame);
if (s == null)
return;
if (s.ClippedEdges == FrameEdges.None)
return;
SkeletonPoint head = s.Joints[JointType.Head].Position;//头
SkeletonPoint centerShoulder = s.Joints[JointType.ShoulderCenter].Position;//肩
SkeletonPoint leftFoot = s.Joints[JointType.FootLeft].Position;//左脚
float height = Math.Abs(head.Y - leftFoot.Y);//身高
float heightEx = Math.Abs(head.Y - centerShoulder.Y) + 0.1f;//头高?
float realHeightViaskeleton = height + heightEx;//计算出的真实高度
labelHeightViaSkeleton.Content = realHeightViaskeleton.ToString();
}
}
const int MaxSkeletonTrackingCount=6;//最多可以同时跟踪的用户数
private Skeleton[]allSkeletons=new Skeleton[MaxSkeletonTrackingCount];//用户骨骼的集合
void kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame DFrame = e.OpenDepthImageFrame())
{
if (DFrame != null)
{
short[] pixelData = new short[kinect.DepthStream.FramePixelDataLength];
DFrame.CopyPixelDataTo(pixelData);
MessureSpecifiedPlayerSize(DFrame,pixelData);
BitmapSource source = BitmapSource.Create(640, 480, 969, 96, PixelFormats.Gray16, null, pixelData, 640 * 2);
imageDepth.Source = source;
}
}
}
private static readonly double HorizontalPoVTanA = Math.Tan(57.0 / 2.0 * Math.PI / 180);
private void MessureSpecifiedPlayerSize(DepthImageFrame depthFrame,short[] pixelData)
{
int depth;
int playerIndex;
int pixelIndex;
int bytesPerPixel = depthFrame.BytesPerPixel;//这是what?
int depthSum = 0;
int depthCount = 0;
//身体各个部位的深度
int depthPixelBodyLeft = int.MaxValue;
int depthPixelBodyRight = int.MinValue;
int depthPixelBodyBottom = int.MaxValue;
int depthPixelBodyTop = int.MinValue;
for(int row = 0; row < depthFrame.Height; row++)
{
for (int col = 0; col < depthFrame.Width; col++)
{
pixelIndex=col+(row*depthFrame.Width);
depth = pixelData[pixelIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;//获得此处的深度数据
playerIndex=(pixelData[pixelIndex]&DepthImageFrame.PlayerIndexBitmask);//判断此处是否为用户
//注:该代码仅支持一个用户测量
if (depth != 0 && playerIndex != 0)
{
depthCount++;//非0的深度
depthSum += depth;//总深度
depthPixelBodyLeft = Math.Min(depthPixelBodyLeft, col);
depthPixelBodyRight = Math.Max(depthPixelBodyRight, col);
depthPixelBodyBottom = Math.Min(depthPixelBodyBottom, row);
depthPixelBodyTop = Math.Max(depthPixelBodyTop, row);
}
}
}
if (depthCount != 0)
{
double avgDepth = depthSum / depthCount;
int pixelWidth = Math.Abs(depthPixelBodyRight - depthPixelBodyLeft);
int pixelHeight = Math.Abs(depthPixelBodyTop - depthPixelBodyBottom);
double realHeightViaDepth = (2 * avgDepth * HorizontalPoVTanA * pixelHeight) / depthFrame.Width;//depthFrame.Wdith是计算机中框架的宽度
labelHeightViaSkeleton.Content = realHeightViaDepth.ToString();
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
startKinect();
} private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
stopKinect();
}
}
}

Kinect测量人体身高的程序的更多相关文章

  1. 基于三个kinect的人体建模

       单个kinect的人体重建,在Kinect SDK 1.8中,Kinect Fusion的效果已经很不错了.其缺点显而易见,一是扫描时间长,重建对象也需要长时间保持静态:二是需要人体或者kine ...

  2. C#测量程序运行时间及cpu使用时间

    转载:http://www.cnblogs.com/yanpeng/archive/2008/10/15/1943369.html 对一个服务器程序想统计每秒可以处理多少数据包,要如何做?答案是用处理 ...

  3. C#测量程序运行时间及cpu使用时间实例方法

    private void ShowRunTime() { TimeSpan ts1 = Process.GetCurrentProcess().TotalProcessorTime; Stopwatc ...

  4. Kinect开发文章目录

    整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...

  5. 【翻译】Kinect v2程序设计(C++) Body 篇

    Kinect SDK v2预览版的主要功能的使用介绍,基本上完成了.这次,是关于取得Body(人体姿势)方法的说明.   上一节,是使用Kinect SDK v2预览版从Kinect v2预览版取得B ...

  6. Kinect开发学习笔记之(一)Kinect介绍和应用

    Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  7. Kinect的学习笔记发展(一)Kinect引进和应用

    Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  8. Kinect的学习笔记发展一Kinect引进和应用

    Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  9. Kinect 开发 —— 控制PPT播放

    实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...

随机推荐

  1. Oracle数据库—— PL/SQL基础编程

    一.涉及内容 1. 掌握PL/SQL程序块的结构,理解并熟悉各种变量的应用. 二.具体操作 (一)使用system用户登录SQL*PLUS,使用SQL语句创建用户:u_你的姓名首字母(例如:u_zs) ...

  2. asp.net中Cookie的用法【转】

    比如建立一个名为aspcn,值为灌水小鱼的cookie HttpCookie cookie = new HttpCookie["aspcn"];cookie.Value = &qu ...

  3. HTML5服务器推送事件

    目前客户端(浏览器)和服务端交互大致有以下几种方式: 1)form表单提交方式,适合访问量不大,对用户体验要求不高的web系统开发,或者页面整体刷新无伤大雅的场合,通信方向是客户端提交给服务端,是客户 ...

  4. Maven最佳实践:版本管理

    什么是版本管理 首先,这里说的版本管理(version management)不是指版本控制(version control),但是本文假设你拥有基本的版本控制的知识,了解subversion的基本用 ...

  5. SQLSERVER 脚本转MYSQL 脚本的方法总结

    1.MYSQL(版本为5.6)中SQL脚本必须以分号(;)结尾,这点比SQLSERVER要严谨:关键字与函数名称全部大写:数据库名称.表名称.字段名称全部小写. 2.所有关键字都要加上``,比如 St ...

  6. eclipse解压后启动弹出A Java Runtime Evironment(JRE) or Java Development Kit(JDK)....

    系统环境:win7 64bit JDK:jdk-7u79-windows-x64 Eclipse:eclipse-jee-helios-win32 启动eclipse:弹出A Java Runtime ...

  7. 删除Android自带软件方法及adb remount 失败解决方案

    删除Android自带软件方法 1.在电脑上打开cmd,然后输入命令 adb remount adb shell su 2.接着就是Linux命令行模式了,输入 cd system/app 3然后输入 ...

  8. 【redis】 linux 下redis 集群环境搭建

    Redis集群 (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下) 127.0.0.1:63791 ...

  9. Servlet Listener

    需要继承ServletContextListener接口. 代码: package com.my; import java.io.*; import javax.servlet.*; import j ...

  10. hostapd移植与使用

    介绍 版本:hostapd-2.5.tar.gz 下载地址:http://w1.fi/releases/hostapd-2.5.tar.gz 依赖:libnl openssl 移植 libnl移植 w ...