WebCamTextureToMat.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using OpenCVForUnity;
  2. using OpenCVForUnity.CoreModule;
  3. using OpenCVForUnity.ImgprocModule;
  4. using OpenCVForUnity.UnityUtils;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using UnityEngine;
  8. using UnityEngine.UI;
  9. namespace DiageoWhiskyBlending
  10. {
  11. public class WebCamTextureToMat : MonoBehaviour
  12. {
  13. private WebCamDevice webCamDevice;
  14. private WebCamTexture webCamTexture;
  15. private Mat rgbaMat;
  16. private Color32[] colors;
  17. private bool isInitWaiting = false;
  18. private bool hasInitDone = false; // 如果Init完毕
  19. // ==================================================
  20. private void Start()
  21. {
  22. Init();
  23. }
  24. private void Update()
  25. {
  26. if (hasInitDone && webCamTexture.isPlaying && webCamTexture.didUpdateThisFrame)
  27. {
  28. Utils.webCamTextureToMat(webCamTexture, rgbaMat, colors);
  29. transform.GetComponent<FaceDetecter>().DetectFace(rgbaMat); // 传入mat 检测人脸 // 会导致原数据反转?
  30. // UpdatePreview();
  31. }
  32. }
  33. private void OnDestroy()
  34. {
  35. Dispose();
  36. }
  37. private void OnApplicationQuit()
  38. {
  39. Dispose();
  40. }
  41. // ==================================================
  42. private void Init()
  43. {
  44. if (isInitWaiting)
  45. {
  46. return;
  47. }
  48. StartCoroutine(InitAction());
  49. return;
  50. }
  51. private IEnumerator InitAction()
  52. {
  53. if (hasInitDone) // 防止重复安装
  54. {
  55. Dispose();
  56. }
  57. isInitWaiting = true;
  58. CreateCamera(); // 创建相机
  59. while (true)
  60. {
  61. if (webCamTexture.didUpdateThisFrame)
  62. {
  63. Debug.Log($"Name:{webCamTexture.deviceName} / Width:{webCamTexture.width} / Height:{webCamTexture.height} / FPS:{webCamTexture.requestedFPS}...<color=green>[OK]</color>");
  64. Debug.Log($"VideoRotationAngle:{webCamTexture.videoRotationAngle} / VideoVerticallyMirrored:{webCamTexture.videoVerticallyMirrored} / IsFrongFacing:{webCamDevice.isFrontFacing}...<color=green>[OK]</color>");
  65. isInitWaiting = false;
  66. hasInitDone = true;
  67. if (colors == null || colors.Length != webCamTexture.width * webCamTexture.height) // 确定color尺寸
  68. {
  69. colors = new Color32[webCamTexture.width * webCamTexture.height];
  70. }
  71. if (orginalPreviewTexture2D == null || orginalPreviewTexture2D.width != webCamTexture.width || orginalPreviewTexture2D.height != webCamTexture.height) // 确定texture2d尺寸
  72. {
  73. orginalPreviewTexture2D = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.RGBA32, false);
  74. }
  75. rgbaMat = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC4, new Scalar(0, 0, 0, 255)); // 高、宽
  76. // UpdatePreview();
  77. break;
  78. }
  79. else
  80. {
  81. yield return null;
  82. }
  83. }
  84. yield break;
  85. }
  86. // ==================================================
  87. // 释放资源
  88. // DONE
  89. private void Dispose()
  90. {
  91. isInitWaiting = false;
  92. hasInitDone = false;
  93. if (webCamTexture != null)
  94. {
  95. webCamTexture.Stop();
  96. Destroy(webCamTexture);
  97. webCamTexture = null;
  98. }
  99. if (rgbaMat != null)
  100. {
  101. rgbaMat.Dispose();
  102. rgbaMat = null;
  103. }
  104. if (orginalPreviewTexture2D != null)
  105. {
  106. Destroy(orginalPreviewTexture2D);
  107. orginalPreviewTexture2D = null;
  108. }
  109. return;
  110. }
  111. // ==================================================
  112. // 按钮
  113. public void OnPlayButtonClick()
  114. {
  115. if (hasInitDone)
  116. {
  117. webCamTexture.Play();
  118. }
  119. return;
  120. }
  121. public void OnPauseButtonClick()
  122. {
  123. if (hasInitDone)
  124. {
  125. webCamTexture.Pause();
  126. }
  127. return;
  128. }
  129. public void OnStopButtonClick()
  130. {
  131. if (hasInitDone)
  132. {
  133. webCamTexture.Stop();
  134. }
  135. return;
  136. }
  137. // ==================================================
  138. // 相机配置
  139. // DONE
  140. private string requestedDeviceName = "Logitech BRIO";
  141. // private string requestedDeviceName = "GC21 Video";
  142. private int requestedWidth = 440;
  143. private int requestedHeight = 440;
  144. private int requestedFPS = 30;
  145. private void CreateCamera()
  146. {
  147. foreach (WebCamDevice device in WebCamTexture.devices)
  148. {
  149. if (device.name == requestedDeviceName)
  150. {
  151. webCamDevice = device;
  152. webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS);
  153. webCamTexture.Play();
  154. }
  155. }
  156. return;
  157. }
  158. // ==================================================
  159. // 预览画面
  160. public Image ImageOrginalPreview;
  161. private Texture2D orginalPreviewTexture2D;
  162. private void UpdatePreview()
  163. {
  164. if (!ImageOrginalPreview)
  165. {
  166. return;
  167. }
  168. Utils.matToTexture2D(rgbaMat, orginalPreviewTexture2D, colors); // Mat更新为texture2d
  169. // texture2D = RotateTexutre(texture2D, false);
  170. ImageOrginalPreview.sprite = Sprite.Create(orginalPreviewTexture2D, new UnityEngine.Rect(0, 0, orginalPreviewTexture2D.width, orginalPreviewTexture2D.height), Vector2.zero);
  171. return;
  172. }
  173. // ==================================================
  174. // Texture画面旋转
  175. // private Texture2D RotateTexutre(Texture2D originalTexture, bool clockwise)
  176. // {
  177. // Color32[] original = originalTexture.GetPixels32();
  178. // Color32[] rotated = new Color32[original.Length];
  179. // int w = originalTexture.width;
  180. // int h = originalTexture.height;
  181. // int iRotated, iOriginal;
  182. // for (int j = 0; j < h; ++j)
  183. // {
  184. // for (int i = 0; i < w; ++i)
  185. // {
  186. // iRotated = (i + 1) * h - j - 1;
  187. // iOriginal = clockwise ? original.Length - 1 - (j * w + i) : j * w + i;
  188. // rotated[iRotated] = original[iOriginal];
  189. // }
  190. // }
  191. // Texture2D newTexture = new Texture2D(originalTexture.height, originalTexture.width, TextureFormat.RGBA32, false);
  192. // newTexture.SetPixels32(rotated);
  193. // newTexture.Apply();
  194. // return newTexture;
  195. // }
  196. }
  197. }