using OpenCVForUnity.CoreModule; using OpenCVForUnity.UnityUtils; using Serenegiant.UVC; using System; using System.Collections; using UnityEngine; namespace Yoga { public class MotionUSBCameraCaptureManager : CaptureManagerBase, IUVCDrawer { private Material _flipImg; private void Awake() { _flipImg = Resources.Load("Materials/Unlit_FlipHorizontal"); InvokeRepeating("GCCollection", 0, 1f); } protected void GCCollection() { if (_isOnCamCapture && enabled == true && gameObject.activeInHierarchy == true) StartCoroutine(CleanUp()); } protected IEnumerator CleanUp() { GC.Collect(); yield return Resources.UnloadUnusedAssets(); GC.Collect(); } protected override void ManagerEnable() { GlobalData.Instance.IsFlip = true; } protected override void ManagerDisable() { GlobalData.Instance.IsFlip = false; } protected override Mat GetMat() { Mat img = null; if (UVCManager.Instance != null && UVCManager.Instance.GetAttachedDevices() != null && UVCManager.Instance.GetAttachedDevices().Count > 0) { var devices = UVCManager.Instance.GetAttachedDevices(); for (int i = 0; i < devices.Count; i++) { UVCManager.CameraInfo device = devices[i]; } var index = PlayerPrefs.GetInt("USBCameraIndex"); if (index >= devices.Count || index < 0) //数量超出时候改为默认第一个 index = 0; if (devices[index].previewTexture == null) throw new Exception("No preview Texture found!"); var tmpTex = new Texture2D(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight); textureToFlipTexture2D(devices[index].previewTexture, tmpTex); img = new Mat(UVCManager.Instance.DefaultHeight, UVCManager.Instance.DefaultWidth, CvType.CV_8UC3); Utils.texture2DToMat(tmpTex, img); } return img; } private void textureToFlipTexture2D(Texture texture, Texture2D texture2D) { if (texture == null) throw new ArgumentNullException("texture"); if (texture2D == null) throw new ArgumentNullException("texture2D"); if (texture.width != texture2D.width || texture.height != texture2D.height) throw new ArgumentException("texture and texture2D need to be the same size."); RenderTexture prevRT = RenderTexture.active; RenderTexture tempRT = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32); Graphics.Blit(texture, tempRT, _flipImg); RenderTexture.active = tempRT; texture2D.ReadPixels(new UnityEngine.Rect(0f, 0f, texture.width, texture.height), 0, 0, false); texture2D.Apply(false, false); RenderTexture.ReleaseTemporary(tempRT); RenderTexture.active = prevRT; } protected override void MatInitial() { if (UVCManager.Instance == null) throw new Exception("没有连接USB摄像头"); } #region UVC public UVCFilter[] UVCFilters; private Texture SavedTexture; public bool OnUVCAttachEvent(UVCManager manager, UVCDevice device) { var result = !device.IsRicoh || device.IsTHETA; result &= UVCFilter.Match(device, UVCFilters); return result; } public void OnUVCDetachEvent(UVCManager manager, UVCDevice device) { LogPrint.Log("OnUVCDetachEvent " + device); } public bool CanDraw(UVCManager manager, UVCDevice device) { return UVCFilter.Match(device, UVCFilters); } public void OnUVCStartEvent(UVCManager manager, UVCDevice device, Texture tex) { HandleOnStartPreview(tex); } public void OnUVCStopEvent(UVCManager manager, UVCDevice device) { HandleOnStopPreview(); } private void HandleOnStartPreview(Texture tex) { SavedTexture = TargetDisplayer.texture; _displayTexture = new Texture2D(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight, TextureFormat.RGB24, false); TargetDisplayer.texture = _displayTexture; } private void HandleOnStopPreview() { RestoreTexture(); } private void RestoreTexture() { try { transform.GetComponent().material.mainTexture = SavedTexture; } catch (Exception e) { Debug.LogException(e); } SavedTexture = null; } #endregion } }