赞
踩
Unity版本:2020.3.25,VisualStudio版本:2022;
1:注册登录百度账号
2: 在搜索窗口输入人脸融合,并进入人脸融合页面;
3:选择立即使用进入控制台-创建应用-(应用名称你随意,接口选择全部,没有领取的可以领取新人福利);创建完后点击该应用,准备好复制你的各种Key;
4:新建Unity工程,新建脚本AccessToken.cs 将百度api中人脸融合APIToken请求方法选择C#代码复制到该脚本中。
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UI;
public static class AccessToken
{
// 调用getAccessToken()获取的 access_token建议根据expires_in 时间 设置缓存
public static String TOKEN = "24.adda70c11b9786206253ddb70affdc46.2592000.1493524354.282335-1234567";
public static String getAccessToken(String clientId, String clientSecret)
{
String authHost = "https://aip.baidubce.com/oauth/2.0/token";
HttpClient client = new HttpClient();
List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();
paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
paraList.Add(new KeyValuePair<string, string>("client_id", clientId));
paraList.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
String result = response.Content.ReadAsStringAsync().Result;
return result;
}
// 人脸融合 注意版本。2.0版本是官网示例中的Demo效果,如果接口不定义版本,则默认为1.0,效果不佳。这里使用3.0
public static string faceMerge(string token, string image1, string image2)
{
// string token = "[调用鉴权接口获取的token]";
string host = "https://aip.baidubce.com/rest/2.0/face/v1/merge?access_token=" + token;
Encoding encoding = Encoding.Default;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
request.Method = "post";
request.KeepAlive = true;
String str = "{\"version\": \"3.0\",\"image_template\":{\"image\":\"" + image1 + "\",\"image_type\":\"BASE64\",\"quality_control\":\"NONE\"},\"image_target\":{\"image\":\"" + image2 + "\",\"image_type\":\"BASE64\",\"quality_control\":\"NONE\"}}";
byte[] buffer = encoding.GetBytes(str);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
string result = reader.ReadToEnd();
return result;
}
}
5: 获取电脑摄像头脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class OpenCamera : MonoBehaviour
{
public RawImage showImage;
private WebCamTexture webCamTexture;
void Start()
{
StartCoroutine("IOpenCamera");
}
/// <summary>
/// 打开摄像机
/// </summary>
public IEnumerator IOpenCamera()
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
if (webCamTexture != null)
{
webCamTexture.Stop();
}
//打开渲染图
if (showImage != null)
{
showImage.gameObject.SetActive(true);
}
//if (quad != null)
//{
// quad.gameObject.SetActive(true);
//}
// 监控第一次授权,是否获得到设备(因为很可能第一次授权了,但是获得不到设备,这里这样避免)
// 多次 都没有获得设备,可能就是真没有摄像头,结束获取 camera
int i = 0;
while (WebCamTexture.devices.Length <= 0 && 1 < 300)
{
yield return new WaitForEndOfFrame();
i++;
}
WebCamDevice[] devices = WebCamTexture.devices;//获取可用设备
if (WebCamTexture.devices.Length <= 0)
Debug.LogError("没有获取到摄像头设备!");
else
{
string devicename = devices[0].name;
webCamTexture = new WebCamTexture(devicename, 640,480, 30)
{
wrapMode = TextureWrapMode.Repeat
};
// 渲染到 UI
if (showImage != null)
showImage.texture = webCamTexture;
webCamTexture.Play();
}
}
else
Debug.LogError("未获得读取摄像头权限");
}
private void OnApplicationPause(bool pause)
{
// 应用暂停的时候暂停camera,继续的时候继续使用
if (webCamTexture != null)
{
if (pause)
{
webCamTexture.Pause();
}
else
{
webCamTexture.Play();
}
}
}
private void OnDestroy()
{
if (webCamTexture != null)
{
webCamTexture.Stop();
}
}
}
6:工具类脚本以及数据结构
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using ZXing.QrCode;
using ZXing;
public class Config
{
public static Dictionary<string,Texture2D> maleModen = new Dictionary<string, Texture2D>();
public static Dictionary<string, Texture2D> femaleModen = new Dictionary<string, Texture2D>();
public static List<Sprite> covers = new List<Sprite>();
public static KeyBaiDu baiDuKey = null;
//public static string MODEN_TEXTURE2D=null;
public static string APP_PATH =Application.streamingAssetsPath;
public const string TARGET_PATH = @"D:\Program Files (x86)\DeskTop\Demo\TestTexture\";
public static string SAVEMY_TEXTURE = string.Format("{0}MyPhoto.png", Config.TARGET_PATH);
public static Transform GetChildTrs(Transform parent,string childName)
{
for (int i = 0; i < parent.childCount; i++)
if (parent.GetChild(i).name == childName)
return parent.GetChild(i);
return null;
}
/// <summary>
/// 返回图片纹理
/// </summary>
/// <param name="_strImagePath"></param>
/// <returns></returns>
public static Texture2D GetTexture2d(string _strImagePath)
{
Texture2D tx = new Texture2D(100, 100);
tx.LoadImage(GetImageByte(_strImagePath));
// Sprite sp = Sprite.Create(tx, new Rect(0, 0, tx.width, tx.height), Vector2.zero);
return tx;
}
/// <summary>
/// 根据图片路径返回图片的字节流byte[]
/// </summary>
/// <param name="imagePath">图片路径</param>
/// <returns>返回的字节流</returns>
public static byte[] GetImageByte(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
}
public static void SaveTexture(Texture2D png, string pngName)
{
byte[] bytes = png.EncodeToPNG();
FileStream file = File.Open(Config.APP_PATH + "/" + pngName + ".png", FileMode.Create);
BinaryWriter writer = new BinaryWriter(file);
writer.Write(bytes);
file.Close();
}
public static void SaveTexture(Texture2D png, string path, string pngName)
{
byte[] bytes = png.EncodeToPNG();
FileStream file = File.Open(path + "/" + pngName + ".png", FileMode.Create);
BinaryWriter writer = new BinaryWriter(file);
writer.Write(bytes);
file.Close();
}
/// <summary>
/// base64编码文本转换成Texture
/// </summary>
public static Texture2D Base64ToTexter2d(string Base64STR)
{
Texture2D pic = new Texture2D(200, 200);
byte[] data = System.Convert.FromBase64String(Base64STR);
//File.WriteAllBytes(Application.dataPath + "/BuildImage/Base64ToSaveImage.png", data);
pic.LoadImage(data);
return pic;
}
/// <summary>
/// 图片转换为Base64字符
/// </summary>
/// <param name="texture2D"></param>
/// <returns></returns>
public static string ImgToBase64String(Texture2D texture2D)
{
byte[] buffer = GetBytesFromTexture(texture2D);
string base64String = Convert.ToBase64String(buffer);
return base64String;
}
/// <summary>
/// 图片转换为byte数据
/// </summary>
/// <param name="texture2D"></param>
/// <returns></returns>
public static byte[] GetBytesFromTexture(Texture2D texture2D)
{
RenderTexture renderTex = RenderTexture.GetTemporary(
texture2D.width,
texture2D.height,
0,
RenderTextureFormat.Default,
RenderTextureReadWrite.Linear);
Graphics.Blit(texture2D, renderTex);
RenderTexture previous = RenderTexture.active;
RenderTexture.active = renderTex;
Texture2D readableText = new Texture2D(texture2D.width, texture2D.height);
readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
readableText.Apply();
byte[] bytes = readableText.EncodeToJPG();
return bytes;
}
}
/// <summary>
/// 百度人脸接口Token数据结构
/// </summary>
[Serializable]
public class BaiduAPIKey
{
public string refresh_token { get; set; }
public string expires_in { get; set; }
public string session_key { get; set; }
public string access_token { get; set; }
public string scope { get; set; }
public string session_secret { get; set; }
}
/// <summary>
/// 百度接口人脸识别接口数据返回
/// </summary>
[Serializable]
public class FaceMergeResult
{
public string error_code { get; set; }
public string error_msg { get; set; }
public string log_id { get; set; }
public string timestamp { get; set; }
public string cached { get; set; }
public ResultData result { get; set; }
}
7:接口调用
private string token = null;
FaceMergeResult faceMergeResult = null;
aPIKey = JsonConvert.DeserializeObject<BaiduAPIKey>(AccessToken.getAccessToken(Config.baiDuKey.apiKey, Config.baiDuKey.secretKey));
token = aPIKey.access_token;
/// <summary>
/// 使用异步方式获取百度接口返回结构。同步可以使用Loading进度条等待此结果返回
/// </summary>
/// <returns></returns>
private Task<string> GetWWWTexture()
{
var task = Task.Run(() => {
var imageBase1 = AccessToken.ImgToBase64String(targetTexbyte);//AccessToken.ImgToBase64String(String.Format("{0}/{1}.png", Config.TARGET_PATH, "MyPhoto"));
var imageBase2 = AccessToken.ImgToBase64String(modenTexbyte);//AccessToken.ImgToBase64String(String.Format("{0}/{1}.png", Config.APP_PATH, "moden"));//Config.MODEN_TEXTURE2D));
var reslut = AccessToken.faceMerge(token, imageBase2, imageBase1);
return reslut;
});
return task;
}
/// <summary>
/// 等待结果处理相关逻辑
/// </summary>
async void ChangeFace()
{
var ttt = GetWWWTexture();
await ttt;
faceMergeResult = JsonConvert.DeserializeObject<FaceMergeResult>(ttt.Result);
print(faceMergeResult.error_code);
if (faceMergeResult != null&&faceMergeResult.error_code == "0")
{
var texture = AccessToken.Base64ToTexter2d(faceMergeResult.result.merge_image);
showImage.texture = texture;
showImage.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
byte[] bytes = texture.EncodeToPNG();
System.IO.File.WriteAllBytes(Config.SAVEMY_TEXTURE, bytes);
showImage.SetNativeSize();
showImage.transform.position = ShowImagePos.position;
//showImage.transform.position = new Vector3(temppos.x, temppos.y-80, temppos.z);
UIMgr.Instance.HidePanel("PageWait");
Config.GetChildTrs(buttons, "SaveBtn").GetComponent<Button>().interactable = true;
}
else
{
try
{
UIMgr.Instance.HidePanel("PageWait");
switch (int.Parse(faceMergeResult.error_code))
{
case 223114:
case 223113:
case 222301:
case 222203:
case 222211:
case 222202:
SetErrorTextValue("无法检测人脸,请不要遮挡脸部!");
break;
case 222204:
SetErrorTextValue("下载图片失败,请再次重试!");
break;
case 222205:
case 222206:
SetErrorTextValue("服务端请求失败,请联系工作人员!");
break;
default:
SetErrorTextValue("未知异常,请联系工作人员!");
break;
}
}
catch (Exception e)
{
print(e.Message);
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。