对着书上敲得,从中体会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. C#读写txt文件的两种方法介绍

    C#读写txt文件的两种方法介绍 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出 ...

  2. asp.net 计算两个时间差

    两个时间相差多少 .net中的timespan应用2008/11/10 11:54TimeSpan 对象表示时间间隔或持续时间,按正负天数.小时数.分钟数.秒数以及秒的小数部分进行度量.用于度量持续时 ...

  3. Linux环境下MySQL使用入门

    1 安装 1.1 yum安装 yum install mysql-server yum remove mysql service mysqld restart // 服务重新启动 chkconfig ...

  4. jquery中关于append()的用法笔记---append()节点移动与复制之说

    jquery中关于append()的用法笔记---append()节点移动与复制之说 今天看一本关于jquery的基础教程,看到其中一段代码关于append()的一行,总是百思不得其解.于是查了查官方 ...

  5. [转] matlab figure最大化

    http://blog.163.com/yinhexiwen@126/blog/static/6404826620122942057214/ % figure 窗口最大化,坐标轴也随着窗口变大而相应变 ...

  6. LintCode "Binary Representation"

    Not hard to think of a solution. But the key is all details. class Solution { public: /** *@param n: ...

  7. 【JDBC】向数据表插入数据时,自动获取生成的主键

    数据表设计时,一般都会有一个主键(Key)(自己指定),有时也可以使用联合主键: 有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值(如:rowid): 当我们没有指定哪一列作为主键key时,数 ...

  8. Spring实战2:装配bean—依赖注入的本质

    主要内容 Spring的配置方法概览 自动装配bean 基于Java配置文件装配bean 控制bean的创建和销毁 任何一个成功的应用都是由多个为了实现某个业务目标而相互协作的组件构成的,这些组件必须 ...

  9. MySQL使用位运算

    通常 我们的数据表中 可能会包含各种状态属性, 例如 blog表中,我们需要有字段表示其是否公开,是否有设置密码,是否被管理员封锁,是否被置顶等等. 也会遇到在后期运维中,策划要求增加新的功能而造成你 ...

  10. WEBrick/Rack Puppet Master

    Puppet's Services: The WEBrick Puppet Master Puppet master is the application that compiles configur ...