概述

使用 BaiduAI 人脸识别的C# SDK,可以在unity中识别并提取人脸特征值。其中包括脸型、年龄、人种、性别、相貌评分等。嗯,其中相貌评分这一项。。。难道美的标准只能有一种吗?

读取图片

识别人脸从读取、加载图片开始。图片获取有多种方式,可以从文件读取,也可以调用WebTexture拍照。

图片信息可以以byte[ ]或string的形式存储。

1. 从文件读取

可以参考使用 File.ReadAllBytes

byte[] image_data = File.ReadAllBytes(Application.dataPath + "....jpg");

或以 WWW 的方式:

public void LoadByWWW(string path)
{
    StartCoroutine(Load(path));
}

private IEnumerator Load(string path)
{
    WWW www = new WWW(path);

    yield return www;
    if (www != null && string.IsNullOrEmpty(www.error))
    {
        Texture2D texture = www.texture;
        byte[] image_data = www.bytes;
    }
}

File相关命令在webgl中是无法使用的,所以如果程序发布webgl版本,只能使用WWW读取文件。

2. 拍照获取

首先用 Webtexture 获取摄像头并显示图像:

IEnumerator OpenCamera()
{
    //wait for authorization
    yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);

    if (Application.HasUserAuthorization(UserAuthorization.WebCam))
    {
        WebCamDevice[] device = WebCamTexture.devices;
        WebCamTexture webcam = new WebCamTexture(device[0].name, Screen.width, Screen.height, 12);
        //MeshRenderer mesh
        mesh.material.mainTexture = webcam;
        webcam.Play();
    }
}

然后创建一个拍照的Button,添加截图代码:

public void TakePhoto()
{
    Texture2D texture2d = new Texture2D(webcam.width, webcam.height, TextureFormat.ARGB32, true);
    texture2d.SetPixels(webcam.GetPixels());
    texture2d.Apply();
    
    webcam.Pause();
	
	byte[] image_data = texture2d.EncodeToJPG();
}



调用 Baidu AI

1. 下载并导入SDK

打开 http://ai.baidu.com/sdk ,下载C# 版SDK

根据官方注释,找到 AipSdk.dll 和 Newtonsoft.Json.dll 两个文件:

unity opencv 人体捕捉 unity iphone人脸捕捉_大数据

在Unity 中创建Plugins 文件夹,然后将上面两个文件放进去即可。

另外需修改Unity中的Player setting:
Edit->Project Settings->Player,在Other Settings中将Api Compatibility Level 更改为 .Net2.0,否则导入时会出错。

2. 在百度云中创建应用

在百度云中登陆注册,打开管理控制台,创建人脸识别应用,并获得 API KeySecret Key ,下一步调用中会用到。

百度云这里除了人脸识别还有很多其他应用领域。

unity opencv 人体捕捉 unity iphone人脸捕捉_大数据_02

3. 调用Baidu AI

引入头文件,第二个头文件用于获取人脸识别的JArray数据

using Baidu.Aip.Face;
using Newtonsoft.Json.Linq;

连接Baidu AI 并设置要获取的数据参数

private void Awake()
{
	System.Net.ServicePointManager.ServerCertificateValidationCallback += 
        delegate (object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
                    {
                        return true;           // always accept
                    };

    Face client = new Face("api key", "secret key");
    //load photo 
    //byte[] image_data = File.ReadAllBytes(path);   
    //LoadByWWW(path);

    Dictionary<string, object> options = new Dictionary<string, object>{
        {"face_field", "beauty,age,gender,face_shape,race,landmark" }
    };
}

options 中为想要获取的人脸信息参数,具体可查看文档:
http://ai.baidu.com/docs#/Face-Csharp-SDK/b2c44c0a

4. 获取人脸数据

参考官方文档,将图片信息byte[]转换成 BASE64 的string 形式:

string image = Convert.ToBase64String(image_data);

然后调用上面建立的人脸识别中的Detect方法:

JObject result = client.Detect(image, "BASE64", options);

其中 “result” 即为根据options参数获取到的所有数据,及一些默认数据。形式如下:

unity opencv 人体捕捉 unity iphone人脸捕捉_unity opencv 人体捕捉_03


这些数据是以JArray的形式存储的,如需要获取具体参数可参考:

string face_age = result["result"]["face_list"][0]["age"].ToString();

因为百度AI人脸识别中的数据是分层次的,数据获取也需按层级得到。具体层级官方可能会不定时更新,所以还要参考官方文档。

代码中的 [0] 是因为每当遇到层级中的方括号 [ ]时,获取其中数据同获取数组元素。
花括号{ }代表不同层级,其中数据直接按层级索取即可。


示例请参考:

因官方文档更新,示例中一些代码需做调整才可以运行成功。