人脸识别,听上去好像很牛批,不过我们能做的也就是调用一下人家的API而已,记录一下我调用百度人脸识别API的过程。
百度AI开发文档:http://ai.baidu.com/docs#/Face-Csharp-SDK/top,本身文档已经写得相当良心了,要是所有开发文档都这么详细就好了。
首先登陆百度云管理后台,创建一个人脸识别应用
右侧菜单打开人脸库,新建一个组,在组里创建一个用户,并为这个用户上传图片(人脸照),这个分组跟照片是之后进行人脸搜索的基础。这里解释一下什么是人脸搜索,这个意思是选择一张图片然后从组中匹配人脸并返回匹配度最高的值,可以用作验证该图片的人脸是否存在组中。
然后我们就可以开始写代码了,下载开发SDK,推荐在NuGet中搜索 Baidu.AI
,直接安装就行了,具体是在vs的工具-NuGet包管理器-解决包管理器的NuGet程序包,搜索baidu即可。
创建一个winform工程,按照下图进行布局,各个控件name为:
图片框pictureBox 文件选择openFileDialog lable从上到下分别是group_id ,user_id,score,然后是button1(左),button2(右)
现在写几个方法用来调用百度API,下面的三个值可以在你创建的应用处找到,需要
using System.IO;
using Baidu.Aip.Face;
/// <summary>
/// 人脸识别API参数初始化
/// </summary>
/// <returns></returns>
private Baidu.Aip.Face.Face GetFacaClient()
{
// 设置APPID/AK/SK
string APP_ID = "你的APP_ID";
string API_KEY = "你的API_KEY";
string SECRET_KEY = "你的SECRET_KEY";
Face client = new Baidu.Aip.Face.Face(API_KEY, SECRET_KEY);
client.Timeout = 60000; // 修改超时时间
return client;
}
然后写一个图片转Base64的方法,因为百度以Base64表示一张图片,下面的“image”会在按钮的点击事件传进去。
/// <summary>
/// 图片转换为Base64
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
private string ImgToBase64String(string image)
{
try
{
Bitmap bmp = new Bitmap(image, true);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
return Convert.ToBase64String(arr);
}
catch (Exception ex)
{
return null;
}
}
最后就是调用API的方法
/// <summary>
/// 人脸搜索,从人脸库中查询是否有合适的人像
/// </summary>
/// <param name="ImageBase">图片Base64值</param>
/// <returns></returns>
public Newtonsoft.Json.Linq.JObject SearchDemo(string ImageBase)
{
string image = ImageBase;
string imageType = "BASE64";
string groupIdList = "test";//你的应用名字
Face client = GetFacaClient();
// 调用人脸搜索,可能会抛出网络等异常,请使用try/catch捕获
var result = client.Search(image, imageType, groupIdList);
return result;
}
然后给两个按钮加上点击事件
选择图片按钮
/// <summary>
/// 选择照片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//PictureBox控件显示图片
pictureBox.Load(openFileDialog.FileName);
}
}
检查按钮
/// <summary>
/// 检查按钮点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
string ImageBase = ImgToBase64String(openFileDialog.FileName.ToString());
var msg = SearchDemo(ImageBase);
group_id.Text = "所在组:" + msg["result"]["user_list"][0].Value<string>("group_id");
user_id.Text = "用户id:" + msg["result"]["user_list"][0].Value<string>("user_id");
score.Text = "匹配度:" + msg["result"]["user_list"][0].Value<string>("score");
}
记得将图片框的SizeMode选为StretchImage,要不然图片可能会显示不全,可以在窗体的初始事件中加入
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
或者在设计窗体选择SizeMode。
现在DEMO已经做好了,我们可以试一下效果。
选择图片,然后点击检查,然后右边就会显示数据。我这里匹配度达到了93,因为人脸库中存在这个人的另一张图片。下面选择另一个人的图片,这个人的其他图片不存在人脸库中。
因为人脸库中就只有一个人的id,所以返回了跟上一张图同样的用户id,不过匹配度就很低了,低于80我们就可以认为这个人不在人脸库中,这样就达到了人脸搜索功能。