BaiduBodySegmentManager.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.Networking;
  6. using Newtonsoft.Json;
  7. using UnityEngine.Events;
  8. using ToneTuneToolkit.Common;
  9. public class BaiduBodySegmentManager : SingletonMaster<BaiduBodySegmentManager>
  10. {
  11. public static UnityAction<Texture2D, int> OnSegmentFinished;
  12. #region Info
  13. private const string CLIENTID = @"2fClRTA6uqf8WMMs3oYetrtN";
  14. private const string CLIENTSECRET = @"9K1HQItadDrPdFizDJkRh5bzWwi1O1tJ";
  15. private const string TOKENURL = @"https://aip.baidubce.com/oauth/2.0/token";
  16. private const string BODYSEGURL = @"https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg?access_token=";
  17. private string token = @"25.0acc4e48d0f7450dd320126240dbaa7c.315360000.2037861152.282335-101570444"; // 后续会Get // 可以用一个月
  18. #endregion
  19. private TokenJson tokenJson;
  20. private ResultJson resultJson;
  21. // ==================================================
  22. #region 上传包
  23. [SerializeField] private Texture2D t2dOrigin;
  24. [SerializeField] private Texture2D t2dResult;
  25. [SerializeField] private int flag;
  26. public void UpdatePackage(Texture2D value, int flagValue)
  27. {
  28. t2dOrigin = value;
  29. flag = flagValue;
  30. return;
  31. }
  32. #endregion
  33. // ==================================================
  34. /// <summary>
  35. /// 人像分割
  36. /// </summary>
  37. public void StartBodySegment() => StartCoroutine(nameof(BodySegmentAction));
  38. private IEnumerator BodySegmentAction()
  39. {
  40. #region GetToken // 获取Token
  41. string url = $"{TOKENURL}?client_id={CLIENTID}&client_secret={CLIENTSECRET}&grant_type=client_credentials";
  42. using (UnityWebRequest uwr = UnityWebRequest.PostWwwForm(url, ""))
  43. {
  44. uwr.SetRequestHeader("Content-Type", "application/json");
  45. uwr.SetRequestHeader("Accept", "application/json");
  46. yield return uwr.SendWebRequest();
  47. if (uwr.result != UnityWebRequest.Result.Success)
  48. {
  49. Debug.LogError(@$"[BBSM] {uwr.error}");
  50. yield break;
  51. }
  52. try
  53. {
  54. tokenJson = JsonConvert.DeserializeObject<TokenJson>(uwr.downloadHandler.text);
  55. token = tokenJson.access_token;
  56. }
  57. catch
  58. {
  59. Debug.Log("[BBSM] Token Analyze Failed.");
  60. RetryBodySegment();
  61. }
  62. }
  63. #endregion
  64. #region BodySegment // 人像分割
  65. WWWForm form = new WWWForm();
  66. form.AddField("image", Texture2Base64(t2dOrigin));
  67. using (UnityWebRequest uwr = UnityWebRequest.Post(BODYSEGURL + token, form))
  68. {
  69. uwr.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  70. yield return uwr.SendWebRequest();
  71. if (uwr.result != UnityWebRequest.Result.Success)
  72. {
  73. Debug.LogError(@$"[BBSM] {uwr.error}");
  74. yield break;
  75. }
  76. try
  77. {
  78. resultJson = JsonConvert.DeserializeObject<ResultJson>(uwr.downloadHandler.text);
  79. string foregroundBase64 = resultJson.foreground;
  80. if (!string.IsNullOrEmpty(foregroundBase64)) // 判断是否有图
  81. {
  82. Texture2D result = Base642Texture(foregroundBase64);
  83. t2dResult = result;
  84. // 保存至本地?
  85. retryTime = 0;
  86. if (OnSegmentFinished != null)
  87. {
  88. OnSegmentFinished(result, flag);
  89. }
  90. }
  91. else
  92. {
  93. // 重拍???
  94. Debug.LogError("[BBSM] Error foreground image null");
  95. retryTime = 0;
  96. if (OnSegmentFinished != null)
  97. {
  98. OnSegmentFinished(null, flag); // 没拍到 // 传空的回去
  99. }
  100. }
  101. }
  102. catch
  103. {
  104. Debug.Log("[BBSM] Image Analyze Failed.");
  105. RetryBodySegment();
  106. }
  107. #endregion
  108. yield break;
  109. }
  110. }
  111. private int retryTime = 0;
  112. private const int RETRYTIMELIMIT = 3;
  113. private void RetryBodySegment() => StartCoroutine(nameof(RetryBodySegmentAction));
  114. private IEnumerator RetryBodySegmentAction()
  115. {
  116. if (retryTime >= RETRYTIMELIMIT)
  117. {
  118. yield break;
  119. }
  120. yield return new WaitForSeconds(3f);
  121. retryTime++;
  122. Debug.Log($"[BBSM] Retry {retryTime} time(s).");
  123. StartBodySegment();
  124. yield break;
  125. }
  126. // ==================================================
  127. // 工具类
  128. /// <summary>
  129. /// 贴图转Base64
  130. /// </summary>
  131. /// <param name="value"></param>
  132. /// <returns></returns>
  133. public static string Texture2Base64(Texture2D value)
  134. {
  135. if (value == null)
  136. {
  137. return null;
  138. }
  139. Texture2D texture2d = new Texture2D(value.width, value.height, TextureFormat.RGBA32, false);
  140. texture2d.SetPixels(value.GetPixels());
  141. texture2d.Apply();
  142. byte[] bytes = texture2d.EncodeToPNG();
  143. string base64String = Convert.ToBase64String(bytes);
  144. return base64String;
  145. }
  146. /// <summary>
  147. /// Base64转贴图
  148. /// </summary>
  149. /// <param name="value"></param>
  150. /// <returns></returns>
  151. public static Texture2D Base642Texture(string value)
  152. {
  153. if (value == null)
  154. {
  155. return null;
  156. }
  157. byte[] bytes = Convert.FromBase64String(value);
  158. Texture2D texture2d = new Texture2D(1, 1);
  159. texture2d.LoadImage(bytes);
  160. return texture2d;
  161. }
  162. // /// <summary>
  163. // /// 保存至本地
  164. // /// </summary>
  165. // private void Save2Local(Texture2D value)
  166. // {
  167. // string path = @$"{Application.dataPath}/{DateTime.Now:yyyy-MM-dd-HH-mm-ss}-{new System.Random().Next(0, 100)}.png";
  168. // byte[] bytes = value.EncodeToPNG();
  169. // File.WriteAllBytes(path, bytes);
  170. // Debug.Log(path);
  171. // return;
  172. // }
  173. // ==================================================
  174. // 数据类
  175. [Serializable]
  176. public class TokenJson
  177. {
  178. public string refresh_token;
  179. public int expires_in;
  180. public string session_key;
  181. public string access_token;
  182. public string scope;
  183. public string session_secret;
  184. }
  185. [Serializable]
  186. public class ResultJson
  187. {
  188. public string log_id;
  189. public string labelmap;
  190. public string scoremap;
  191. public string foreground;
  192. public string person_num;
  193. public object person_info;
  194. }
  195. }