一、kinect开发的一个流程图

1、我们可以知道一个简单的框架就是几部分

(1)选择使用的kinect传感器

KinectSensor.KinectSensors[]

(2)打开需要的数据流

_kinect.DepthStream.Enable();
_kinect.ColorStream.Enable();
_kinect.SkeletonStream.Enable();

(3)注册事件

其实就是主要的算法在这里体现。

有个小窍门:VS的CodeSnippet快速生成事件代码,如在代码“_kinect.DepthFrameReady+=”后面连续按两次“Tab”键,就会生成相应的时间并处理相应的代码。

二、初始化、启用kinect设备

代码如下,记得要声明一个私有成员变量_kinect,并在MainWindow()里面调用。

KinectSensor _kinect;

        private void startKinect()
{
if(KinectSensor.KinectSensors.Count>)
{
//选择第一个kinect设备
_kinect = KinectSensor.KinectSensors[];
MessageBox.Show("Kinect目前状态为:" + _kinect.Status); //初始化设定,启用彩色图像,深度图像和骨骼追踪
_kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
_kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
_kinect.SkeletonStream.Enable(); //注册时间,该方法将保证彩色图像,深度图像和骨骼图像的同步
_kinect.AllFramesReady += _kinect_AllFramesReady; //启动kinect
_kinect.Start();
}
else
{
MessageBox.Show("没有发现任何kinect设备");
}
}

void _kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{

}

三、彩色图像流数据处理

1、在MainWindows窗体上新增一个Image控件,命名为imageCamera

2、在_kinect_AllFramesReady事件处理中增加如下代码、

//显示彩色摄像头
using(ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if(colorFrame == null)
{
return;
} byte[] pixels = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(pixels); //BGR32格式图片一个像素为4个字节
int stride = colorFrame.Width * ;
ImageCamera.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, , , PixelFormats.Bgr32, null, pixels, stride); }

BGR32图像的1像素对应4字节(32位),分别是B,G,R,阿尔法通道(透明度)。

BitmapSource.Create是一个从数组到二维矩阵的过程。

Stride为图片步长,代表图片一行像素所占的字节数,为摄像头传输图片的宽度乘以4,

DPI,越高越清晰,普通的显示器就是96差不多。

3、效果图

四、深度数据捕获

1、定义深度图像的有效视角范围。

const float MaxDepthDistance = ;
const float MinDepthDistance = ;
const float MaxDepthDistanceOffest = MaxDepthDistance - MinDepthDistance; private const int RedIndex = ;
private const int GreenIndex = ;
private const int BlueIndex = ;

2、代码

private byte[]convertDepthFrameToColorFrame(DepthImageFrame depthFrame)
{
short[] rawDepthData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(rawDepthData); Byte[] piexls = new byte[depthFrame.Height * depthFrame.Width * ]; for(int depthIndex = ,colorIndex=;depthIndex<rawDepthData.Length&&colorIndex<piexls.Length;depthIndex++,colorIndex+=)
{
int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask; int depth = rawDepthData[depthIndex];
if(depth<=)
{
piexls[colorIndex + BlueIndex] = ;
piexls[colorIndex + GreenIndex] = ;
piexls[colorIndex + RedIndex] = ;
}
else if(depth>&&depth<)
{
piexls[colorIndex + BlueIndex] = ;
piexls[colorIndex + GreenIndex] = ;
piexls[colorIndex + RedIndex] = ;
}
else if(depth>)
{
piexls[colorIndex + BlueIndex] = ;
piexls[colorIndex + GreenIndex] = ;
piexls[colorIndex + RedIndex] = ;
} byte intensity = CalculateIntensityFromDepth(depth);
piexls[colorIndex + BlueIndex] = intensity;
piexls[colorIndex + GreenIndex] = intensity;
piexls[colorIndex + RedIndex] = intensity; if(player>)
{
piexls[colorIndex + BlueIndex] = Colors.LightGreen.B;
piexls[colorIndex + GreenIndex] = Colors.LightGreen.G;
piexls[colorIndex + RedIndex] = Colors.LightGreen.R;
}
}
return piexls;
} void _kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
//显示彩色摄像头
using(ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if(colorFrame == null)
{
return;
} byte[] pixels = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(pixels); //BGR32格式图片一个像素为4个字节
int stride = colorFrame.Width * ;
ImageCamera.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, , , PixelFormats.Bgr32, null, pixels, stride); } using(DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if(depthFrame==null)
{
return;
} byte[] piexls = convertDepthFrameToColorFrame(depthFrame); int stride = depthFrame.Width * ;
imageDepth.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height, , , PixelFormats.Bgr32, null, piexls, stride); }

3、效果图

五、骨骼追踪

1、首先注释掉我们之前注册的时间,重新注册一个彩色数据流时间和一个骨骼事件,然后添加如下代码

private Skeleton[] skeletons;
void _kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
bool isSkeletonDataEeady = false;
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if(skeletonFrame!=null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
isSkeletonDataEeady = true;
} } if(isSkeletonDataEeady==true)
{
Skeleton currentSkeleton = (from s in skeletons where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault();
if(currentSkeleton !=null)
{
lockHeadWithSpot(currentSkeleton);
} }
} void lockHeadWithSpot(Skeleton s)
{
Joint head = s.Joints[JointType.Head];
ColorImagePoint colorPoint = _kinect.MapSkeletonPointToColor(head.Position, _kinect.ColorStream.Format); Point p = new Point((int)(ImageCamera.Width * colorPoint.X / _kinect.ColorStream.FrameWidth),
(int)(ImageCamera.Height * colorPoint.Y / _kinect.ColorStream.FrameHeight)); Canvas.SetLeft(ellipseHead, p.X);
Canvas.SetRight(ellipseHead, p.Y);
} void _kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame == null)
{
return;
} byte[] pixels = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(pixels); //BGR32格式图片一个像素为4个字节
int stride = colorFrame.Width * ;
ImageCamera.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, , , PixelFormats.Bgr32, null, pixels, stride); } }

2、效果图

六关闭kinect设备

private void stopKinect()
{
if(_kinect != null)
{
if(_kinect.Status== KinectStatus.Connected)
{
_kinect.Stop();
}
}
}

kinect学习笔记(四)——各种数据流的更多相关文章

  1. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  2. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

  3. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  4. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  5. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  6. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  8. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  9. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

  10. Go语言学习笔记四: 运算符

    Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...

随机推荐

  1. GDB中应该知道的几个调试方法 来自陈皓

    GDB中应该知道的几个调试方法 2011年2月10日陈皓发表评论阅读评论62,325 人阅读   七.八年前写过一篇<用GDB调试程序>,于是,从那以后,很多朋友在MSN上以及给我发邮件询 ...

  2. sql数据库常用语句总结

    1.增加字段     alter table docdsp     add dspcodechar(200)2.删除字段     ALTER TABLE table_NAME DROP COLUMNc ...

  3. 山东省第四届acm.Rescue The Princess(数学推导)

    Rescue The Princess Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 412  Solved: 168 [Submit][Status ...

  4. Tenth scrum meeting - 2015/11/4

    我们的项目开发已经渐渐进入了后期,每个模块都只剩下了一小块任务待做,同学们在做自己的模块的同时也开始对各个同学的模块进行合并. 其中最麻烦的就是视频播放模块与其他模块的合并了,由于该模块的实现需要添加 ...

  5. unity3d 加密资源并缓存加载

    原地址:http://www.cnblogs.com/88999660/archive/2013/04/10/3011912.html 首先要鄙视下unity3d的文档编写人员极度不负责任,到发帖为止 ...

  6. linux 如何清理僵尸进程

    今天在维护服务器的时候,发现有5个nova-novncproxy的僵尸进程. 26327 ?        S      0:05  \_ /usr/bin/python /usr/bin/nova- ...

  7. [原创]DELPHI木马DIY之生成服务端

    文章作者:上帝的禁区信息来源:邪恶八进制信息安全团队(www.eviloctal.com)DELPHI木马DIY之生成服务端   我在这里就生成简单的服务端,为什么不先讲服务端的隐藏?因为我觉得生成服 ...

  8. HDOJ 1875

    畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  9. ios 动态测定字符串frame : boundingRectWithSize函数

    用NSString中的一个方法,第一个参数是text形成的frame的最大的宽度和高度, 其中的options比较关键 CGSize labelSize = [text boundingRectWit ...

  10. Java for LeetCode 027 Remove Element

    Given an array and a value, remove all instances of that value in place and return the new length. T ...