Kinect测量人体身高的程序
对着书上敲得,从中体会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测量人体身高的程序的更多相关文章
- 基于三个kinect的人体建模
单个kinect的人体重建,在Kinect SDK 1.8中,Kinect Fusion的效果已经很不错了.其缺点显而易见,一是扫描时间长,重建对象也需要长时间保持静态:二是需要人体或者kine ...
- C#测量程序运行时间及cpu使用时间
转载:http://www.cnblogs.com/yanpeng/archive/2008/10/15/1943369.html 对一个服务器程序想统计每秒可以处理多少数据包,要如何做?答案是用处理 ...
- C#测量程序运行时间及cpu使用时间实例方法
private void ShowRunTime() { TimeSpan ts1 = Process.GetCurrentProcess().TotalProcessorTime; Stopwatc ...
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- 【翻译】Kinect v2程序设计(C++) Body 篇
Kinect SDK v2预览版的主要功能的使用介绍,基本上完成了.这次,是关于取得Body(人体姿势)方法的说明. 上一节,是使用Kinect SDK v2预览版从Kinect v2预览版取得B ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect的学习笔记发展(一)Kinect引进和应用
Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect的学习笔记发展一Kinect引进和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
随机推荐
- linux包之iproute之ss命令
概述 [root@localhost ~]# rpm -qa|grep iprouteiproute-2.6.32-31.el6.x86_64 当服务器的socket连接数量变得非常大时,无论是使用n ...
- GridView 控制分页页码间距
来源:http://auv2009.blog.163.com/blog/static/68858712200992793853431/ 技巧1:在分页区中改变当前页码的样式或高亮显示页码 一个简单的办 ...
- no ocijdbc11 in java.library.path linux
no ocijdbc11 in java.library.path linux vi /etc/profile export ORACLE_HOME=/oracle/database/oracle/p ...
- Amoeba:开源的分布式数据库Porxy解决方案
http://www.biaodianfu.com/amoeba.html 什么是Amoeba? Amoeba(变形虫)项目,该开源框架于2008年 开始发布一款 Amoeba for Mysql软件 ...
- mootools upgrate from 1.2 to 1.3 or 1.4
Update from 1.2 to 1.3 lorenzos edited this page on 8 Jul 2011 · 2 revisions Pages 19 Home Home Chan ...
- android 反编译 逆向工具整理
需要准备的道具需要哪些软件会在后面逆向过程中详细介绍,这里先大致罗列一下 android一台root并安装了xposed框架的手机(主要是为了脱壳) 类似[海马玩]这种模拟器 android-kill ...
- 未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0"解决方案
可以到http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede1 ...
- select,epool,pool解释
内容主要来自搜狗实验室技术交流文档, 编写链接数巨大的高负载服务器程序时,经典的多线程模式和select模式都不再适合了.应该采用epool/kqueue/dev_pool来捕获IO事件. ----- ...
- 部署与管理ZooKeeper(转)
本文以ZooKeeper3.4.3版本的官方指南为基础:http://zookeeper.apache.org/doc/r3.4.3/zookeeperAdmin.html,补充一些作者运维实践中的要 ...
- Scala第四章学习笔记(面向对象编程)
延迟构造 DelayedInit特质是为编译器提供的标记性的特质.整个构造器被包装成一个函数并传递给delayedInit方法. trait DelayedInit { def deayedInit( ...