Unity基于百度大脑SDK的人脸识别

首先需要登录百度大脑,然后在控制台选择人脸识别

接下来创建一个新应用


应用名称和应用描述随便写,只要自己能辨别就行,创建完后,点击查看应用详情


在应用详情界面,我们可以看到自己的应用名称,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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容