Kinect 开发 —— 全息图
Kinect的另一个有趣的应用是伪全息图(pseudo-hologram)。3D图像可以根据人物在Kinect前面的各种位置进行倾斜和移动。如果方法够好,可以营造出3D控件中3D图像的效果,这样可以用来进行三维展示。因为WPF具有3D矢量绘图的功能。所以这一点使用WPF和Kinect比较容易实现。下图显示了一个可以根据观察者位置进行旋转和缩放的3D立方体。但是,只有一个观察者时才能运行。
使用Kinect SDK实现这一效果非常简单。Kinect已经在骨骼数据中提供了坐标点的以米为单位的X,Y和Z的值。比较困难的部分是,如何使用XAML创建一个3D矢量模型。在本例子中,我使用Blender这个工具,他是一个开源的3D模型建造工具,可以在www.blender.org网站上下载到。但是,要将3D网格曲面导出为XAML,需要为Blender安装一个插件。我使用的Blender版本是2.6,本身有这么一个功能,虽然有些限制。Dan Lehenbauer在CodePlex上也有针对Blender开发的导出Xmal的插件,但是只能在老版本的Blender上使用。
WPF中3D矢量图像的核心概念是Viewport3D对象。Viewport3D对象可以被认为是一个3D空间,在这个空间内,我们可以放置对象,光源和照相机。为了演示一个3D效果,我们创建一个新的名为KinectHologram项目,并添加对Microsoft.Kinect.dll的引用。在MainWindow的UI界面中,在root Grid对象下面创建一个新的ViewPort3D元素。下面的代码显示了一个立方体的代码。代码中唯一和Kinect进行交互的是Viewport3D照相机对象。因此很有必要对照相机对象进行命名。
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera" Position="-40,160,100" LookDirection="40,-160,-100"
UpDirection="0,1,0" />
</Viewport3D.Camera>
<ModelVisual3D x:Name="mainBox">
<ModelVisual3D.Transform>
<Transform3DGroup>
<TranslateTransform3D>
<TranslateTransform3D.OffsetY>10</TranslateTransform3D.OffsetY>
</TranslateTransform3D>
<ScaleTransform3D>
<ScaleTransform3D.ScaleZ>3</ScaleTransform3D.ScaleZ>
</ScaleTransform3D>
</Transform3DGroup>
</ModelVisual3D.Transform>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Color="White" Direction="-1,-1,-3" />
<GeometryModel3D >
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="1.000000,1.000000,-1.000000 1.000000,-1.000000,-1.000000 -1.000000,-1.000000,-1.000000 -1.000000,1.000000,-1.000000 1.000000,0.999999,1.000000 -1.000000,1.000000,1.000000 -1.000000,-1.000000,1.000000 0.999999,-1.000001,1.000000 1.000000,1.000000,-1.000000 1.000000,0.999999,1.000000 0.999999,-1.000001,1.000000 1.000000,-1.000000,-1.000000 1.000000,-1.000000,-1.000000 0.999999,-1.000001,1.000000 -1.000000,-1.000000,1.000000 -1.000000,-1.000000,-1.000000 -1.000000,-1.000000,-1.000000 -1.000000,-1.000000,1.000000 -1.000000,1.000000,1.000000 -1.000000,1.000000,-1.000000 1.000000,0.999999,1.000000 1.000000,1.000000,-1.000000 -1.000000,1.000000,-1.000000 -1.000000,1.000000,1.000000"
TriangleIndices="0,1,3 1,2,3 4,5,7 5,6,7 8,9,11 9,10,11 12,13,15 13,14,15 16,17,19 17,18,19 20,21,23 21,22,23"
Normals="0.000000,0.000000,-1.000000 0.000000,0.000000,-1.000000 0.000000,0.000000,-1.000000 0.000000,0.000000,-1.000000 0.000000,-0.000000,1.000000 0.000000,-0.000000,1.000000 0.000000,-0.000000,1.000000 0.000000,-0.000000,1.000000 1.000000,-0.000000,0.000000 1.000000,-0.000000,0.000000 1.000000,-0.000000,0.000000 1.000000,-0.000000,0.000000 -0.000000,-1.000000,-0.000000 -0.000000,-1.000000,-0.000000 -0.000000,-1.000000,-0.000000 -0.000000,-1.000000,-0.000000 -1.000000,0.000000,-0.000000 -1.000000,0.000000,-0.000000 -1.000000,0.000000,-0.000000 -1.000000,0.000000,-0.000000 0.000000,1.000000,0.000000 0.000000,1.000000,0.000000 0.000000,1.000000,0.000000 0.000000,1.000000,0.000000"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="blue"/>
</GeometryModel3D.Material> </GeometryModel3D>
<Model3DGroup.Transform>
<Transform3DGroup>
<Transform3DGroup.Children>
<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0.0935395359992981"/>
<ScaleTransform3D ScaleX="12.5608325004577637" ScaleY="12.5608322620391846" ScaleZ="12.5608325004577637"/>
</Transform3DGroup.Children>
</Transform3DGroup>
</Model3DGroup.Transform>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
上面的代码中,照相机对象(camera)有一个以X,Y,Z表示的位置属性。X从左至右增加。Y从下往上增加。Z随着屏幕所在平面,向靠近用户的方向增加。该对象还有一个观看方向,该方向和位置相反。在这里我们告诉照相机往后面的0,0,0坐标点看。最后,UpDirection表示照相机的朝向,在本例中,照相机向上朝向Y轴方向。
立方体使用一系列8个位置的值来绘制,每一个点都是三维坐标点。然后通过这些点绘制三角形切片来形成立方体的表面。在这之上我们添加一个Material对象然后将其颜色改为蓝色。然后给一个缩放变形使这个立方体看起来大一点。最后我们给这个立方体一些定向光源来产生一些3D的效果。
在后台代码中,我们只需要配置KienctSensor对象来支持骨骼追踪,如下代码所示。彩色影像和深度值影像在该项目中不需要用到。
KinectSensor _kinectSensor;
public MainWindow()
{
InitializeComponent();
this.Unloaded += delegate
{
_kinectSensor.DepthStream.Disable();
_kinectSensor.SkeletonStream.Disable();
}; this.Loaded += delegate
{
_kinectSensor = KinectSensor.KinectSensors[];
_kinectSensor.SkeletonFrameReady += SkeletonFrameReady;
_kinectSensor.DepthFrameReady += DepthFrameReady;
_kinectSensor.SkeletonStream.Enable();
_kinectSensor.DepthStream.Enable();
_kinectSensor.Start();
};
}
为了能够产生全息图的效果,我们将会围绕立方体来移动照相机的位置,而不是对立方体本身进行旋转。首先我们需要确定Kinect中是否有用户正在处于追踪状态。如果有一个,我们就忽略其他的。我们获取追踪到的骨骼数据并提取X,Y,Z坐标信息。因为Kinect提供的位置信息的单位是米,而我们的3D立方体不是的,所以需要将这些位置点信息进行一定的转换才能够产生3D效果。基于这些位置坐标,我们大概以正在追中的骨骼为中心来移动照相机。我们也用这些坐标,并将这些坐标翻转,使得照相机能够连续的指向0,0,0这个原点。
void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
float x=, y=, z = ;
//get angle of skeleton
using (var frame = e.OpenSkeletonFrame())
{
if (frame == null || frame.SkeletonArrayLength == )
return; var skeletons = new Skeleton[frame.SkeletonArrayLength];
frame.CopySkeletonDataTo(skeletons);
for (int s = ; s < skeletons.Length; s++)
{
if (skeletons[s].TrackingState == SkeletonTrackingState.Tracked)
{
border.BorderBrush = new SolidColorBrush(Colors.Red);
var skeleton = skeletons[s];
x = skeleton.Position.X * ;
z = skeleton.Position.Z * ;
y = skeleton.Position.Y;
break;
}
else
{
border.BorderBrush = new SolidColorBrush(Colors.Black);
} }
}
if (Math.Abs(x) > )
{
camera.Position = new System.Windows.Media.Media3D.Point3D(x, y , z);
camera.LookDirection = new System.Windows.Media.Media3D.Vector3D(-x, -y , -z);
}
}
有意思的是,这样产生全息图影像的效果比许多复杂的3D对象产生的全息图要好。3D立方体可以很容易的转换为矩形,如下图所示,只需要简单的将立方体在Z方向上进行拉伸即可。这个矩形朝向游戏者拉伸。我们可以简单的将立方体的UI这部分代码复制,然后创建一个新的modelVisual3D对象来产生新的矩形。使用变换来将这些矩形放X,Y轴上的不同位置,并给予不同的颜色。因为照相机是后台代码唯一需要关注的对象,在前台添加一个矩形对象及变换并不会影响代码的运行。
与Kinect相关的一些类库和工具在以后的几年,估计会更加多和Kienct SDK一起工作。当然,最重要的使人着迷的类库及工具有FAAST,Utility3D以及Microsoft Robotics Developer Studio。
FAAST(Flexible Action and Articulated Skeleton Toolkit)是一个中间件类库用来连接Kinect的手势交互界面和传统的人际交互界面。这个类库由南加利福利亚大学的创新技术研究院编写和维护。最初FAAST是使用OpenNI结合Kinect来编写的一个手势识别类库。这个类库真正优秀的地方在于它能够将大多数内建手势映射到其他API中,甚至能够将手势映射到键盘点击中来。这使得一些Kinect技术爱好者(hacker)能够使用这一工具来使用Kinect玩一些视频游戏,包括一些例如《使命召唤》(Call of Duty)的第一人称射击游戏,以及一些像《第二人生》(Second Life)和《魔兽世界》(World of Warcraft)这样的网络游戏。目前FAAST只有针对OpenNI版本,但是据最新的消息,FAAST现在正在针对KienctSDK进行开发,可以在其官网http://projects.ict.usc.edu/mxr/faast了解更多的相关信息。
Utility3D是一个工具,能够使得传统开发3D游戏的复杂工作变得相对简单,他有免费版和专业版之分。使用Uitltiy3D编写的游戏能够轻松的跨多种平台,包括web,windows,ios, iPhone,ipad,Android,Xbox,Playstation以及Wii。它也支持第三方插件,包括一些为Kinect开发的插件,使得开发者能够使用Kinect作为传感器来作为Windows游戏的输入设备。可以在Unity3D的官网查看更多信息http://unity3d.com。
Microsoft Robotics Developer Studio是微软针对机器人的开发平台,其最新发布的RDS4.0版本也集成了Kinect传感器。除了能够访问Kinect提供的功能,Kinect也支持一系列特定的基于Kinect的机器人平台,他们可以利用Kinect传感器进行障碍物避让。更多的有关Microsoft Robotics Developer Studio的信息可以访问http://www.microsoft.com/robotics。
Kinect 开发 —— 全息图的更多相关文章
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- Kinect开发资源汇总
Kinect开发资源汇总 转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- Kinect 开发 —— 杂一
Kinect 提供了非托管(C++)和托管(.NET)两种开发方式的SDK,如果您用C++开发的话,需要安装Speech Runtime(V11),Kinect for Windows Runtime ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
- Kinect 开发 —— 进阶指引(上)
本文将会介绍一些第三方类库如何来帮助处理Kinect传感器提供的数据.使用不同的技术进行Kinect开发,可以发掘出Kinect应用的强大功能.另一方面如果不使用这些为了特定处理目的而开发的一些类库, ...
- Kinect开发 —— 基础知识
转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...
- Kinect 开发 —— ColorBasic
创建一个Kincet项目通常需要: 1. 创建一个VS项目,一般为了展示通常创建一个wpf项目. 2. 添加Microsoft.Kinect.dll引用,如果是早期版本的SDK,这个名称可能不同. 3 ...
随机推荐
- 我照着NancyFx官网的demo来做为什么会有错误呢????
我照着NancyFx官网的demo来做为什么会有错误呢???? >> csharp这个答案描述的挺清楚的:http://www.goodpm.net/postreply/csharp/10 ...
- iOS-RAC学习笔记(一)——RACStream
RACStream是RACSignal和RACSequence的父类,定义了一些流的操作方法.从名字上可以看出来,这个对象就像流一样可以往任何一个出口流,同时也可以给这个流设计一道道关卡,改变流(这里 ...
- mongodb 的查询深入剖析
db.表名.find({goods_id:3}); //查询出 goods_id 为 3 的数据 db.表名.find({cat_i ...
- js利用点击事件做一个简单的计算器
先放一个样式图: 源代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...
- [HNOI2018]爆零记
Day 0 完全不知道做什么. 打了一个splay板子,还没调出来emmmmm 不想做题目,最后做的一题是[HNOI2016]的超(sha)难(bi)题网络. 当我希望省选能出一下树剖时,旁边的大佬跟 ...
- Eclipse StartExplorer插件
http://www.cnblogs.com/wuxiang/p/5489961.html
- ArcGIS api for javascript——图形-选择一个范围内的点
描述 本例展示了如何使用图形显示查询结果,如何使用draw toolbar在地图上选择图形和如何修改图形符号为“高亮”. 在地图上画一个矩形区域,加亮矩形范围内的城市.这个应用统计高亮的城市个数并列出 ...
- MYSQL 更新时间自己主动同步与创建时间默认值共存问题
本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50326259 在使用SQL的时候,希望在更新数据的时候自己主动填充 ...
- [Recompose] Stream Props to React Children with RxJS
You can decouple the parent stream Component from the mapped React Component by using props.children ...
- 使用spring-loaded开源项目,实现java程序和web应用的热部署
JDK1.5之后提供了java.lang.instrument.Instrumentation,即java agent机制可以实现类的redefinition和retransform. redefin ...