SDK1.5中新增了人脸识别类库:Microsoft.Kinect.Toolkit.FaceTracking使得在Kinect中进行人脸识别变得简单,该类库的源代码也在Developer Toolkit中。在Developer Toolkit中也自带人脸识别的例子,您也可以打开运行或者查看源代码。


开发前准备

要使用面部追踪功能,Kinect SDK版本应该至少是1.5,最新版本为1.6,您可以参考之前的那篇文章下载安装,Kinect SDK 和 Kinect Developer Toolkit要一起安装,我的机器上装的是最新的SDK1.6版本。

安装Kinect Developer Toolkit会安装Kinect Studio、一些C#/VB.Net/C++的应用程序示例、源码以及两个用于面部追踪的类库FaceTrackData.dll ,FaceTrackLib.dll包括32位和64位版本,安装好了之后,这些dll应该都在该目录下面 :

如果用C++开发的话,可以直接在项目中使用着两个dll,否则,如果使用.NET开发的话,还需要将这些dll包装成托管代码。

幸运的是, Developer Toolkit中提供了两个使用.NET来实现面部追踪的代码,我们可以直接使用其替我们包装好了dll,该类库的源码也可以看到。 打开Developer Toolkit Browser 找到Component示例,然后安装,之后浏览所在目录,应该能够找到下面两个dll,不安装也可以,您也可以直接到SDK目录中查找这两个dll,在我的及其上目录为C:\Program Files\Microsoft SDKs\Kinect\Developer Toolkit v1.6.0\Samples\bin:

  • Microsoft.Kinect.Toolkit
  • Microsoft.Kinect.Toolkit.FaceTracking

这两个dll的源码可以在示例中找到,引用了这两个dll之后,还需要将FaceTrackData.dll和FaceTrackLib.dll拷贝到项目中,并保证他和exe在同一个目录下面。


创建WPF项目

新建一个名为KinectFaceTracking的WPF项目,然后引用Microsoft.Kinect ,Microsoft.Kinect.Toolkit.FaceTracking 和Microsoft.Kinect.Toolkit这三个dll

要使用面部追踪,在开启KinectSensor之后需要启用ColorImageStream,  DepthImageStream 和SkeletonStream这三个Stream,部分代码如下:

//启用必要的三个Stream
kinectSensor.ColorStream.Enable();
kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution80x60Fps30);kinectSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters() { Correction = 0.5f, JitterRadius = 0.05f, MaxDeviationRadius = 0.05f, Prediction = 0.5f, Smoothing = 0.5f });// 监听流事件.
kinectSensor.AllFramesReady +=kinectSensor_AllFramesReady;// 初始化数据
colorPixelData = new byte[kinectSensor.ColorStream.FramePixelDataLength];
depthPixelData = new short[kinectSensor.DepthStream.FramePixelDataLength];
skeletonData = new Skeleton[6];//打开Kinect
kinectSensor.Start();//初始化人脸识别
faceTracker = new FaceTracker(kinectSensor);

前面的代码应该都好懂,值得一提的是最后一句,初始化FaceTracker 对象。在初始化景深数据流时,我们使用最低分辨率的景深影像数据流,这样fps会更高,使得结果更加流畅. 最后,我们注册了AllFramesReady事件。


获取面部数据

在Developer Toolkit中,脸部数据帧使用FaceTrackFrame表示。 为了获取数据,我们需要调用FaceTracker对象的Track方法并传入我们从Kinect中获取的数据,然后FaceTracker对象会对这些数据进行处理来进行面部追踪,部分代码如下:

// 获取每一帧数据,然后存储到变量中来
using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
{if (colorImageFrame == null)return;colorImageFrame.CopyPixelDataTo(colorPixelData);
}using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
{if (depthImageFrame == null)return;depthImageFrame.CopyPixelDataTo(depthPixelData);
}using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{if (skeletonFrame == null)return;skeletonFrame.CopySkeletonDataTo(skeletonData);
}//获取处于跟踪状态的骨骼数据对象,如果没有,则返回.
var skeleton = skeletonData.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked);
if (skeleton == null)return;

前面的都是数据准备阶段,一旦数据都获取了之后,我们使用FaceTracker对象来对这些数据进行识别,提取面部信息。

// 面部追踪
FaceTrackFrame faceFrame = faceTracker.Track(kinectSensor.ColorStream.Format, colorPixelData,kinectSensor.DepthStream.Format, depthPixelData,skeleton);

faceFrame是一个FaceTrackFrame类型的变量,代表面部追踪的处理结果,该对象的更详细信息,您可以查看 MSDN ,下面是该对象的OMD图

首先,TrackSuccessful 属性只是是否识别出了面部,FaceRect是面部所在的矩形区域,最重要的是下面的几个方法:这些方法可以提供最多87个点来表示面部信息,这些点可以以二维或者三维的形式提供。我们可以提取一些用户的面部表情信息:

  • Get3DShape() 方法返回三维表示的121个点集合.
  • GetProjected3DShape() 方法返回同样数目的以二维形式展现的点的集合,这些点映射到640×480像素的图像上.
  • GetAnimationUnitCoefficients()  返回面部表情的描述值,在下面我们会用到这个值来绘制人物图像.更多的信息,您可以查看 Animation Units on MSDN.
  • GetTriangles() 该方法可以 和Get3DShape 方法一起使用. 他返回一个三角形集合,集合中的每个三角形的顶点都是由Get3DShape 中的点组成。这些三角形可以用来进行3D建模,就像Developer Toolkit自带例子中的那样,我们可以用它来对整个面部进行动态建模。

绘制面部

有了数据之后,我们可以在WPF中用XAML来绘制一个简单的人脸了。在绘制过程中,我们会使用一些变换Transformations (Translations, Rotations, Scales, …) 来表示人的表情的变化,比如说RenderTransform对象可以用来改变对象的渲染方式,我们使用一个Ellipse 对象来代表嘴巴 (Ellipse with x:Name=”Mouth”) :他有一个 ScaleTransform属性,我们可以使用它来改变X轴和Y轴上的缩放,来模拟口型的变化,眉头的模拟也是如此。

<Window x:Class="KinectFaceTracking.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><Grid><Grid><Canvas x:Name="MainCanvas" Width="500" Height="500"><Canvas.RenderTransform><TransformGroup><RotateTransform x:Name="CanvasRotate" CenterX="250" CenterY="250" /><!--<TranslateTransform x:Name="CanvasTranslate" />--></TransformGroup></Canvas.RenderTransform><Ellipse Width="300" Height="300" x:Name="Face"  StrokeThickness="2" Stroke="Black" Canvas.Left="105" Canvas.Top="6" /><Ellipse Width="30" Height="30" x:Name="LeftEye" Stroke="Black" StrokeThickness="2" Canvas.Left="289" Canvas.Top="102" /><Ellipse Canvas.Left="194" Canvas.Top="102" x:Name="RightEye" Height="30" Stroke="Black" StrokeThickness="2" Width="30" /><Ellipse Canvas.Left="224" Canvas.Top="239" Height="18" x:Name="Mouth" Stroke="Black" StrokeThickness="2" Width="64" ><Ellipse.RenderTransform><ScaleTransform x:Name="MouthScaleTransform" CenterX="32" CenterY="9" ScaleX="1" ScaleY="1"/></Ellipse.RenderTransform></Ellipse><!--<Ellipse Canvas.Left="244" Canvas.Top="151" Height="53" x:Name="Nose" Stroke="Black" StrokeThickness="2" Width="22" />--><Rectangle Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="169" Canvas.Top="80"><Rectangle.RenderTransform><TransformGroup><TranslateTransform x:Name="RightBrow" /><RotateTransform x:Name="RightBrowRotate" CenterX="50" Angle="0" /></TransformGroup></Rectangle.RenderTransform></Rectangle><Rectangle  Width="70" Stroke="Black" Fill="Black" StrokeThickness="10" Height="5" Canvas.Left="274" Canvas.Top="80" ><Rectangle.RenderTransform><TransformGroup><TranslateTransform x:Name="LeftBrow" /><RotateTransform x:Name="LeftBrowRotate" CenterX="20" Angle="0" /></TransformGroup></Rectangle.RenderTransform></Rectangle><Rectangle Canvas.Left="207" Canvas.Top="148" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="50"><Rectangle.RenderTransform><TransformGroup><RotateTransform Angle="-70" CenterX="50" /></TransformGroup></Rectangle.RenderTransform></Rectangle><Rectangle Canvas.Left="246" Canvas.Top="190" Fill="Black" Height="5" Stroke="Black" StrokeThickness="10" Width="15"><Rectangle.RenderTransform><TransformGroup><RotateTransform Angle="0" CenterX="50" /></TransformGroup></Rectangle.RenderTransform></Rectangle></Canvas></Grid></Grid>
</Window>

完成之后,一个简单的人脸就绘制完成了,如下:


将数据和表情绑定

现在表情绘制完成,我们只需要使用面部追踪的数据来改变各部分的动画参数就可以模拟脸部表情了。

获取数据之前,我们需要检查是否识别出来了脸部。如果识别出来人脸,我们就接着获取动画单位系数(Animation Units coefficients). 这个参数可以告诉哦我们被追踪对象嘴巴是张开还是合拢,还是在笑,眉头紧锁还是笑颜逐开等等…

//如果识别出来,进行进一步处理
if (faceFrame.TrackSuccessful)
{// 获取动画单位系数 Animation Units coeffs.var AUCoeff = faceFrame.GetAnimationUnitCoefficients();var jawLowerer = AUCoeff[AnimationUnit.JawLower];jawLowerer = jawLowerer < 0 ? 0 : jawLowerer;MouthScaleTransform.ScaleY = jawLowerer * 5 + 0.1;MouthScaleTransform.ScaleX = (AUCoeff[AnimationUnit.LipStretcher] + 1);LeftBrow.Y = RightBrow.Y = (AUCoeff[AnimationUnit.BrowLower]) * 40;RightBrowRotate.Angle = (AUCoeff[AnimationUnit.BrowRaiser] * 20);LeftBrowRotate.Angle = -RightBrowRotate.Angle;CanvasRotate.Angle = faceFrame.Rotation.Z;}

上面的动画参数的取值范围都是在-1和1之间。到这里一个简单的面部追踪小程序就完成了,您可以对着Kinect做一些表情试一试变化。下面是我做的一些截图:

转载于:https://www.cnblogs.com/sprint1989/p/3862424.html

Kinect 开发 —— 面部追踪相关推荐

  1. Kinect开发笔记之二Kinect for Windows 2.0新特性

    这是本博客的第一篇翻译文档,笔者已经苦逼的竭尽全力的在翻译了,但无奈英语水平也是很有限,不对或者不妥当不准确的地方必然会有,还恳请大家留言或者邮件我以批评指正,我会虚心接受.谢谢大家.         ...

  2. 体感(Kinect)开发要点总结一

    体感(Kinect)开发要点总结一 Kinect有两类摄像头,近红外摄像头和普通的视频摄像头.视频摄像头提供了一般摄像头类似的彩色影像.       Kinect的彩色摄像头默认每秒产生30副Colo ...

  3. Kinect开发学习笔记之(七)骨骼数据的提取

    Kinect开发学习笔记之(七)骨骼数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7x86 + VS2010 ...

  4. Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取

    Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7x86 + ...

  5. Kinect开发学习笔记之(四)提取颜色数据并用OpenCV显示

    Kinect开发学习笔记之(四)提取颜色数据并用OpenCV显示 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7 x86 ...

  6. VR成为下一代计算平台的关键技术:面部追踪

    即使你是一个真正的VR铁粉,你也得必须承认现在的头显永远不会被大众接受.因为现在虚拟现实意味着被捆绑到一台昂贵的个人电脑上,在一个监护系统的"牢房"里行动.这并不是我们理想中的虚拟 ...

  7. Kinect开发学习笔记之(五)不带游戏者ID的深度数据的提取

    Kinect开发学习笔记之(五)不带游戏者ID的深度数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7 x86 ...

  8. Kinect开发之结合Unity3D进行游戏应用开发

    转自:http://yacare.iteye.com/blog/1950164 最近在用unity3d和Kinect结合开发一个项目,突然间发现了这个博客,感觉其中的Unity3d包太厉害了,挺有意思 ...

  9. unity怎么实现人脸追踪_Unity 2019.2 beta为AR增加面部追踪、2D图像追踪、3D对象追踪等功能...

    Unity今天正式放出了Unity 2019.2 beta.对于这个版本,Unity集成了热门的Polybrush工具,添加了Unity Distribution Platform,同时扩展了用于XR ...

  10. Kinect开发资源汇总

    Kinect开发资源汇总   转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...

最新文章

  1. 处理问题:变量名‘@UserName’已声明。变量名在插叙批次或存储过程内部必须唯一
  2. 读写App.config配置文件的方法
  3. (53)进程结构体EPROCESS,擦除 DebugPort 实现反调试,ActiveProcessLinks 断链实现进程隐藏
  4. java file ip_java常用工具类 IP、File文件工具类
  5. feign rest_与Feign客户轻松进行REST通信
  6. 线上电商年货节,PSD分层模板,让“年味”触手可及~
  7. plpgsql语句的兼容性
  8. 《重回耶路撒冷——犹太人的三千年》(Return to Jerusalem)读后感
  9. 利用交换机搭建局域网并实现PC机或者带网口设备的通信
  10. Linux之分析bin文件的10种方法
  11. 王小九用计算机弹桥边姑娘,抖音最火歌曲是哪首?QQ音乐开放平台《桥边姑娘》让“野狼”靠边站...
  12. Google play aso 关键词覆盖指南
  13. 骨传导耳机靠谱吗?骨传导耳机是不是智商税?
  14. javamail QQ邮箱发验证码设定有效时间
  15. 2020年计算机系毕业人数,2020年中国大学生各专业就业报告出炉:计算机类专业月薪最高!...
  16. 2020.09.19【普及组】模拟赛C组总结
  17. 嵌入式软件开发笔试面试知识点总结-操作系统部分
  18. 微信小程序获取当前页面url
  19. 后台数据不清理android,android 后台被数据清理后切换到前台数据丢失问题
  20. 关于短信内容格式及压缩方法

热门文章

  1. VS编译错误与链接错误汇总
  2. java访问控制关键字_Java 访问控制关键字
  3. osql 登陆mysql_命令行登录mysql报Segmentation fault故障解决
  4. 润乾报表分组求和_中国式复杂报表:按段分组报表制作对比(润乾 vs 帆软)...
  5. 谁设计python_如果你有设计师朋友,请对TA好一些...
  6. git刷新分支列表_如何使用Git小技巧让你开发协作过程更加顺利?
  7. android 背景逐渐变暗,UI:使View背景逐渐变暗的方法
  8. Java进阶:SpringMVC中自定义类型转换器
  9. 正则表达式:基础知识学习
  10. linux远程控制本地用户登录,linux 本地无法登录 远程可以登陆的解决办法