diff --git a/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_bg.png b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_bg.png new file mode 100644 index 0000000..db002a7 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_bg.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_title.png b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_title.png new file mode 100644 index 0000000..797d361 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_home_title.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_jump.png b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_jump.png new file mode 100644 index 0000000..4a55197 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_jump.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_music.png b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_music.png new file mode 100644 index 0000000..06e7f32 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_music.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_vs.png b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_vs.png new file mode 100644 index 0000000..1e00175 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/play_img/play_vs.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_bg.png b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_bg.png new file mode 100644 index 0000000..4f65775 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_bg.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_title.png b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_title.png new file mode 100644 index 0000000..7be5b26 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_home_title.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_jump.png b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_jump.png new file mode 100644 index 0000000..50ecba5 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_jump.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_rope.png b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_rope.png new file mode 100644 index 0000000..d73b860 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_rope.png differ diff --git a/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_situp.png b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_situp.png new file mode 100644 index 0000000..73001ef Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Img/test_img/test_situp.png differ diff --git a/Wpf_AiSportsMicrospace/Views/CenterHome.xaml b/Wpf_AiSportsMicrospace/Views/CenterHome.xaml new file mode 100644 index 0000000..78a778d --- /dev/null +++ b/Wpf_AiSportsMicrospace/Views/CenterHome.xaml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wpf_AiSportsMicrospace/Views/CenterHome.xaml.cs b/Wpf_AiSportsMicrospace/Views/CenterHome.xaml.cs new file mode 100644 index 0000000..b1947ea --- /dev/null +++ b/Wpf_AiSportsMicrospace/Views/CenterHome.xaml.cs @@ -0,0 +1,253 @@ +using Microsoft.ML.Runtime; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using Wpf_AiSportsMicrospace.Common; +using Wpf_AiSportsMicrospace.Enum; +using Wpf_AiSportsMicrospace.MyUserControl; +using Wpf_AiSportsMicrospace.Views; +using Yztob.AiSports.Inferences.Abstractions; +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.Views +{ + /// + /// Home.xaml 的交互逻辑 + /// + public partial class CenterHome : UserControl + { + private IHumanPredictor _humanPredictor; + private WebcamClient _webcamClient; + private ConcurrentQueue _frameQueue = new(); + private CancellationTokenSource _cts = new(); + private SportOperate _sportOperate; + + public String _nowSelect = "test"; //测试吧:test 游戏吧:play + public String NowSelect + { + get => _nowSelect; + set + { + if (_nowSelect != value) + { + _nowSelect = value; + InitImg(); + } + } + } + + public CenterHome() + { + InitializeComponent(); + _humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.SingleHigh); + + //_sports = SportBase.GetSports(); + //_detectQueue = new SportDetectionQueue(); + + //string imgPath = Path.Combine(projectRoot, "Resources", "Img" , _nowSelect == "test" ? "test_img" : "play_img"); + + // 默认选中第1张 + coverFlow.SelectedIndex = 0; + + InitImg(); + //AnimationBehavior.SetSourceUri(LoadingImage, loadingImage); + } + + private void Window_Loaded(object sender, RoutedEventArgs e) + { + _sportOperate = new SportOperate(); + _webcamClient = _sportOperate.CreateRTSP(); + + _webcamClient.OnExtractFrame += frame => + { + if (frame != null) + _frameQueue.Enqueue(frame); + }; + _webcamClient.StartExtract(); + + StartFrameProcessing(); + + Utils.PlayBackgroundMusic("homeprojectselected.mp3"); + + //coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted; + } + private void CoverFlow_ProgressCompleted(CoverFlowItem item) + { + // 停止抽帧线程/释放资源 + try + { + _cts.Cancel(); // 停止后台处理线程 + _webcamClient?.StopExtract(); // 停止摄像头抽帧 + _webcamClient = null; + + } + catch (Exception ex) + { + Debug.WriteLine($"停止抽帧异常: {ex.Message}"); + } + + // 解绑事件,防止重复触发 + //coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted; + + // 根据图片跳转新窗口 + string uri = item.ImageUri.ToString(); + + //if (uri.EndsWith("1.jpg")) + // newWindow = new GroupJumpRope(); + //else if (uri.EndsWith("2.jpg")) + // newWindow = new GroupJumpRope(); + //else if (uri.EndsWith("3.jpg")) + // newWindow = new GroupJumpRope(); + // 找到主窗口,切换内容到 GroupJumpRopePage + + //var mainWin = Application.Current.MainWindow as Main; + //if (mainWin != null) + //{ + // Utils.PlayBackgroundMusic("musicjumprope1.mp3"); + // mainWin.SwitchPage(new GroupJumpRope(), true); + //} + + RouterGoNew(); + } + + private void StartFrameProcessing() + { + Task.Run(() => + { + while (!_cts.Token.IsCancellationRequested) + { + if (_frameQueue.TryDequeue(out var frame)) + { + ProcessFrame(frame); + } + else + { + //_webcamClient.OnExtractFrame += frame => + //{ + // if (frame != null) + // _frameQueue.Enqueue(frame); + //}; + //_webcamClient.StartExtract(); + + _webcamClient.StartExtract(); + //Thread.Sleep(5); + } + } + }, _cts.Token); + } + + 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 + // .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 wavingaction = _sportOperate.VerifyWavingAction(human); + + // 把低 8 位作为动作类型,高 8 位作为进度 + //int actionType = wavingaction & 0xFF; + //int progress = (wavingaction >> 8) & 0xFF; + + switch (wavingaction) + { + case (int)WavingAction.LeftWave: // 左手挥动 + Dispatcher.BeginInvoke(() => coverFlow.SlideRight()); + break; + + case (int)WavingAction.RightWave: // 右手挥动 + Dispatcher.BeginInvoke(() => coverFlow.SlideLeft()); + break; + + case (int)WavingAction.FirstHand: // 举手开始 + Dispatcher.BeginInvoke(() => coverFlow.StartSelectedProgress()); + break; + + case (int)WavingAction.Raising: // 举手中,实时更新进度 + break; + + case (int)WavingAction.RaiseHand: // 举手完成 + _cts.Cancel(); + coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted; + break; + + default: // 没有动作 → 取消进度 + Dispatcher.BeginInvoke(() => coverFlow.CancelSelectedProgress()); + break; + } + } + catch (Exception ex) + { + Console.WriteLine("OnFrameExtracted error: " + ex.Message); + } + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public void InitImg() + { + string projectRoot = Path.Combine(AppContext.BaseDirectory, @"..\..\.."); + coverFlow.Images.Clear(); // 先清空原有图 + if (_nowSelect == "test") + { + string imgPath = Path.Combine(projectRoot, "Resources", "Img", "test_img"); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "test_jump.png")), ProgressColor1 = "#215bc7", ProgressColor2 = "#fc640e" }); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "test_situp.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#fd8212" }); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "test_rope.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#215bc7" }); + } + else + { + string imgPath = Path.Combine(projectRoot, "Resources", "Img", "play_img"); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "play_vs.png")), ProgressColor1 = "#215bc7", ProgressColor2 = "#fc640e" }); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "play_jump.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#fd8212" }); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(imgPath, "play_music.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#215bc7" }); + } + + } + + //跳转二级页面 + private void RouterGoNew() + { + // 跳转逻辑(如导航到新页面并传递参数) + // 例如:RaiseEvent、调用外部委托、或使用导航框架 + var mainWin = Application.Current.MainWindow as Main; + var newPage = new GroupJumpRope(); + mainWin?.SwitchPage(newPage, true); + } + } +}