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);
+ }
+ }
+}