WebCamTextureToMat.cs 6.0 KB

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