首先需要登录百度大脑,然后在控制台选择人脸识别
接下来创建一个新应用
应用名称和应用描述随便写,只要自己能辨别就行,创建完后,点击查看应用详情
在应用详情界面,我们可以看到自己的应用名称,AppID、APIKey、SecretKey,这些后续开发是要用到的
然后点击左侧列表中的服务端SDK下载,找到C#SDK下载
下载后打开net35文件夹,其中AipSdk.dll和Newtonsoft.Json.dll两个引用后续我们要加到Unity3d工程里
OK准备工作到此结束,现在才是正式开始
新建个Unity3d工程
此时在Assets下新建一个Plugins文件夹,我们将之前下载的AipSdk.dll和Newtonsoft.Json.dll复制到该文件夹下
新建个场景FaceDetect,新建个C#脚本FaceDetect(命名随意)
定义一个客户端,此时要用到之前创建的应用的APIKey和SecretKey
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Baidu.Aip.Face;
using System.Text;
using System;
using UnityEngine.UI;
public class FaceDetect : MonoBehaviour
{
public string API_KEY = "之前创建的应用的API_KEY";
public string SECRET_KEY = "之前创建的应用的SECRET_KEY ";
Face client;//调用百度API接口
void Start()
{
client = new Face(API_KEY, SECRET_KEY);
}
}
注册人脸,参数的说明可以在官方文档里查看
private byte[] image;//注册时用到的图片数据
private Dictionary<string, object> options = new Dictionary<string, object>();//多参数
private string groupId;//用户所在组,部门
//人脸注册
public void SignUpFace(string image, string imageType, string groupId, string userId)
{
var options = new Dictionary<string, object>{
{"user_info", "LiYanHong"},
{"quality_control", "NORMAL"},
{"liveness_control", "LOW"}
};
// 带参数调用人脸注册
var result = client.UserAdd(image, imageType, groupId, userId, options);
}
注册人脸,其实就是上传图片到百度大脑人脸识别库;如果是上传本地图片,则需获取图片的BASE64字符串或者FACE__TOKEN字符串(这个我没用过,感兴趣的自己研究);也可以直接用通过url上传。
我们这里采用上传本地图片
随便找一张照片(为了方便测试,推荐用自拍)保存到新建的StreamingAssets文件夹下的FaceUpLoad文件夹下
我们这里采用BASE64字符串,首先我们需要获取到图片的BASE64字符串; 由于百度大脑给我限制的QPS是2,我只能降低注册频率
//获取图片base64字符串,由于QPS限制,此处采用协程降低注册频率
IEnumerator IEGetStringBase64()
{
//获取到每一张图片的路径
string[] picsPathArr = Directory.GetFiles(Application.streamingAssetsPath + "/FaceDetect/");
//循环获取每张图片的base64字符串
for (int i = 0; i < picsPathArr.Length; i++)
{
//unity会自动生成.meta文件,过滤掉
if (picsPathArr[i].Contains("meta")) continue;
//读取
FileInfo file = new FileInfo(picsPathArr[i]);
var stream = file.OpenRead();
byte[] buffer = new byte[file.Length];
//读取图片字节流
stream.Read(buffer, 0, Convert.ToInt32(file.Length));
//base64字符串
string imageBase64 = Convert.ToBase64String(buffer);
//采用base64字符串方式上传
string imageType = "BASE64";
//用户组
string groupId = "group1";//改成自己的人脸识别库中创建的的groupid
//用户id,一般同一个人的图片放在同一个id下
string userId = "test01";//改成自己的人脸识别库中创建的的userid
//开始注册
SignUpFace(imageBase64, imageType, groupId, userId);
yield return new WaitForSeconds(0.6f);
}
}
注册完后我们可以在百度大脑的控制台找到之前创建的应用的人脸识别库里看到上传的图片(同样的图片不要重复注册)
如下图,用户组的名字就是groupid,“group1”是我这次创建的groupid
点击group1,在group1下一级就是userid了,如下图,“test01”就是我这次创建的的userid
接下来我们创建一个新的C#脚本取名CallCamera,主要功能是用来调用外接摄像头,就一个调用摄像头的协程,本人默认分辨率1920x1080,刷新率20,然后在工程中新建一个rawImage,将获取到的画面显示出来
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CallCamera : MonoBehaviour
{
[HideInInspector]
public WebCamTexture webTex;
[HideInInspector]
public string deviceName;
//显示摄像头画面
public RawImage rawImage;
// Use this for initialization
void Start ()
{
StartCoroutine(IECallCamera());
}
IEnumerator IECallCamera()
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
WebCamDevice[] devices = WebCamTexture.devices;
deviceName = devices[0].name;
//设置摄像机摄像的区域
webTex = new WebCamTexture(deviceName, 1920, 1080, 20);
webTex.Play();//开始摄像
rawImage.texture = webTex;
}
}
}
摄像头画面已经能获取到了,此时我们要实现截图功能
我们将Canvas的模式改为WorldSpace模式,然后在场景中复制MainCamera得到一个新的camera,取名CaptureCamre,专门用来截图
打开FaceDetect脚本来添加代码,定义一个camera,把刚才场景中新建的captureCamera挂上去
//截取摄像头实时画面
public Camera cameras;
在StreamingAssets文件夹下新建个CameraFaceDetect文件夹用来保存摄像头画面的截图
然后在代码中实现点击按钮截屏保存到本地然后截屏功能,新建个Button和三个text,一个用来显示检测信息一个用来显示人脸识别成功和失败的文字,然后给Button添加事件BtnClick()
public GameObject 识别成功文本;
public GameObject 识别失败文本;
private double scores = 0.01f;//认证返回的分数(百度0-100,指数是80分可以通过认证,可以自己设置)
public Text text;
//截图
public void CaptureScreen()
{
Texture2D screenShot;
RenderTexture rt = new RenderTexture(1920, 1080, 1);
cameras.targetTexture = rt;
cameras.Render();
RenderTexture.active = rt;
screenShot = new Texture2D(1920, 1080, TextureFormat.RGB24, false);
screenShot.ReadPixels(new Rect(0, 0, 1920, 1080), 0, 0);
screenShot.Apply();
string fileName = Application.streamingAssetsPath + "/CameraFaceDetect/" + "CameraFace.jpg";
//保存到本地
byte[] jpgData = screenShot.EncodeToJPG();
System.IO.File.WriteAllBytes(fileName, jpgData);
//人脸对比
CameraFaceSearch(fileName);
}
//实时摄像头人脸画面对比
public void CameraFaceSearch(string fileName)
{
FileInfo file = new FileInfo(fileName);
var stream = file.OpenRead();
byte[] buffer = new byte[file.Length];
//读取图片字节流
stream.Read(buffer, 0, Convert.ToInt32(file.Length));
var image = Convert.ToBase64String(buffer);
var imageType = "BASE64";
//之前注册的组
var groupIdList = "group1";
var result = client.Search(image, imageType, groupIdList);
text.text = result.ToString();
scores = float.Parse(result["result"]["user_list"][0]["score"].ToString());//获得对比结果返回的分数值
Debug.Log(result);
}
//点击按钮开始截屏检测对比
public void BtnClick()
{
text.text = null;
CaptureScreen();
if (scores > 80.0)//说明该人脸的匹配度达标
{
Debug.Log("识别成功");
识别成功文本.SetActive(true);
识别失败文本.SetActive(false);
}
else
{
Debug.Log("识别失败");
识别成功文本.SetActive(false);
识别失败文本.SetActive(true);
}
}
要和哪个组内照片作对比,那么CameraFaceSearch()方法里的groupIdList就要改成对应的组名,例如上图我新建了MySelf组,假设我在MySelf组里上传了照片并且我要和MySelf组里的照片做对比,那么groupIdList=“MySelf”;
然后点击开始检测按钮实现刷脸功能
如果以上步骤都没有问题那么我们接下来在创建一个Button用作人脸注册按钮添加事件BtnSignUpFace()
//点击按钮进行人脸注册
public void BtnSignUpFace()
{
StartCoroutine(IEGetStringBase64());
}
回到人脸注册的协程方法在首行执行CaptureScreen();并将获取图片路径改为CameraFaceDetect
//获取图片base64字符串,由于QPS限制,此处采用协程降低注册频率
IEnumerator IEGetStringBase64()
{
识别成功文本.SetActive(false);
识别失败文本.SetActive(false);
CaptureScreen();
//获取到每一张图片的路径
string[] picsPathArr = Directory.GetFiles(Application.streamingAssetsPath + "/CameraFaceDetect/");
到此基本功能就实现了
不要忘了赋值自己的API_KEY和SECRET_KEY