当前位置:   article > 正文

UnityC#接入百度SDK实现人脸融合_unity人脸融合

unity人脸融合

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;
    } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

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();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

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; }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143

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);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

本文到此讲解结束,欢迎各位大佬提出宝贵意见以及建议。有项目需求合作也可以加QQ516172386 !!!

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号