线程组赛

This commit is contained in:
tanglong 2025-09-25 17:12:47 +08:00
parent 99f4bfe607
commit 0de1017593

View File

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