From b5db17278f39c14bb913924953a4ac8c8e39abf6 Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Thu, 25 Sep 2025 15:35:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A3=80=E6=B5=8B=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Wpf_AiSportsMicrospace/Common/SportOperate.cs | 85 +++++++++++++++++++ Wpf_AiSportsMicrospace/Home.xaml.cs | 83 ++++++++---------- .../MyUserControl/CoverFlowControl1.xaml | 13 ++- .../MyUserControl/CoverFlowControl1.xaml.cs | 43 ++++++---- 4 files changed, 157 insertions(+), 67 deletions(-) create mode 100644 Wpf_AiSportsMicrospace/Common/SportOperate.cs diff --git a/Wpf_AiSportsMicrospace/Common/SportOperate.cs b/Wpf_AiSportsMicrospace/Common/SportOperate.cs new file mode 100644 index 0000000..1095f51 --- /dev/null +++ b/Wpf_AiSportsMicrospace/Common/SportOperate.cs @@ -0,0 +1,85 @@ +using HandyControl.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Yztob.AiSports.Inferences.Abstractions; +using Yztob.AiSports.Inferences.Things; +using Yztob.AiSports.Postures; +using Yztob.AiSports.Postures.Abstractions; +using Yztob.AiSports.Postures.Sports; +using Yztob.AiSports.Postures.Things; +using Yztob.AiSports.Sensors.Abstractions; +using Yztob.AiSports.Sensors.Things; + +namespace Wpf_AiSportsMicrospace.Common +{ + /// + /// 运动检测操作类 + /// + public class SportOperate + { + private DateTime _lastSlideTime = DateTime.MinValue; + public WebcamClient CreateRTSP() + { + WebcamClient webcamClient = WebcamClient.CreateRTSP("192.168.3.64", "admin", "yd708090", 554u); + return webcamClient; + } + + /// + /// 验证挥手动作[0:无效,1:左,2:右] + /// + /// + public int VerifyWavingAction(Human human) + { + IPointTracker _leftTracker = PostureCalculate.CreatePointTracker("left_wrist", 0); + IPointTracker _rightTracker = PostureCalculate.CreatePointTracker("right_wrist", 0); + IPointTracker _leftElbow = PostureCalculate.CreatePointTracker("left_elbow", 0); + IPointTracker _rightElbow = PostureCalculate.CreatePointTracker("right_elbow", 0); + + _leftTracker.Amplitude = 0.05f; + _rightTracker.Amplitude = 0.05f; + _leftElbow.Amplitude = 0.05f; + _rightElbow.Amplitude = 0.05f; + + 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 0; + _lastSlideTime = DateTime.Now; + + // 根据手势结果选择滑动方向 + if (leftResult != 0 && leftElbowResult != 0) return 1; + if (rightResult != 0 & rightElbowResult != 0) return 2; + + return 0; + } + + + public int VerifyLiftHandAction(Human human) + { + IPointTracker _rightTracker = PostureCalculate.CreatePointTracker("right_wrist", 0); + IPointTracker _rightElbow = PostureCalculate.CreatePointTracker("right_elbow", 0); + + _rightTracker.Amplitude = 0.05f; + _rightElbow.Amplitude = 0.05f; + + var rightResult = _rightTracker.Tracking(human); + var rightElbowResult = _rightElbow.Tracking(human); + + // 节流:每 300ms 最多更新一次 UI + if ((DateTime.Now - _lastSlideTime).TotalMilliseconds < 500) return 0; + _lastSlideTime = DateTime.Now; + + // 根据手势结果选择滑动方向 + if (rightResult != 0 & rightElbowResult != 0) return 1; + + return 0; + } + } +} diff --git a/Wpf_AiSportsMicrospace/Home.xaml.cs b/Wpf_AiSportsMicrospace/Home.xaml.cs index f93599f..bd49f04 100644 --- a/Wpf_AiSportsMicrospace/Home.xaml.cs +++ b/Wpf_AiSportsMicrospace/Home.xaml.cs @@ -1,4 +1,5 @@ -using Microsoft.ML.Runtime; + +using Microsoft.ML.Runtime; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -34,11 +35,10 @@ namespace Wpf_AiSportsMicrospace private readonly List _sports; private SportBase _sport; private readonly SportDetectionQueue _detectQueue; - private IPointTracker _leftTracker; - private IPointTracker _rightTracker; - private IPointTracker _leftElbow; - private IPointTracker _rightElbow; private WebcamClient _webcamClient; + private DateTime _lastSlideTime = DateTime.MinValue; + + private SportOperate _sportOperate; public Home() { @@ -74,35 +74,15 @@ 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); + _sportOperate = new SportOperate(); - //_leftTracker.Amplitude = 0.05f; - //_rightTracker.Amplitude = 0.05f; - - //_leftElbow.Amplitude = 0.05f; - //_rightElbow.Amplitude = 0.05f; - - //LoadRTSP(); - } - - private void LoadRTSP() - { - //_sport.Reset(); - //_sport.Start(); - //_detectQueue.Start(); - - _webcamClient = WebcamClient.CreateRTSP("192.168.3.64", "admin", "yd708090", 554u); + _webcamClient = _sportOperate.CreateRTSP(); //处理抽帧回调 _webcamClient.OnExtractFrame += this.OnFrameExtracted; _webcamClient.StartExtract();//开始抽帧 } - private DateTime _lastSlideTime = DateTime.MinValue; - private void OnFrameExtracted(VideoFrame frame) { if (frame == null) return; @@ -119,37 +99,38 @@ namespace Wpf_AiSportsMicrospace 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 + .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(); + //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 (human == null) return; + //检测挥手动作 + var wavingAction = _sportOperate.VerifyWavingAction(human); // 根据手势结果选择滑动方向 - if (leftResult != 0 && leftElbowResult != 1) + if (wavingAction == 1) { SlideCoverFlow(coverFlow.SlideRight); } - if (rightResult != 0 & rightElbowResult != 1) + if (wavingAction == 2) { SlideCoverFlow(coverFlow.SlideLeft); } + + //检测举手动作 + var liftHandAction = _sportOperate.VerifyLiftHandAction(human); + + // 根据手势结果选择滑动方向 + if (wavingAction == 1) + { + // 启动进度条动画; + SlideCoverFlow(coverFlow.StartSelectedProgress); + } } catch (Exception ex) { @@ -173,5 +154,11 @@ namespace Wpf_AiSportsMicrospace } }), System.Windows.Threading.DispatcherPriority.Background); } + + private void Button_Click(object sender, RoutedEventArgs e) + { + // 启动进度条动画; + SlideCoverFlow(coverFlow.StartSelectedProgress); + } } } diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml index affadd0..3715957 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml +++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml @@ -34,12 +34,19 @@ - - + + + + + + + + - + diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs index 058578d..6bff3e8 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs +++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs @@ -46,8 +46,8 @@ namespace Wpf_AiSportsMicrospace.MyUserControl UpdateLayoutWithAnimation(); // 启动进度条动画 - var current = Images[_selectedIndex]; - StartProgress(current); + //var current = Images[_selectedIndex]; + //StartProgress(current); } } @@ -72,7 +72,19 @@ namespace Wpf_AiSportsMicrospace.MyUserControl private CoverFlowItem _currentItem; - private void StartProgress(CoverFlowItem item) + /// + /// 针对当前选中项启动进度条动画 + /// + public void StartSelectedProgress() + { + if (SelectedIndex >= 0 && SelectedIndex < Images.Count) + { + var current = Images[SelectedIndex]; + StartProgress(current); + } + } + + public void StartProgress(CoverFlowItem item) { StopProgress(); @@ -91,7 +103,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl { if (_currentItem.Progress < 1) { - _currentItem.Progress += 0.002; // 控制速度 + _currentItem.Progress += 0.00556; // 控制速度 if (spark != null) { var pos = GetSparkPosition(_currentItem.Progress, 150, 200); @@ -164,7 +176,6 @@ namespace Wpf_AiSportsMicrospace.MyUserControl private void UpdateLayoutWithAnimation(bool instant = false) { - double centerX = ActualWidth / 2; double spacing = 180; double sideScale = 0.8; @@ -229,18 +240,18 @@ namespace Wpf_AiSportsMicrospace.MyUserControl new DoubleAnimation(targetOpacity, TimeSpan.FromMilliseconds(400))); } - var item = Images[i]; + //var item = Images[i]; - if (i == SelectedIndex) - { - item.IsSelected = true; - StartProgress(item); // 开始绘制进度条 + 火花 - } - else - { - item.IsSelected = false; - StopProgress(); // 停止并重置进度 - } + //if (i == SelectedIndex) + //{ + // item.IsSelected = true; + // StartProgress(item); // 开始绘制进度条 + 火花 + //} + //else + //{ + // item.IsSelected = false; + // StopProgress(); // 停止并重置进度 + //} } }