diff --git a/Wpf_AiSportsMicrospace/Home.xaml.cs b/Wpf_AiSportsMicrospace/Home.xaml.cs index f93599f..3bcda19 100644 --- a/Wpf_AiSportsMicrospace/Home.xaml.cs +++ b/Wpf_AiSportsMicrospace/Home.xaml.cs @@ -1,5 +1,6 @@ using Microsoft.ML.Runtime; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -39,14 +40,17 @@ namespace Wpf_AiSportsMicrospace private IPointTracker _leftElbow; private IPointTracker _rightElbow; private WebcamClient _webcamClient; + private ConcurrentQueue _frameQueue = new(); + private CancellationTokenSource _cts = new(); + private DateTime _lastSlideTime = DateTime.MinValue; public Home() { InitializeComponent(); - //_humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.SingleHigh); - //_objectDetector = ObjectDetectorFactory.CreateSportGoodsDetector(); - //_humanGraphicsRenderer = new HumanGraphicsRenderer(); - //_humanGraphicsRenderer.DrawLabel = false; + _humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.SingleHigh); + _objectDetector = ObjectDetectorFactory.CreateSportGoodsDetector(); + _humanGraphicsRenderer = new HumanGraphicsRenderer(); + _humanGraphicsRenderer.DrawLabel = false; //_sports = SportBase.GetSports(); //_detectQueue = new SportDetectionQueue(); @@ -74,91 +78,92 @@ namespace Wpf_AiSportsMicrospace private void Window_Loaded(object sender, RoutedEventArgs e) { - //_leftTracker = PostureCalculate.CreatePointTracker("left_wrist", 0); - //_rightTracker = PostureCalculate.CreatePointTracker("right_wrist", 0); - //_leftElbow = PostureCalculate.CreatePointTracker("left_elbow", 0); - //_rightElbow = PostureCalculate.CreatePointTracker("right_elbow", 0); + _leftTracker = PostureCalculate.CreatePointTracker("left_wrist", 0); + _rightTracker = PostureCalculate.CreatePointTracker("right_wrist", 0); + _leftElbow = PostureCalculate.CreatePointTracker("left_elbow", 0); + _rightElbow = PostureCalculate.CreatePointTracker("right_elbow", 0); - //_leftTracker.Amplitude = 0.05f; - //_rightTracker.Amplitude = 0.05f; + _leftTracker.Amplitude = 0.05f; + _rightTracker.Amplitude = 0.05f; - //_leftElbow.Amplitude = 0.05f; - //_rightElbow.Amplitude = 0.05f; + _leftElbow.Amplitude = 0.05f; + _rightElbow.Amplitude = 0.05f; - //LoadRTSP(); + StartRTSP(); + StartFrameProcessing(); } - private void LoadRTSP() + private void StartRTSP() { - //_sport.Reset(); - //_sport.Start(); - //_detectQueue.Start(); - _webcamClient = WebcamClient.CreateRTSP("192.168.3.64", "admin", "yd708090", 554u); - - //处理抽帧回调 - _webcamClient.OnExtractFrame += this.OnFrameExtracted; - _webcamClient.StartExtract();//开始抽帧 + _webcamClient.OnExtractFrame += frame => + { + if (frame != null) + _frameQueue.Enqueue(frame); + }; + _webcamClient.StartExtract(); } - private DateTime _lastSlideTime = DateTime.MinValue; - - private void OnFrameExtracted(VideoFrame frame) + private void StartFrameProcessing() { - if (frame == null) return; - - // 抽帧和人体识别全部在后台线程 Task.Run(() => { - try + while (!_cts.Token.IsCancellationRequested) { - var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray(); - var humanResult = _humanPredictor.Predicting(buffer, frame.Number); - - var humans = humanResult?.Humans?.ToList(); - if (humans == null || humans.Count == 0) - return; - - //var human = humans - // .Where(h => - // h.Keypoints.Any(kp => kp.Name == "left_ankle" && kp.X < 1020 && kp.Y > 900 && kp.Y < 1020) && - // h.Keypoints.Any(kp => kp.Name == "right_ankle" && kp.X > 750 && kp.Y > 900 && kp.Y < 1020) - // ) - // .FirstOrDefault(); - - var human = humans.FirstOrDefault(); - - if (human == null) - return; - - var leftResult = _leftTracker.Tracking(human); - var rightResult = _rightTracker.Tracking(human); - - var leftElbowResult = _leftElbow.Tracking(human); - var rightElbowResult = _rightElbow.Tracking(human); - - // 节流:每 300ms 最多更新一次 UI - if ((DateTime.Now - _lastSlideTime).TotalMilliseconds < 500) return; - _lastSlideTime = DateTime.Now; - - // 根据手势结果选择滑动方向 - if (leftResult != 0 && leftElbowResult != 1) + if (_frameQueue.TryDequeue(out var frame)) { - SlideCoverFlow(coverFlow.SlideRight); + ProcessFrame(frame); } - if (rightResult != 0 & rightElbowResult != 1) + else { - SlideCoverFlow(coverFlow.SlideLeft); + Thread.Sleep(5); } } - catch (Exception ex) - { - Console.WriteLine("OnFrameExtracted error: " + ex.Message); - } - }); + }, _cts.Token); } - // 抽象 UI 更新到方法中 + private void ProcessFrame(VideoFrame frame) + { + try + { + var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray(); + var humanResult = _humanPredictor.Predicting(buffer, frame.Number); + var humans = humanResult?.Humans?.ToList(); + if (humans == null || humans.Count == 0) return; + + var human = humans.FirstOrDefault(); + if (human == null) return; + + var leftResult = _leftTracker.Tracking(human); + var rightResult = _rightTracker.Tracking(human); + var leftElbowResult = _leftElbow.Tracking(human); + var rightElbowResult = _rightElbow.Tracking(human); + + if ((DateTime.Now - _lastSlideTime).TotalMilliseconds < 500) return; + _lastSlideTime = DateTime.Now; + + if (leftResult != 0 && leftElbowResult != 1) + Dispatcher.BeginInvoke(() => coverFlow.SlideRight()); + if (rightResult != 0 && rightElbowResult != 1) + Dispatcher.BeginInvoke(() => coverFlow.SlideLeft()); + } + catch (Exception ex) + { + Console.WriteLine("ProcessFrame error: " + ex.Message); + } + } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + _cts.Cancel(); + _webcamClient?.StopExtract(); + } + + + /// + /// 更新 UI(线程安全) + /// private void SlideCoverFlow(Action slideAction) { Application.Current?.Dispatcher?.BeginInvoke(new Action(() =>