【搬运+翻译】WIn10 周年更新 1607 尝试运用 UWP 中对 Kinect For Windows V2 的新支持( Windows 10, 1607, UWP and Experimenting with the Kinect for Windows V2 Update )
原文链接:
Windows 10, 1607, UWP and Experimenting with the Kinect for Windows V2 Update
注:有些配图根据我个人电脑(XPS15-9550)上运行情况重新截取。
译文保留所有权
看到官方这篇博客我很兴奋
它向诸位 UWP 开发者宣布了一个好消息,Windows 10 周年更新 增强了对 Kinect For Windows V2 的支持。
十个月前 UWP 刚支持一些基础功能时作者写过一篇短文
很高兴现在有更多功能可以在 UWP 上实现,特别是 骨骼数据 skeletal data
将 Kinect For Windows V2 连接至 我的 Surface Pro 3 上,打开设备管理面板,找到 Kinect 相关的驱动

请确保你的驱动版本不低于 【2.2.1610.17001】 如果低于该版本号可直接用系统自带的驱动更新来检查更新驱动日期是一个多月之前,可能这是该驱动的编译完成日期
然后去下载微软在 GitHub 上发布的一个 C++ 样例
接着在我的 Surface Pro 3 上编译并运行,可以看到一开始获取了我设备上的后置摄像头源信息

然后点击 "下一个" 按钮显示说是 Intel RealSense Camera 信息【注:Sp3 并不带有因特尔的实感摄像头,但 SP4 确是有的,这里估计是微软乱推送驱动导致的】

当我再次点击 "下一个" 按钮时,程序卡住了,由于我不确定 RealSense Camera 在我设备上的运行状态,所以我将它的驱动禁用

接着重新运行样例,这次可以获取到 Kinect 的传感器源了,将 "Toggle Depth Fading" 选项关闭 "Toggle Skeletal Overlay" 选项打开
这时候在画面之上用颜色标记出了一个(平面的)骨骼信息,并且显示得非常流畅

很高兴可以看到这一切都是可行的。由于这段代码是由 C++ 编写的,所以我想知道 如果一个用 C# 开发 UWP 的程序员来写这个功能会怎么样实现,也许以后会在这里附上相关代码。
【然后博主就来贴代码啦!】
====================================================分割线======================================================
在由 C# 编写的 UWP 程序里获取骨骼数据
我用之前的一篇博客中所提到的代码来新建一个新的项目
先是创建一个目标 SDK 为 14393 的空项目,然后确保它拥有 网络摄像头 和 麦克风的使用权限,然后添加 Win2d.UWP 的 NuGet 环境包。
1 <Page 2 x:Class="KinectTestApp.MainPage" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="using:KinectTestApp" 6 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 xmlns:w2d="using:Microsoft.Graphics.Canvas.UI.Xaml" 9 mc:Ignorable="d"> 10 11 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 12 <TextBlock 13 FontSize="36" 14 HorizontalAlignment="Center" 15 VerticalAlignment="Center" 16 TextAlignment="Center" 17 Text="No Cameras" /> 18 <w2d:CanvasControl 19 x:Name="canvasControl" 20 Visibility="Collapsed" 21 SizeChanged="OnCanvasControlSizeChanged" 22 Draw="OnDraw"/> 23 </Grid> 24 </Page>
我想做出仅通过 Kinect 传感器获取色彩并在其上方加上骨骼节点的效果
我通过参考官方样例,发现他并没有使用 WinRT 组件而是用了一个引用(PoseTrackingPreview)来转换从 Kinect 所获取的 MediaFrameReference 信息,所以我也将这个引用添加进了我的 C# 项目中,这个引用 在这里 看上去想要保持它的独立运行性,我是这样在项目中对它进行引用的(将 Git 上的代码连同文件夹一同复制到你自己的项目解决方案目录下,然后右击项目解决方案添加现有项目,然后点击 C# 代码部分的引用 选择 "项目" "解决方案" 然后勾选右侧的 PoseTrackingPreview 即完成了引用)

然后就可以尝试写一些代码来获取色彩数据和骨骼数据以便显示在屏幕上
我用 mt* 前缀标记出所有自己所写的类,以便于和官方样例或者框架所写的区分开来
这个类实现了位图的传递
1 namespace KinectTestApp 2 { 3 using System; 4 using Windows.Graphics.Imaging; 5 6 class mtSoftwareBitmapEventArgs : EventArgs 7 { 8 public SoftwareBitmap Bitmap { get; set; } 9 } 10 }
这个类实现了绘制骨骼数据
1 namespace KinectTestApp 2 { 3 using System; 4 5 class mtPoseTrackingFrameEventArgs : EventArgs 6 { 7 public mtPoseTrackingDetails[] PoseEntries { get; set; } 8 } 9 }
用一个简单的数组把传感器获取的 被追踪的 使用者信息保存
1 namespace KinectTestApp 2 { 3 using System; 4 using System.Linq; 5 using System.Numerics; 6 using Windows.Foundation; 7 using Windows.Media.Devices.Core; 8 using WindowsPreview.Media.Capture.Frames; 9 10 class mtPoseTrackingDetails 11 { 12 public Guid EntityId { get; set; } 13 public Point[] Points { get; set; } 14 15 public static mtPoseTrackingDetails FromPoseTrackingEntity( 16 PoseTrackingEntity poseTrackingEntity, 17 CameraIntrinsics colorIntrinsics, 18 Matrix4x4 depthColorTransform) 19 { 20 mtPoseTrackingDetails details = null; 21 22 var poses = new TrackedPose[poseTrackingEntity.PosesCount]; 23 poseTrackingEntity.GetPoses(poses); 24 25 var points = new Point[poses.Length]; 26 27 colorIntrinsics.ProjectManyOntoFrame( 28 poses.Select(p => Multiply(depthColorTransform, p.Position)).ToArray(), 29 points); 30 31 details = new mtPoseTrackingDetails() 32 { 33 EntityId = poseTrackingEntity.EntityId, 34 Points = points 35 }; 36 return (details); 37 } 38 static Vector3 Multiply(Matrix4x4 matrix, Vector3 position) 39 { 40 return (new Vector3( 41 position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31 + matrix.M41, 42 position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32 + matrix.M42, 43 position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33 + matrix.M43)); 44 } 45 } 46 }
这个类运用了 全局唯一标识符(GUID)来识别并分辨被追踪的用户,然后用 Point 类型的数组来存储每个被追踪用户的骨骼节点信息,接着我想让这些 2D 的 节点 利用深度信息来映射对应的 色彩空间 内的颜色。
【未完成!】

浙公网安备 33010602011771号