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

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

好,屁话不说,先介绍一下如何完成人脸识别(或者叫人脸检测,随你怎么翻译,反正知道是怎么一回事就行)。核心的类是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. 基于2D-RNN的鲁棒行人跟踪

    基于2D-RNN的鲁棒行人跟踪 Recurrent Neural Networks RNN 行人跟踪 读"G.L. Masala, et.al., 2D Recurrent Neural N ...

  2. Linux内核笔记——进程管理之执行体

    内核版本:linux-2.6.11 在Linux中,有多种执行体(指令流.执行单位),它们是CPU调度和分配资源的基本单位,它们是内核态可见的,即内核态下,每一种执行体都有对应的唯一数据结构task_ ...

  3. Spring AOP详解

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  4. macosx 10.11 python pip install 出现错误OSError: [Errno 1] Operation not permitted:

    Exception: Traceback (most recent call last): File , in main status = self.run(options, args) File , ...

  5. [翻译svg教程]svg中矩形元素 rect

    svg 元素<rect> 是一个矩形元素,用这个元素,可以你可以绘制矩形,设置矩形宽高,边框的宽度颜色,矩形的填充颜色,是否用圆角等 rect 示例 <svg xmlns=" ...

  6. nodejs express 安装

    前几天刚遇到的问题sudo npm install -g expresssudo npm install -g express-generator然后通过express -V查看版本,看好是大写的V ...

  7. ssh密钥私钥不能登陆问题处理

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! ...

  8. vertical-align和line-height的那些事

    可能是又遇到了瓶颈,好长时间感觉css上没什么可看.从来没觉得css有什么难,什么盒模型和各种流也觉得理解起来毫不费力,但好像仅限于此.对一些属性仅限于常用,有时会去做实验验证一些属性,过后就忘了.现 ...

  9. swift-string(字符串的一些语法)

    1 isEmpty 返回一个布尔值,确定该字符串是否为空 2 hasPrefix(prefix: String) 函数检查给定的参数字符串是否以 string 为前缀 3 hasSuffix(suff ...

  10. 【JBOSS】控制台数据库连接信息

    数据库连接 信息 进入         在这个页面中(IP和端口已自己的为主):ConnectionCount 这个项目代表在服务开启后,总共使用的连接数!ConnectionCreatedCount ...