using OpenCVForUnity.CoreModule; using OpenCVForUnity.ImgprocModule; using OpenCVForUnity.UnityUtils; using System; using System.Collections.Generic; using System.Threading; using UnityEngine; using Yoga; public class CVEstimator : Singleton { private bool isInited = false; public bool IsInited { get => isInited; private set => isInited = value; } public bool IsRunning { get; private set; } private Thread _mainThread; private Thread _estimateThread; private static readonly TimeSpan _refreshRate = TimeSpan.FromSeconds(1 / 30); public void Init(params object[] args) { if (IsInited) { return; } if (_mainThread != null) { _mainThread.Abort(); _mainThread = null; } //加载模型 switch (YogaManager.Instance.LevelData.ModelType) { case ModelType.OpenPose: YogaManager.Instance.CurrentEstimator = new OpenPoseEsimater(); break; case ModelType.MediapipePose: YogaManager.Instance.CurrentEstimator = new MediaPipeEstimator(); break; } YogaManager.Instance.CurrentEstimator.Init(); //IsRunning = false; _mainThread = new Thread(new ThreadStart(MainThread)); _mainThread.Start(); IsInited = true; } private void MainThread() { //解析数据 _estimateThread = new Thread(new ThreadStart(Estimation)); } public void StartEstimation() { if (IsRunning) { return; } if (!IsInited) { Init(); LogPrint.Log("CVEstimator is not inited. ", PrintLevel.Normal); } if (_estimateThread == null) { LogPrint.Error("Estimate Thread fail to load!", PrintLevel.Important); LogPrint.Error($"Main Thread: {_mainThread.ThreadState}"); return; } IsRunning = true; _estimateThread.Start(); } public void StopEstimation() { if (IsRunning) { IsRunning = false; } Dispose(); } public void Dispose() { if (!IsInited) { return; } IsRunning = false; _estimateThread.Abort(); _mainThread.Abort(); IsInited = false; } private void Estimation() { DateTime startTime = DateTime.Now; Mat bgrMat = new Mat(); LogPrint.Log("IsRunning: " + IsRunning); while (IsRunning) { try { Mat rgbaMat = YogaManager.Instance.RgbaMat; if (rgbaMat == null) { //LogPrint.Log("WebCamTexture is null. "); //LogPrint.Log("Re-Estimation."); continue; //重新检测 } Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR); if (!YogaManager.Instance.CurrentEstimator.Esitmate(bgrMat, rgbaMat, out List points)) { //LogPrint.Log("Pose estimation failed. Re-Estimating."); continue; //重新检测 } //更新关键点位检测结果 YogaManager.Instance.AddCurrEstimateKeyPoints(points); //等待到下一个更新周期 if (DateTime.Now - startTime > _refreshRate) { startTime = DateTime.Now; } else { Thread.Sleep(_refreshRate - (DateTime.Now - startTime)); } } catch (Exception e) { LogPrint.Exception(e); } } bgrMat.Dispose(); } }