需要引入的dll:

需要将下面两个dll复制到当前路径

Kinect for windows提供了脸部识别的功能,可以识出人脸。主要是通过FaceTrackFrame类的GetTriangles()来得到一个三角形数组,这个三角形数组就是给成人面部的基本形状,并且组成的效果是立体的(可以这样理解,可以把3D都拆成三角形来表示,看上去像3D,但其实是2D),这个数组的每个元素都存放着三个整数,分别代码三角形的第一个点,第二个点和第三个点。FaceTrackFrame的GetProjected3DShape方法,可以获取一组坐标信息,这样就可以结合三角形数组元素中的点作为索引,从本方法的坐标集合中取出每个三角形的坐标点来了,就可以绘制这些三角形,就可以组成一个人脸的网络3D效果图了。

本例是从色彩摄像头中获取彩色数据流,并显示到窗体上,再通过FaceTracker得到得到脸部3D信息,并用GDI+的方式把网络图形画到窗体上,这时就可以在真实图像上看到浮着一张网络的面套。同时可以得出脸部交汇最多的坐标,并用GDI+添加上不同有色彩,同时还可以得到人体面部和Kinect 正面的偏差,即人头是否竖直,有没有偏上一边等角度信息。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;  using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit;
using Microsoft.Kinect.Toolkit.FaceTracking;
using System.Threading;
using System.IO;
using System.Drawing.Imaging;  namespace Face
{  public partial class Form1 : Form  {  public Form1()  {  InitializeComponent();  }  KinectSensor ks = null;  private void Form1_Load(object sender, EventArgs e)  {  //让winform窗体刷新不闪动  this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);  this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);  this.SetStyle(ControlStyles.UserPaint, true);  this.SetStyle(ControlStyles.DoubleBuffer, true);  //找到连接的Kinect设备  foreach (var ks in KinectSensor.KinectSensors)  {  if (ks.Status == KinectStatus.Connected)  {  this.ks = ks;  }  }  //开启色彩流,深度流,骨骼流的跟踪  if (this.ks != null)  {  this.ks.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);  this.ks.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);  this.ks.DepthStream.Range = DepthRange.Near;  this.ks.SkeletonStream.EnableTrackingInNearRange = true;  this.ks.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;  this.ks.SkeletonStream.Enable();  //订阅跟踪数据读取事件  this.ks.AllFramesReady += OnAllFramesReady;  ks.Start();  }  }  //这个方法很重要,就是重绘人脸跟踪采集到的数据  protected override void OnPaint(PaintEventArgs e)  {  base.OnPaint(e);  foreach (SkeletonFaceTracker faceInformation in this.trackedSkeletons.Values)  {  //第一个参数为当前窗体为画布,第二个是添加采集到的信息到listbox中,这个方法画识别到脸部的信息
                faceInformation.DrawFaceModel(e.Graphics, Messbox_LB);  }  }  //定义脸部识别的集合  private readonly Dictionary<int, SkeletonFaceTracker> trackedSkeletons = new Dictionary<int, SkeletonFaceTracker>();  //色彩流字节数组  private byte[] colorImage;  private ColorImageFormat colorImageFormat = ColorImageFormat.Undefined;  //深度流字节数组  private short[] depthImage;  private DepthImageFormat depthImageFormat = DepthImageFormat.Undefined;  //骨骼信息数组  private Skeleton[] skeletonData;  private void OnAllFramesReady(object sender, AllFramesReadyEventArgs allFramesReadyEventArgs)  {  ColorImageFrame colorImageFrame = null;  DepthImageFrame depthImageFrame = null;  SkeletonFrame skeletonFrame = null;  try {  colorImageFrame = allFramesReadyEventArgs.OpenColorImageFrame();     //接到色彩流对框架  depthImageFrame = allFramesReadyEventArgs.OpenDepthImageFrame();     //接到深度流对框架  skeletonFrame = allFramesReadyEventArgs.OpenSkeletonFrame();     //接到骨骼流对框架  if (colorImageFrame == null || depthImageFrame == null || skeletonFrame == null)  {  return;  }  if (this.depthImageFormat != depthImageFrame.Format)  {  this.ResetFaceTracking();  this.depthImage = null;  this.depthImageFormat = depthImageFrame.Format;  }  if (this.colorImageFormat != colorImageFrame.Format)  {  this.ResetFaceTracking();  this.colorImage = null;  this.colorImageFormat = colorImageFrame.Format;  }  if (this.depthImage == null)  {  this.depthImage = new short[depthImageFrame.PixelDataLength];  }  if (this.colorImage == null)  {  this.colorImage = new byte[colorImageFrame.PixelDataLength];  }  if (this.skeletonData == null || this.skeletonData.Length != skeletonFrame.SkeletonArrayLength)  {  this.skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];  }  //获取各种数据流信息  colorImageFrame.CopyPixelDataTo(this.colorImage);  depthImageFrame.CopyPixelDataTo(this.depthImage);  skeletonFrame.CopySkeletonDataTo(this.skeletonData);  //清空列表信息
                Messbox_LB.Items.Clear();  //编历骨骼流  foreach (Skeleton skeleton in this.skeletonData)  {  //找到有效的骨骼信息  if (skeleton.TrackingState == SkeletonTrackingState.Tracked  || skeleton.TrackingState == SkeletonTrackingState.PositionOnly)  {  if (!this.trackedSkeletons.ContainsKey(skeleton.TrackingId))  {  //添加骨骼信息到集合中  this.trackedSkeletons.Add(skeleton.TrackingId, new SkeletonFaceTracker());  }  // 得到脸部识别对象
                        SkeletonFaceTracker skeletonFaceTracker;  if (this.trackedSkeletons.TryGetValue(skeleton.TrackingId, out skeletonFaceTracker))  {  //把获取的数据流的相关信息传给OnFrameReady方法  skeletonFaceTracker.OnFrameReady(Messbox_LB, this.ks, colorImageFormat, colorImage, depthImageFormat, depthImage, skeleton);  skeletonFaceTracker.LastTrackedFrame = skeletonFrame.FrameNumber;  }  }  }  //这个刷新会触发窗体的重画,OnPaint方法会被调用。  this.Refresh();  //把色彩流转转成位图显示成窗体的背景  this.BackgroundImage = ToGrayBitmap(colorImage, 640, 480);  }  finally {  if (colorImageFrame != null)  {  colorImageFrame.Dispose();  }  if (depthImageFrame != null)  {  depthImageFrame.Dispose();  }  if (skeletonFrame != null)  {  skeletonFrame.Dispose();  }  }  }  //把色采流数据转成位图返回  public static Bitmap ToGrayBitmap(byte[] rawValues, int width, int height)  {  //定议转换图片的格式,一个像素占32个,前24位为红绿蓝,后8位为空  PixelFormat pf = PixelFormat.Format32bppRgb;  //申请目标位图的变量  Bitmap bmp = new Bitmap(width, height, pf);  //将其内存区域锁定   BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, pf);  //获取位图的起始地址  IntPtr iptr = bmpData.Scan0;  //用Marshal的Copy方法,将色彩流字节数组复制到BitmapData中   System.Runtime.InteropServices.Marshal.Copy(rawValues, 0, iptr, rawValues.Length);  //释放锁
            bmp.UnlockBits(bmpData);  return bmp;  }  //重新设置识别对象  private void ResetFaceTracking()  {  foreach (int trackingId in new List<int>(this.trackedSkeletons.Keys))  {  this.RemoveTracker(trackingId);  }  }  //从集合中移动识别信息  private void RemoveTracker(int trackingId)  {  this.trackedSkeletons[trackingId].Dispose();  this.trackedSkeletons.Remove(trackingId);  }  private void Form1_FormClosing(object sender, FormClosingEventArgs e)  {  if (this.ks.Status == KinectStatus.Connected)  {  ks.Stop();  }  }  //定义脸识别类  class SkeletonFaceTracker : IDisposable  {  //定义脸部识别形状三角形数组  private static FaceTriangle[] faceTriangles;  //脸部识别坐标点集合  private EnumIndexableCollection<FeaturePoint, Microsoft.Kinect.Toolkit.FaceTracking.PointF> facePoints;  //脸部跟踪类  private FaceTracker faceTracker;  //定义识别成功标识  private bool lastFaceTrackSucceeded;  //骨骼跟踪状态  private SkeletonTrackingState skeletonTrackingState;  public int LastTrackedFrame { get; set; }  public void Dispose()  {  if (this.faceTracker != null)  {  this.faceTracker.Dispose();  this.faceTracker = null;  }  }  //用来把识别的信息绘制出来  public void DrawFaceModel(Graphics graphics, ListBox lb)  {  if (!this.lastFaceTrackSucceeded || this.skeletonTrackingState != SkeletonTrackingState.Tracked)  {  return;  }  List<System.Drawing.PointF> faceModelPts = new List<System.Drawing.PointF>();  for (int i = 0; i < this.facePoints.Count; i++)  {  faceModelPts.Add(new System.Drawing.PointF(this.facePoints[i].X + 0.5f, this.facePoints[i].Y + 0.5f));  }  System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Green);  List<System.Drawing.PointF> list = new List<System.Drawing.PointF>();  //遍历所有的三角形,分别画三角形  for (int i = 0; i < faceTriangles.Count(); i++)  {  System.Drawing.PointF[] pointFarr = new System.Drawing.PointF[4];  pointFarr[0] = faceModelPts[faceTriangles[i].First];  pointFarr[1] = faceModelPts[faceTriangles[i].Second];  pointFarr[2] = faceModelPts[faceTriangles[i].Third];  pointFarr[3] = faceModelPts[faceTriangles[i].First];  list.AddRange(pointFarr.Take(3));  graphics.DrawLines(pen, pointFarr);  }  lb.Items.Add(list.GroupBy(f => f).Count() + "点");  int count = list.GroupBy(f => f).Max(s => s.Count());  lb.Items.Add(count);  foreach (var v in list.GroupBy(f => f).Where(s => s.Count() == 10))  {  lb.Items.Add(v.Key + " " + 10);  graphics.FillEllipse(new SolidBrush(System.Drawing.Color.Red), v.Key.X, v.Key.Y, 5, 5);  }  foreach (var v in list.GroupBy(f => f).Where(s => s.Count() == 9))  {  lb.Items.Add(v.Key + " " + 9);  graphics.FillEllipse(new SolidBrush(System.Drawing.Color.Blue), v.Key.X, v.Key.Y, 5, 5);  }  foreach (var v in list.GroupBy(f => f).Where(s => s.Count() == 8))  {  lb.Items.Add(v.Key + " " + 8);  graphics.FillEllipse(new SolidBrush(System.Drawing.Color.Black), v.Key.X, v.Key.Y, 5, 5);  }  }  /// <summary>  /// 数据更新的方法  /// </summary>  internal void OnFrameReady(ListBox lb, KinectSensor kinectSensor, ColorImageFormat colorImageFormat, byte[] colorImage, DepthImageFormat depthImageFormat, short[] depthImage, Skeleton skeletonOfInterest)  {  this.skeletonTrackingState = skeletonOfInterest.TrackingState;  //判断是否为跟踪状态  if (this.skeletonTrackingState != SkeletonTrackingState.Tracked)  {  return;  }  if (this.faceTracker == null)  {  try {  //从KinectSensor中实例化出一个脸部识别对象  this.faceTracker = new FaceTracker(kinectSensor);  }  catch (InvalidOperationException)  {  this.faceTracker = null;  }  }  if (this.faceTracker != null)  {  //从脸部识别对象中得到脸识别框架  FaceTrackFrame frame = this.faceTracker.Track(  colorImageFormat, colorImage, depthImageFormat, depthImage, skeletonOfInterest);  //标识识别成功  this.lastFaceTrackSucceeded = frame.TrackSuccessful;  if (this.lastFaceTrackSucceeded)  {  if (faceTriangles == null)  {  //得到脸部识别三角形数组  faceTriangles = frame.GetTriangles();  }  //得到脸部识别点的坐标  this.facePoints = frame.GetProjected3DShape();  //加载脸部的空间位置
 lb.Items.Add("Rotation   仰低头:" + frame.Rotation.X);  lb.Items.Add("Rotation   左右转头:" + frame.Rotation.Y);  lb.Items.Add("Rotation   左右偏头:" + frame.Rotation.Z);  }  }  }  }  }  }
}

转载于:https://www.cnblogs.com/shouhouxiaomuwu/p/3389541.html

Kinect for windows的脸部识别相关推荐

  1. 深入理解Kinect for Windows开发

    ----微软Build2012大会:Kinect for Windows Programming Deep Dive 这个周末看了两天的微软Build 2012大会,真的是一次盛会,上面有很多的演讲主 ...

  2. Kinect for Windows SDK发布

    转载请注明出处为KlayGE游戏引擎,本文地址为http://www.klayge.org/2011/06/17/kinect-for-windows-sdk%e5%8f%91%e5%b8%83/ 前 ...

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

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

  4. 更多 Kinect for Windows 项目揭示

    虽然Kinect for Windows的发布不过才过去一个月而已,但是到目前为止这个Xbox 360游戏设备辅助产品似乎已经赶上了一些商业企业项目了.其中包括一个让机器人自动购物车成为现实的项目.在 ...

  5. [译]Kinect for Windows SDK开发入门(二):基础知识 上

    上篇文章介绍了Kinect开发的环境配置,这篇文章和下一篇文章将介绍Kinect开发的基本知识,为深入研究Kinect for Windows SDK做好基础. 每一个Kinect应用都有一些基本元素 ...

  6. [译]Kinect for Windows SDK开发入门(八):骨骼追踪进阶 上

    前7篇文件我们介绍了Kinect SDK中各种传感器的各种基本知识,我们用实验的方式演示了这些基本对象和方法的如何使用,这些都是Kinect开发最基本的知识.了解了这些基本知识后,就可以开发出一个基于 ...

  7. Kinect for Windows v2.0安装教程

    Kinect for Windows v2.0安装教程 根据官方教程,Kinect v2.0支持Windows 8/8.1/10,本教程讲述在Windows 10上的安装. 打开浏览器,百度搜索--K ...

  8. Kinect for Windows Samples

    Kinect for Windows 团队在CodePlex发布了 Kinect for Windows Samples . List of Samples This is the list of a ...

  9. 深度相机(八)--OpenNI及与Kinect for windows SDK的比较

     OpenNI(开放自然交互)是一个多语言,跨平台的框架,它定义了编写应用程序,并利用其自然交互的API.OpenNI API由一组可用来编写通用自然交互应用的接口组成.OpenNI的主要目的是要 ...

最新文章

  1. Paper9:Fast RCNN
  2. Yii2 解决2006 MySQL server has gone away问题
  3. mysql忘记数据库密码
  4. Git的commit之后的撤销revert
  5. HDU - 6959 zoto 莫队 + 值域分块
  6. Linux空硬盘从分区到挂载
  7. 一文彻底搞懂静态库和动态库,显示链接和隐式链接
  8. Java微信公众平台获取签名
  9. python 函数式_10分钟学习函数式Python
  10. 批处理路径中含有空格的处理办法
  11. bay——RAC 表空间时数据文件误放置到本地文件系统-介质恢复.txt
  12. Arduino Uno 学习第零课,Arduino认识
  13. 虚拟机运行python_虚的解释|虚的意思|汉典“虚”字的基本解释
  14. 制作自动添加IE信任站点运行文件
  15. Vue基础入门(2) Vue.js下载与安装
  16. 镜头能看多远,人眼能看多远
  17. appium 等待的3中方式:强制等待、隐式等待、显示等待
  18. lisp 提取字符串中的數字_lisp 提取字符串中的數字_LISP - 字符串
  19. 前端如何解决白屏问题
  20. 直方图均衡化(Matlab实现)

热门文章

  1. 程序员基本功书籍--程序员修炼之道——从小工到专家
  2. gin中间件中使用Goroutines
  3. object类中的equals与自定义equals方法详解
  4. 两个线程并发执行以下代码,假设a是全局变量,初始为1,那么以下输出______是可能的?
  5. springmvc三十二:spring mvc的运行流程
  6. 前端一HTML:二: html开发工具
  7. pycharm远程开发项目
  8. WKWebView get/set cookie小结
  9. 《移动App测试的22条军规》—App测试综合案例分析23.7节测试微信App对于操作系统特性的支持程度...
  10. springboot @ConfigurationProperties