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捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
随机推荐
- vs2010 clickone 工程安装后的路径 win7
C:\Users\xuan\AppData\Local\Apps\2.0\DX16T5JV.MLO\1H1ZAND1.1ZY\test..tion_f74974f651f2573b_0001.0000 ...
- SMO序列最小最优化算法
SMO例子: 1 from numpy import * 2 import matplotlib 3 import matplotlib.pyplot as plt 4 5 def loadDataS ...
- linux ubuntu系统下,adb不是内部命令 (如何才能让adb命令可以使用)
linux ubuntu系统下,adb不是内部命令 原文地址 linux ubuntu系统下,adb不是内部命令 解决方法: 1.sudo gedit ~/.bashrc 2.将下面的两句加到上面打开 ...
- SQL 查看数据库表的容量大小
--==============查看数据库表的容量大小========start================================?============ Create Table # ...
- 10 程序员必备:Linux日常维护命令
一.服务器硬件配置 1.查看硬盘及分区情况 # fdisk -l 2.查看分区空间使用情况 可以查看各分区大小.已使用.可用.已使用百分比.挂载情况 1)默认单位为K # df 2)可读性更好的显示, ...
- 51nod1369 无穷印章
有一个印章,其完全由线段构成.这些线段的线足够细可以忽略其宽度,就像数学上对线的定义一样,它们没有面积.现在给你一张巨大的白纸(10亿x10亿大小的纸,虽然这个纸很大,但是它的面积毕竟还是有限的),你 ...
- 详解 “Android UI”设计官方教程
我们曾经给大家一个<MeeGo移动终端设备开发UI设计基础教程>,同时很多朋友都在寻找Android UI开发的教程,我们从Android的官方开发者博客找了一份幻灯片,介绍了一些Andr ...
- Dell vsotro 14 3000系列从win10重装win7
1. F2启动进入新的BIOS界面,首先Disable Secure Boot,然后把UEFI改为Legeacy模式,当然是改不回来的,不知道为什么: 2. 插入U盘(老毛桃+UEFI启动镜像): 3 ...
- 黄聪:NaviCat通过Http方式连接服务器的MySQL数据库(转)
首先到NaviCat官网上去下载最新版本的NaviCat.安装完成后,打开NaviCat,如下图所示: 然后点击左上角的连接,弹出新键连接信息,如下图所示: 在主机名IP地址那里填写LocalHost ...
- java面试常考题
基础知识: 1.C++或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2种情况.一种是JAVA类库 ...