Health/Assets/Scripts/UI/Component/USBFaceDetectManager.cs

249 lines
8.0 KiB
C#
Raw Normal View History

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()
{
//摄像头问题 需要反转
GlobalData.Instance.IsFlip = true;
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()
{
//摄像头问题,需要反转
GlobalData.Instance.IsFlip = false;
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 textureToTargetPosTexture2D(Texture texture, Texture2D texture2D, bool isFlip)
{
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);
if (isFlip)
Graphics.Blit(texture, tempRT, _flipImg);
else
Graphics.Blit(texture, tempRT);
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();
if (GlobalData.Instance.IsFlip)
{
textureToFlipTexture2D(devices.FirstOrDefault().previewTexture, _videoTexture);
textureToTargetPosTexture2D(devices.FirstOrDefault().previewTexture, _cutTexture, true);
}
else
{
Utils.textureToTexture2D(devices.FirstOrDefault().previewTexture, _videoTexture);
textureToTargetPosTexture2D(devices.FirstOrDefault().previewTexture, _cutTexture, false);
}
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
}