http://ai.baidu.com/tech/face/compare
①-获取权限:
using System.Collections;
using UnityEngine;
using LitJson;
namespace XJH
{
public class XGetAccessToken : MonoBehaviour
{
[SerializeField, Header("授权服务地址")]
private string accessUrl = "https://aip.baidubce.com/oauth/2.0/token";
[SerializeField, Header("授权类型")]
private string grant_type = "client_credentials";
[SerializeField, Header("API Key")]
private string client_id = "Nc53cN7Dc7qVac7ok4NCgllY";
[SerializeField, Header("Secret Key")]
private string client_secret = "BDKK180LIkD59p4iCkOskUWlGkWNlbMH";
//获取到的授权码
public static string accessToken = "";//一大长串:24.98f5a647562ba769547802ed8f07f71d.2592000.1515313786.282335-10500874
//提交的表单
private string postUrl;
//接收到的信息
private string resiveMsg;
// Use this for initialization
void Start()
{
CreatePostUrl();
StartCoroutine(WWWGetAccessToken());
}
void CreatePostUrl()
{
postUrl = string.Format("{0}?grant_type={1}&client_id={2}&client_secret={3}&",
accessUrl, grant_type, client_id, client_secret);
Debug.Log("postUrl:" + postUrl);
}
IEnumerator WWWGetAccessToken()
{
using (WWW www = new WWW(postUrl))
{
yield return www;
if (www.isDone)
{
resiveMsg = www.text;
Debug.Log("resiveMsg: " + resiveMsg);
AnalysisJson(resiveMsg);
}
}
}
void JsonUtilityAnalysis(string jsonMsg)
{
//明天再看看unity自带的Json解析
}
void AnalysisJson(string msg)
{
JsonData data = JsonMapper.ToObject(msg);
if (data.GetJsonType() != JsonType.None)
{
//请求成功
string refresh_token = GetJsonValueStr(data, "refresh_token");
string expires_in = GetJsonValueStr(data, "expires_in");
string scope = GetJsonValueStr(data, "scope");
string access_token = GetJsonValueStr(data, "access_token");
string session_secret = GetJsonValueStr(data, "session_secret");
//如果请求错误
string error = GetJsonValueStr(data, "session_secret");
string error_description = GetJsonValueStr(data, "error_description");
accessToken = access_token;
Debug.Log(System.Convert.ToInt32(expires_in) / 3600 / 24 + " days");
Debug.Log("access_token: " + access_token);
}
}
string GetJsonValueStr(JsonData data,string key)
{
if (((IDictionary)data).Contains(key))
{
//Debug.Log(key + ": " + data[key].ToString());
return data[key].ToString();
}
return "";
}
}
}
②工具类(泛型单例)
using UnityEngine;
public class SingleTon : MonoBehaviour where T :MonoBehaviour {
private static T instance;
private static object lockThread = new object();//锁
private static bool isQuit = false;
public static T GetInstance
{
get
{
if (isQuit) return null;
lock (lockThread)
{
if (instance == null)
{
instance = FindObjectOfType(typeof(T)) as T;
if (FindObjectsOfType(typeof(T)).Length > 1)
{
Debug.LogWarning("Too many " + typeof(T).ToString());
return instance;
}
if (instance == null)
{
GameObject singleTon = new GameObject("SingleTon", typeof(T));
instance = singleTon.GetComponent();
DontDestroyOnLoad(singleTon);
}
}
return instance;
}
}
}
}
③图片录入
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;
///
/// 一,提供查询的图片库
/// 二,能录入图片
/// 图片需经过base64编码,仅支持PNG/JPG/JPEG/BMP,不支持GIF
/// 问题:保存图片数组还是每次重新加载?
/// 折中办法:一定时间后清空,需要比对的时候加载(先不做)
///
namespace XJH
{
public class XGetTextureLibrary : SingleTon
{
public string textureFilePath;//图片库的路径
[HideInInspector] public List<string> textureArray = new List<string>();//图片转化为base64,放到list中存起来
public int textureWidth = 512, textureHeight = 512;
private string rootPath;//根目录
void Start()
{
string textName = "Ltext";
TextAsset mytext = Resources.Load(textName) as TextAsset;
byte[] data = mytext.bytes;//获取到文本
string savePath = @Application.persistentDataPath + @"\" + textName + ".txt";
Debug.Log("savePath:" + savePath);
File.WriteAllBytes(savePath, data);
rootPath = GetRootPath(Application.dataPath);//根目录路径
textureFilePath = @rootPath + @"/FaceLibrary";//图片库路径
DirectoryCheck(textureFilePath);//保证有图片库文件夹
GetAllTextures(textureFilePath);
}
//检测,录入图片
private void Update()
{
//截图,存起来
if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Q))
{
StartCoroutine(AddTextureToLibrary());
}
}
public void GetAllTextures(string path)//获取路径下所有的图片
{
DirectoryInfo dInfo = new DirectoryInfo(path);
foreach (FileInfo files in dInfo.GetFiles())
{
textureArray.Add(System.Convert.ToBase64String(LoadTextures(files.FullName)));//添加进list中存起来
}
}
string GetRootPath(string path)//根目录->去掉最后一个/以及其后面的字符串
{
string[] nodes = path.Split('/'); //分割
if (nodes.Length < 2)
{
Debug.LogError("RootPath Error");
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < nodes.Length - 1; i++)
{
sb.Append(nodes[i]);
if (i < nodes.Length - 2)
{
sb.Append("/");
}
}
Debug.Log(sb.ToString());
return sb.ToString();
}
private void DirectoryCheck(string path)//有则过,无则添
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
byte[] LoadTextures(string filePath)//加载成二进制数组
{
try
{
FileStream fs = new FileStream(@filePath, FileMode.Open);
fs.Seek(0, SeekOrigin.Begin);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int)fs.Length);
fs.Close();
fs.Dispose();
fs = null;
return bytes;
}
catch (System.Exception ex)
{
Debug.LogError(ex.Message);
return null;
}
//Texture2D tex = new Texture2D(textureWidth, textureHeight);
//tex.LoadImage(bytes);
}
public IEnumerator AddTextureToLibrary()//图片录入
{
yield return new WaitForEndOfFrame();
Texture2D snap = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
snap.ReadPixels(new Rect(0, 0, snap.width, snap.height), 0, 0, false);
snap.Apply();
byte[] bytes = snap.EncodeToPNG();
string fileName = @"/" + @System.DateTime.Now.ToString("yyy-MM-dd") + (textureArray.Count + 1) + ".png";
File.WriteAllBytes(@textureFilePath + @fileName, bytes);
textureArray.Add(System.Convert.ToBase64String(bytes));
}
}
}
④图片比对
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System;
namespace XJH
{
public class XWWWPost : MonoBehaviour {
[SerializeField, Header("请求URL")]
private string postUrl = "https://aip.baidubce.com/rest/2.0/face/v2/match";
private string imageData; //分别base64编码后的2张图片数据,半角逗号分隔,单次请求总共最大20M
private string extFields; //返回质量信息,取值固定,目前支持qualities(质量检测)(对所有图片都会做改处理)
private string imageLiveness;//返回的活体信息,“faceliveness,faceliveness” 表示对比对的两张图片都做活体检测;
//“,faceliveness” 表示对第一张图片不做活体检测、第二张图做活体检测;“faceliveness,” 表示对第一张图片做活体检测、第二张图不做活体检测
private string types; //请求对比的两张图片的类型,示例:“7,13”
//7表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等
//11表示身份证芯片照:二代身份证内置芯片中的人像照片
//12表示带水印证件照:一般为带水印的小图,如公安网小图
//13表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片,注:需要确保人脸部分不可太小,通常为100px*100px
private bool isRecognition = false;
void Start() {
}
IEnumerator OnWWWPost()
{
isRecognition = true;
yield return null;
WWWForm wwwForm;
WWW www;
int count = XGetTextureLibrary.GetInstance.textureArray.Count;
Debug.Log("count: " + count);
yield return StartCoroutine(XGetTextureLibrary.GetInstance.AddTextureToLibrary()); ;//临时增加一个
List<string> textureArray = XGetTextureLibrary.GetInstance.textureArray;
string screenShot = textureArray[count];
while (--count > 0)//重复调用
{
int childCount = count;
while (--childCount > -1)
{
wwwForm = new WWWForm();
wwwForm.AddField("images", textureArray[count] + "," + textureArray[childCount]);
www = new WWW(postUrl + "?access_token=" + XGetAccessToken.accessToken, wwwForm);
yield return www;
if (www.isDone)
{
Debug.Log("Response: " + www.text);
}
}
}
isRecognition = false;
}
// Update is called once per frame
void Update() {
if (Input.GetKeyDown(KeyCode.Space) && !isRecognition)
{
StartCoroutine(OnWWWPost());
}
}
}
}