.NET做人脸识别并分类
.NET做人脸识别并分类
在游乐场、玻璃天桥、滑雪场等娱乐场所,经常能看到有摄影师在拍照片,令这些经营者发愁的一件事就是照片太多了,客户在成千上万张照片中找到自己可不是件容易的事。在一次游玩等活动或家庭聚会也同理,太多了照片导致挑选十分困难。
还好有.NET,只需少量代码,即可轻松找到人脸并完成分类。
本文将使用Microsoft Azure云提供的认知服务(Cognitive Services)API来识别并进行人脸分类,可以免费使用,注册地址是:https://portal.azure.com。注册完成后,会得到两个密钥,通过这个密钥即可完成本文中的所有代码,这个密钥长这个样子(非真实密钥):
fa3a7bfd807ccd6b17cf559ad584cbaa
使用方法
首先安装NuGet包Microsoft.Azure.CognitiveServices.Vision.Face,目前最新版是2.5.0-preview.1,然后创建一个FaceClient:
string key = "fa3a7bfd807ccd6b17cf559ad584cbaa"; // 替换为你的key
using var fc = new FaceClient(new ApiKeyServiceClientCredentials(key))
{
Endpoint = "https://southeastasia.api.cognitive.microsoft.com",
};
然后识别一张照片:
using var file = File.OpenRead(@"C:\Photos\DSC_996ICU.JPG");
IList<DetectedFace> faces = await fc.Face.DetectWithStreamAsync(file);
其中返回的faces是一个IList结构,很显然一次可以识别出多个人脸,其中一个示例返回结果如下(已转换为JSON):
[
{
"FaceId": "9997b64e-6e62-4424-88b5-f4780d3767c6",
"RecognitionModel": null,
"FaceRectangle": {
"Width": 174,
"Height": 174,
"Left": 62,
"Top": 559
},
"FaceLandmarks": null,
"FaceAttributes": null
},
{
"FaceId": "8793b251-8cc8-45c5-ab68-e7c9064c4cfd",
"RecognitionModel": null,
"FaceRectangle": {
"Width": 152,
"Height": 152,
"Left": 775,
"Top": 580
},
"FaceLandmarks": null,
"FaceAttributes": null
}
]
可见,该照片返回了两个DetectedFace对象,它用FaceId保存了其Id,用于后续的识别,用FaceRectangle保存了其人脸的位置信息,可供对其做进一步操作。RecognitionModel、FaceLandmarks、FaceAttributes是一些额外属性,包括识别性别、年龄、表情等信息,默认不识别,如下图API所示,可以通过各种参数配置,非常好玩,有兴趣的可以试试:

最后,通过.GroupAsync来将之前识别出的多个faceId进行分类:
var faceIds = faces.Select(x => x.FaceId.Value).ToList();
GroupResult reslut = await fc.Face.GroupAsync(faceIds);
返回了一个GroupResult,其对象定义如下:
public class GroupResult
{
public IList<IList<Guid>> Groups
{
get;
set;
}
public IList<Guid> MessyGroup
{
get;
set;
}
// ...
}
包含了一个Groups对象和一个MessyGroup对象,其中Groups是一个数据的数据,用于存放人脸的分组,MessyGroup用于保存未能找到分组的FaceId。
有了这个,就可以通过一小段简短的代码,将不同的人脸组,分别复制对应的文件夹中:
void CopyGroup(string outputPath, GroupResult result, Dictionary<Guid, (string file, DetectedFace face)> faces)
{
foreach (var item in result.Groups
.SelectMany((group, index) => group.Select(v => (faceId: v, index)))
.Select(x => (info: faces[x.faceId], i: x.index + 1)).Dump())
{
string dir = Path.Combine(outputPath, item.i.ToString());
Directory.CreateDirectory(dir);
File.Copy(item.info.file, Path.Combine(dir, Path.GetFileName(item.info.file)), overwrite: true);
}
string messyFolder = Path.Combine(outputPath, "messy");
Directory.CreateDirectory(messyFolder);
foreach (var file in result.MessyGroup.Select(x => faces[x].file).Distinct())
{
File.Copy(file, Path.Combine(messyFolder, Path.GetFileName(file)), overwrite: true);
}
}
然后就能得到运行结果,如图,我传入了102张照片,输出了15个分组和一个“未找到队友”的分组:

还能有什么问题?
就两个API调用而已,代码一把梭,感觉太简单了?其实不然,还会有很多问题。
图片太大,需要压缩
毕竟要把图片上传到云服务中,如果上传网速不佳,流量会挺大,而且现在的手机、单反、微单都能轻松达到好几千万像素,jpg大小轻松上10MB,如果不压缩就上传,一来流量和速度遭不住。
二来……其实Azure也不支持,文档(https://docs.microsoft.com/en-us/rest/api/cognitiveservices/face/face/detectwithstream)显示,最大仅支持6MB的图片,且图片大小应不大于1920x1080的分辨率:
- JPEG, PNG, GIF (the first frame), and BMP format are supported. The allowed image file size is from 1KB to 6MB.
- The minimum detectable face size is 36x36 pixels in an image no larger than 1920x1080 pixels. Images with dimensions higher than 1920x1080 pixels will need a proportionally larger minimum face size.
因此,如果图片太大,必须进行一定的压缩(当然如果图片太小,显然也没必要进行压缩了),使用.NET的Bitmap,并结合C# 8.0的switch expression,这个判断逻辑以及压缩代码可以一气呵成:
byte[] CompressImage(string image, int edgeLimit = 1920)
{
using var bmp = Bitmap.FromFile(image);
using var resized = (1.0 * Math.Max(bmp.Width, bmp.Height) / edgeLimit) switch
{
var x when x > 1 => new Bitmap(bmp, new Size((int)(bmp.Size.Width / x), (int)(bmp.Size.Height / x))),
_ => bmp,
};
using var ms = new MemoryStream();
resized.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}
竖立的照片
相机一般都是3:2的传感器,拍出来的照片一般都是横向的。但偶尔寻求一些构图的时候,我们也会选择纵向构图。虽然现在许多API都支持正负30度的侧脸,但竖着的脸API基本都是不支持的,如下图(实在找不到可以授权使用照片的模特了
.NET做人脸识别并分类的更多相关文章
- swift通过摄像头读取每一帧的图片,并且做识别做人脸识别
最近帮别人做一个项目,主要是使用摄像头做人脸识别 github地址:https://github.com/qugang/AVCaptureVideoTemplate 要使用IOS的摄像头,需要使用AV ...
- Android 用虹软SDK做人脸识别
人脸识别第三方sdk比较多,但是大多都是收费的或者限制次数什么的,虹软的效果还不错,全免费也不需要联网 V1.2版本使用和快速集成:https://www.jianshu.com/p/8dee89ec ...
- python 调用百度接口 做人脸识别
操作步骤差不多,记得要在百度AIPI中的控制台中创建对应的工单 创建工单成功后 会生成两个key 这个两个key是要生成tokn 用 这里大家可以用 def函数 将token返回 供下面的接口使用 ...
- 人脸识别必读的N篇文章
一,人脸检测/跟踪 人脸检测/跟踪的目的是在图像/视频中找到各个人脸所在的位置和大小:对于跟踪而言,还需要确定帧间不同人脸间的对应关系. 1, Robust Real-time Object Dete ...
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图
原地址:http://blog.csdn.net/watkinsong/article/details/7631241 目前因为做人脸识别的一个小项目,用到了AdaBoost的人脸识别算法,因为在网上 ...
- face recognition[翻译][深度人脸识别:综述]
这里翻译下<Deep face recognition: a survey v4>. 1 引言 由于它的非侵入性和自然特征,人脸识别已经成为身份识别中重要的生物认证技术,也已经应用到许多领 ...
- Python的开源人脸识别库:离线识别率高达99.38%
Python的开源人脸识别库:离线识别率高达99.38% github源码:https://github.com/ageitgey/face_recognition#face-recognitio ...
- ng-深度学习-课程笔记-14: 人脸识别和风格迁移(Week4)
1 什么是人脸识别( what is face recognition ) 在相关文献中经常会提到人脸验证(verification)和人脸识别(recognition). verification就 ...
- Cell期刊论文:为什么计算机人脸识别注定超越人类?(祖母论与还原论之争)
终于找到ML日报的微信链接,抄之...................................... 请拜访原文链接:[祖母论与还原论之争]为什么计算机人脸识别注定超越人类?评价: ...
随机推荐
- 高性能Web动画和渲染原理系列(3)——transform和opacity为什么高性能
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] [T ...
- Spring(一)Spring基础知识
创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB(Enterprise JavaBean 企业级JavaBean).相对于EJB来说,Spring提供了更加轻量级和简单 ...
- 全方面讲解TensorFlow
任何曾经试图在 Python 中只利用 NumPy 编写神经网络代码的人都知道那是多么麻烦.编写一个简单的一层前馈网络的代码尚且需要 40 多行代码,当增加层数时,编写代码将会更加困难,执行时间也会更 ...
- 无法打开msvcrtd.lib
- open_basedir限制目录
1.open_basedir介绍 前言:前些日我用lnmp一键安装包出现了open_basedir的问题,因为我把项目目录变了,所以要在的fastcgi.conf下面加上open_basedir的目录 ...
- Linux性能分析
生产环境服务器变慢,诊断思路和性能评估 整机:top 代码 public class JavaDemo2 { public static void main(String[] args) { whil ...
- 从函数计算架构看 Serverless 的演进与思考
作者 | 杨皓然 阿里巴巴高级技术专家 导读:云计算之所以能够成为 DT 时代颠覆性力量,是因为其本质是打破传统架构模式.降低成本并简化体系结构,用全新的思维更好的满足了用户需求.而无服务器计算(S ...
- 使用Bind提供域名解析服务(正向解析)
小知识: 一般来讲域名比IP地址更加的有含义.也更容易记住,所以通常用户更习惯输入域名来访问网络中的资源,但是计算机主机在互联网中只能通过IP识别对方主机,那么就需要DNS域名解析服务了. DNS域名 ...
- Spring 动态代理 之 but was actually of type 'com.sun.proxy.$Proxy14 Exception
今天在写Spring的引介代理的时候,报了一个错: Exception in thread "main" org.springframework.beans.factory.Bea ...
- web中间件常见漏洞总结笔记
之前看吐司别人发的个文档,简单记的笔记 ----- IIS 解析漏洞 IIS 6 *.asp;.jpg会被当作asp解析 *.asp/ ...