using OpenCVCompact; using Serenegiant.UVC; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; public class USBFaceDetectManager : FaceDetectManagerBase, IUVCDrawer { public RawImage image; public RawImage cutImage; private Material _flipImg; private int[] _positionRect; public int[] PositionRect { get { if (_positionRect == null) _positionRect = PictureUtility.GetPositionRect(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight); return _positionRect; } } protected override void InitMatHelper() { _flipImg = new Material(Shader.Find("Unlit/FlipHorizontal")); ; InvokeRepeating("GCCollection", 0, 1f); } private void OnEnable() { mat4Display = new Mat(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight, CvType.CV_8UC4); mat4Process = new Mat(PositionRect[2] - PositionRect[0], PositionRect[3] - PositionRect[1], CvType.CV_8UC4); mat4DisplayTexture = new Mat(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight, CvType.CV_8UC4); _videoTexture = new Texture2D(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight, TextureFormat.RGBA32, false); _cutTexture = new Texture2D(PositionRect[2] - PositionRect[0], PositionRect[3] - PositionRect[1], TextureFormat.RGBA32, false); image.texture = _videoTexture; cutImage.texture = _cutTexture; } private void OnDisable() { Destroy(_videoTexture); Destroy(_cutTexture); _videoTexture = null; _cutTexture = null; mat4Display.Dispose(); mat4Process.Dispose(); mat4DisplayTexture.Dispose(); } protected void GCCollection() { if (enabled == true && gameObject.activeInHierarchy == true) StartCoroutine(CleanUp()); } protected IEnumerator CleanUp() { GC.Collect(); yield return Resources.UnloadUnusedAssets(); GC.Collect(); } protected override Mat GetMat() { return null; } 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; } private void textureToTargetPosTexture2DFlipped(Texture texture, Texture2D texture2D) { if (texture == null) throw new ArgumentNullException("texture"); if (texture2D == null) throw new ArgumentNullException("texture2D"); if (PositionRect[2] - PositionRect[0] > texture.width || PositionRect[3] - PositionRect[1] > texture.height) { LogPrint.Error($"{PositionRect[0]},{PositionRect[1]},{texture.width}||{PositionRect[2]},{PositionRect[3]},{texture.height}"); throw new ArgumentException("取值框超过目标像素最大范围"); } 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(PositionRect[0], PositionRect[1], PositionRect[2] - PositionRect[0], PositionRect[3] - PositionRect[1]), 0, 0, false); texture2D.Apply(false, false); RenderTexture.ReleaseTemporary(tempRT); RenderTexture.active = prevRT; } protected override void AnalyzingFace() { if (UVCManager.Instance == null || UVCManager.Instance.GetAttachedDevices() == null || UVCManager.Instance.GetAttachedDevices().Count <= 0) return; if (image.gameObject.activeInHierarchy != GlobalData.Instance.ShowFaceDetectCameraCaptureImage) image.gameObject.SetActive(GlobalData.Instance.ShowFaceDetectCameraCaptureImage); if (cutImage.gameObject.activeInHierarchy != GlobalData.Instance.ShowFaceDetectCameraCaptureImage) cutImage.gameObject.SetActive(GlobalData.Instance.ShowFaceDetectCameraCaptureImage); var devices = UVCManager.Instance.GetAttachedDevices(); textureToFlipTexture2D(devices.FirstOrDefault().previewTexture, _videoTexture); textureToTargetPosTexture2DFlipped(devices.FirstOrDefault().previewTexture, _cutTexture); Utils.texture2DToMat(_videoTexture, mat4Display); Utils.texture2DToMat(_cutTexture, mat4Process); panel.RefreshData(LandmarkDetect());//Face Detect OpenCVCompact.Rect roiRect = new OpenCVCompact.Rect(PositionRect[0], PositionRect[1], PositionRect[2] - PositionRect[0], PositionRect[3] - PositionRect[1]); Imgproc.rectangle(mat4Display, roiRect, new Scalar(255, 0, 0), 2); //DebugPint(); } protected override void DebugPint() { //image.texture = videoTexture; if (mat4Process.rows() == _cutTexture.height) { Mat cutMat = mat4Process.clone(); Utils.matToTexture2D(cutMat, _cutTexture); } if (mat4Display.rows() == _videoTexture.height) { Mat display = mat4Display.clone(); Utils.matToTexture2D(display, _videoTexture); } } protected override void Dispose() { } #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) { LogPrint.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation); dnnUtils.InitHeadPoseEstimationCameraInfo(UVCManager.Instance.DefaultWidth, UVCManager.Instance.DefaultHeight); } private void HandleOnStopPreview() { RestoreTexture(); } private void RestoreTexture() { try { } catch (Exception e) { Debug.LogException(e); } SavedTexture = null; } #endregion }