可能你会认为人脸识别用起来会很复杂,老周当初也这么想,但通过实际操作后,我发现非然。

经过微软封装的东西,向来都是复杂问题简单化,只要用得舒心,代码越少越好,用最少的代码做最多的事情,此为大师境界也。

好,屁话不说,先介绍一下如何完成人脸识别(或者叫人脸检测,随你怎么翻译,反正知道是怎么一回事就行)。核心的类是FaceDetector,不要问我这个类在哪里,自己打开对象浏览器搜索。

第一步,访问静态属性IsSupported,看看当前平台是不是支持人脸识别,如果返回false,那就没戏了。

第二步,调用静态方法CreateAsync得到一个FaceDetector实例,所以该类不需要手动实例化,初始化过程由运行库来完成,然后把初始化好的实例返回给咱们,然后就可以用它来干活了。

第三步,调用实例方法DetectFacesAsync进行识别,识别完后会返回一个DetectedFace列表,每个DetectedFace表示一张脸,因为你用来识别的照片中可能包含N张脸。FaceBox属性包含了人脸的矩形区域,就是人脸位于整张照片的哪个位置,可通过X,Y坐标描述矩形的左上角位置,并用宽度和高度来表明那张脸的大小。

DetectFacesAsync方法需要一个SoftwareBitmap类型的参数,该参数就是你要用来识别人脸的图像。

可能大家已经知道,通过BitmapDecoder类的GetSoftwareBitmapAsync方法可以返回一个SoftwareBitmap实例,不过要注意的是,FaceDetector在进行检测时并不是所有像素格式都支持,可以调用GetSupportedBitmapPixelFormats方法来获取所有受支持的像素格式列表,经老周测试,该方法返回Nv12和Gray8,也就是当前只支持这两种格式。当然,你也可以通过IsBitmapPixelFormatSupported方法来验证一下某个像素格式是否被支持。

好了,基本用法已经说完了,确实不是很复杂。下面,老周给大家演示一个例子,该例子允许你选择一张照片,然后识别出照片上的人脸,并用一个矩形来标记。

先看看UI的设计,主要的XAML如下:

        <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Button Content="选择要识别的照片" Click="OnClick"/>
<Viewbox Grid.Row="1" Margin="5" Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas Name="cv" Width="{x:Bind img.Width,Mode=OneWay}" Height="{x:Bind img.Height,Mode=OneWay}" >
<Image Name="img" Stretch="None"/>
</Canvas>
</Viewbox> <TextBlock Name="tbMessage" Foreground="Red" FontSize="16" Grid.Row="2"/>
</Grid>

为啥我要用一个ViewBox呢,因为这个控件有一个好处,就是会自动将它里面的可视化对象进行缩放,待会儿我要在Image上显示图片,而且还要用到Rectangle元素来标记人脸的位置,为了让绝对坐标计算起来能与原图相等,就把这些内容都放在ViewBox中,让Viewbox来进行缩放,这样一来,就能够根据窗口的大小自动调整显示区域了。

之所以用Canvas,是因它是绝对坐标定位的,这方便我稍后放置Rectangle元素。

处理按钮事件,通过OpenFilePicker来打开图像文件。

            FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png"); StorageFile file = await picker.PickSingleFileAsync();

记得以前跟大家讲过,picker调用后要挂起当前应用,并通过响应应用激活来处理获取的文件,这是在WP 8.1的文章中说过,但是,现在不用了,很简单,因为Windows Phone App和Windows App已经完全统一了,所以不必再考虑平台隔离的代码了。

下面代码完成两件事:1、在Image控件上显示图像;2、进行识别,并用矩形标记人脸位置。

            if (file != null)
{
using (IRandomAccessStream streamIn= await file.OpenReadAsync())
{
// 对图像文件进行解码
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(streamIn);
// 获取图像内容
SoftwareBitmap sbmp = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight); WriteableBitmap bmp = new WriteableBitmap(sbmp.PixelWidth, sbmp.PixelHeight);
sbmp.CopyToBuffer(bmp.PixelBuffer);
this.img.Source = bmp;
img.Width = bmp.PixelWidth;
img.Height = bmp.PixelHeight; // 通过循环,尝试以各种受支持的格式来进行识别
// 如果识别顺利,就跳出循环
// 否则进入下一轮循环
int n = ;
while (n < formats.Count)
{
if (FaceDetector.IsBitmapPixelFormatSupported(formats[n]))
{
FaceDetector detector = await FaceDetector.CreateAsync();
try
{
// 转换图像像素格式
SoftwareBitmap sbmp2 = SoftwareBitmap.Convert(sbmp, formats[n]);
// 进行检测
IList<DetectedFace> results = await detector.DetectFacesAsync(sbmp2); // 清理Canvas中的矩形
while (cv.Children.Count > )
cv.Children.RemoveAt(cv.Children.Count - );
// 在界面上添加矩形
for (int i = ; i < results.Count; i++)
{
DetectedFace dface = results[i];
Rectangle rect = new Rectangle(); rect.Stroke = new SolidColorBrush(Colors.Yellow);
rect.StrokeThickness = 5d;
// 定位矩形
Canvas.SetLeft(rect, dface.FaceBox.X);
Canvas.SetTop(rect, dface.FaceBox.Y);
rect.Width = dface.FaceBox.Width;
rect.Height = dface.FaceBox.Height;
cv.Children.Add(rect);
}
tbMessage.Text = "人脸识别完成。";
break;
}
catch
{
tbMessage.Text = "人脸识别失败。";
n++;
}
//cv.InvalidateArrange();
}
} }

因为我要在Image上显示图像,所以从decoder中得到的SoftwareBitmap不能直接用于识别,原因是我刚才说了,目前SDK的人脸识别只支持少量的像素格式,Bgra8是不受支持的,所以可以用SoftwareBitmap的Convert方法转换格式,并返回转换后的SoftwareBitmap对象。

这里我用一个while循环来完成识别:

                    int n = ;
while (n < formats.Count)
{
if (FaceDetector.IsBitmapPixelFormatSupported(formats[n]))
{
FaceDetector detector = await FaceDetector.CreateAsync();
try
{
……
break;
}
catch
{
……
n++;
}
}

意思是,我用FaceDetector所支持的所有像素格式都去尝试进行识别,只要其中有一种格式能够顺利完成识别,就终止循环(break);如果第一种格式不能识别,就把n++来使用第二种格式来识别。

=============================================

示例的大致情况就是这样,做完后我们当然要来试试效果了。

首先,来检测一下八戒的猪脸。

很显然,猪脸也能检测出来,不错。

接着,我又请神仙妹妹来试镜。发现效果甚好。

    

然后,我又找来一位MM再试,效果也甚佳。

怎么样,这姿势不错吧。

示例源码下载:http://files.cnblogs.com/files/tcjiaan/FaceDetApp.zip

【Win10 应用开发】人脸识别的更多相关文章

  1. Nodejs开发人脸识别系统-教你实现高大上的人工智能

    Nodejs开发人脸识别系统-教你实现高大上的人工智能   一.缘起缘生 前段时间有个H5很火,上传个头像就可以显示自己穿军装的样子,无意中看到了一篇帖子叫 全民刷军装背后的AI技术及简单实现 ,里面 ...

  2. 全栈工程师带你开发 ,node开发人脸识别门禁系统

    效果图:       知识点: 人脸识别SKD部署,  webRTC视频流处理,URL构建blob对象,Canvas映射截图,ajax数据交互,Node图像处理,跨域与413处理,base64解码,p ...

  3. 基于Dlib、OpenCV开发人脸识别程序的开发建议

    前言 在去年十月的时候参加了一个小比赛,做了一个人脸识别程序并很意外地获得省里面的一等奖,视频演示链接在这里,有同学想要做这方面的毕业设计or课程设计,发一篇博客来分享一下当时的开发过程. 视频演示链 ...

  4. [深度应用]·实战掌握Dlib人脸识别开发教程

    [深度应用]·实战掌握Dlib人脸识别开发教程 个人网站--> http://www.yansongsong.cn/ 项目GitHub地址--> https://github.com/xi ...

  5. C#实现基于ffmpeg加虹软的人脸识别demo及开发分享

    对开发库的C#封装,屏蔽使用细节,可以快速安全的调用人脸识别相关API.具体见github地址.新增对.NET Core的支持,在Linux(Ubuntu下)测试通过.具体的使用例子和Demo详解,参 ...

  6. C#_Demo_摄像头实时_4线程人脸识别注册开发全过程

    v效率有点低,大家看看哪里开可以节省时间?源代码:https://github.com/catzhou2002/ArcFaceDemo说实话,为了提高识别效率,我也是竭尽所能,干了不少自认为的优化,如 ...

  7. c# 利用AForge和百度AI开发实时人脸识别

    baiduAIFaceIdentify项目是C#语言,集成百度AI的SDK利用AForge开发的实时人脸识别的小demo,里边包含了人脸检测识别,人脸注册,人脸登录等功能 人脸实时检测识别功能 思路是 ...

  8. opencv+opencv_contrib 人脸识别和检测 python开发环境快速搭建(30分钟)图文教程

    很多朋友为了学习python.ML(机器学习).DL(深度学习).opencv等花费了大量时间配置安装环境(一个朋友花了4天时间才配置好)各种搜索.下载.安装配置,出问题等. 市面上的配置资料很多,选 ...

  9. C++开发人脸性别识别教程(16)——视频人脸性别识别

    在之前的博文中我们已经可以顺利驱动摄像头来採集源图像.在这篇博文中将正式为其加入性别识别的代码,实现摄像头视频的人脸性别识别. 一.人脸检測 在得到摄像头採集的源图像之后,首先要做的就是对其进行人脸检 ...

随机推荐

  1. Python for Infomatics 第14章 数据库和SQL应用三(译)

    14.5 SQL 总结 到目前为止,我们在Python示例程序中使用了SQL,并且涉及了许多SQL基础.在这一小节中,我们特别审视SQL语言,并对其语法进行回顾. 虽然有很多不同的数据库供应商,但因S ...

  2. [面试] Design Questions

    Uber总是考一些系统设计的题目,而且重复率很高,汇总了一下地里的所有design的题目,希望可以跟小伙伴们讨论下. Uber Design Questions 1.    让design uber ...

  3. JQ 常见demo

    使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: <!DOCTYPE html> <html> <head> <script src= ...

  4. 安卓(android)之实现断点下载功能

    一.建立实体类 1.文件实体类 package com.example.zjw.myapplication.dao; import java.io.Serializable; /** * 预下载文件实 ...

  5. java空指针异常:java.lang.NullPointException

    一.什么是java空指针异常 我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析.空 ...

  6. Bug管理系统 BugFree

    BugFree - 借鉴微软公司软件研发理念.免费且开放源代码.基于Web的精简版Bug管理系统 在线演示:http://www.bugfree.org.cn/demo/Login.php 其它项目管 ...

  7. 7_nodejs angularjs

    webstrom使用: ctrl+b/点击,代码导航,自动跳转到定义 ctrl+n跳转指定类 ctrl+d复制当前行ctrl+enter另起一行ctrl+y删除当前行 ctrl+alt/shift+b ...

  8. C++风格的回调对象方法. 采用template实现

    今天看了一篇文章,收藏一下代码.读一读很有激情 #include <iostream> #include <string> #include <vector> us ...

  9. Excel表格数据导入到SQLServer数据库

    转载:http://blog.csdn.net/lishuangzhe7047/article/details/8797416 步骤: 1,选择要插入的数据库--右键--任务--导入数据 2,点击下一 ...

  10. js通过注册表找到本地软件安装路径并且执行

    场景:用js执行本地的安装软件,如果不存在就执行安装 操作步骤: 1.前台js代码 <script type="text/javascript"> function e ...