229 lines
7.4 KiB
C#
229 lines
7.4 KiB
C#
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
|
||
}
|