举手会首页
This commit is contained in:
parent
5ea60735e4
commit
6d248c8892
13
Wpf_AiSportsMicrospace/Enum/GameState.cs
Normal file
13
Wpf_AiSportsMicrospace/Enum/GameState.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Enum
|
||||
{
|
||||
public enum GameState
|
||||
{
|
||||
NotStarted, // 游戏未开始
|
||||
Running, // 游戏进行中
|
||||
Finished // 游戏完成
|
||||
}
|
||||
}
|
||||
@ -64,11 +64,12 @@ namespace Wpf_AiSportsMicrospace
|
||||
{
|
||||
_mainWin.HumanFrameUpdated -= OnHumanFrameUpdated;
|
||||
}
|
||||
|
||||
private bool IsGestureActive = true; // 标记手势识别是否有效
|
||||
private void OnHumanFrameUpdated(object sender, List<Human> humans)
|
||||
{
|
||||
var human = humans.FirstOrDefault();
|
||||
if (!IsGestureActive) return; // 手势识别已停止,直接返回
|
||||
|
||||
var human = humans.FirstOrDefault();
|
||||
if (human == null) return;
|
||||
|
||||
// 检测挥手动作
|
||||
@ -93,6 +94,9 @@ namespace Wpf_AiSportsMicrospace
|
||||
|
||||
case (int)WavingAction.RaiseHand: // 举手完成
|
||||
coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
|
||||
|
||||
// 设置标记,停止后续手势识别
|
||||
IsGestureActive = false;
|
||||
break;
|
||||
|
||||
default: // 没有动作 → 取消进度
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Dto;
|
||||
using Emgu.CV.Flann;
|
||||
using Enum;
|
||||
using HandyControl.Controls;
|
||||
using SharpDX.Direct3D9;
|
||||
using System;
|
||||
@ -49,18 +50,20 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
private MediaPlayer _mediaPlayer = new MediaPlayer();
|
||||
List<RankItem> RankingItemList = new();
|
||||
|
||||
private readonly SportDetectionQueue _detectQueue;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
private bool IsGameStarted = false;
|
||||
private GameState _currentGameState = GameState.NotStarted;
|
||||
private readonly object _updateLock = new object();
|
||||
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
|
||||
private GroupJumpRopeContext _groupJumpRopeContext;
|
||||
public GroupJumpRope()
|
||||
{
|
||||
InitializeComponent();
|
||||
_detectQueue = new SportDetectionQueue();
|
||||
Loaded += UserControl_Loaded;
|
||||
Unloaded += UserControl_Unloaded;
|
||||
_groupJumpRopeContext = new GroupJumpRopeContext();
|
||||
@ -162,47 +165,46 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
private void OnHumanFrameUpdated(object sender, List<Human> humans)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsGameStarted)
|
||||
{
|
||||
if (humans == null || humans.Count == 0) return;
|
||||
|
||||
int wavingaction = 0;
|
||||
|
||||
wavingaction = DetectRightHandRaise(humans);
|
||||
|
||||
if (wavingaction < 3)
|
||||
return;
|
||||
|
||||
switch (wavingaction)
|
||||
switch (_currentGameState)
|
||||
{
|
||||
case GameState.NotStarted: // 未开始
|
||||
int rightWaving = DetectRightHandRaise(humans);
|
||||
if (rightWaving >= 3)
|
||||
{
|
||||
switch (rightWaving)
|
||||
{
|
||||
case (int)WavingAction.FirstHand:
|
||||
// 第一次举手,初始化倒计时
|
||||
StartCountdown(3);
|
||||
break;
|
||||
|
||||
case (int)WavingAction.Raising:
|
||||
// 持续倒计时中
|
||||
UpdateCountdown();
|
||||
break;
|
||||
|
||||
case (int)WavingAction.RaiseHand:
|
||||
// 举手完成,倒计时结束
|
||||
FinishCountdown();
|
||||
break;
|
||||
|
||||
default:
|
||||
// 没检测到动作,重置倒计时显示
|
||||
Utils.StopBackgroundMusic();
|
||||
countdownText.Text = "3";
|
||||
countdownGrid.Visibility = Visibility.Hidden;
|
||||
_currentGameState = GameState.Running; // 倒计时完成 → 游戏开始
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case GameState.Running: // 游戏进行中
|
||||
UpdateCircleCounts(humans);
|
||||
|
||||
// 可选:判断游戏结束条件,将状态切换到 Finished
|
||||
// if (CheckGameFinished()) _currentGameState = GameState.Finished;
|
||||
break;
|
||||
|
||||
case GameState.Finished: // 游戏完成
|
||||
int leftWaving = DetectLeftHandRaise(humans);
|
||||
if (leftWaving == 5)
|
||||
{
|
||||
// 举左手逻辑,例如结束动画或退出
|
||||
var newPage = new Home();
|
||||
_mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -210,6 +212,7 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
Console.WriteLine("OnFrameExtracted error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private int _currentCountdown = 3;
|
||||
private DateTime _lastUpdateTime = DateTime.Now;
|
||||
private void StartCountdown(int start = 3)
|
||||
@ -246,11 +249,9 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
{
|
||||
countdownText.Text = "GO!";
|
||||
countdownGrid.Visibility = Visibility.Hidden;
|
||||
IsGameStarted = true;
|
||||
|
||||
// 播放背景音乐(循环)
|
||||
Utils.PlayBackgroundMusic("homeprojectselected1.mp3", true);
|
||||
|
||||
// 启动60秒倒计时(独立任务)
|
||||
StartGameCountdown(60);
|
||||
}
|
||||
@ -273,8 +274,9 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
|
||||
RankingItemList = _groupJumpRopeContext.UpdateRankList();
|
||||
ShowRankingBoard(RankingItemList);
|
||||
IsGameStarted = false;
|
||||
Utils.StopBackgroundMusic();
|
||||
|
||||
_currentGameState = GameState.Finished;
|
||||
}
|
||||
|
||||
private DateTime? _raiseStartTime;
|
||||
@ -367,6 +369,46 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
// 没有任何中心区域内的人举手
|
||||
return (int)WavingAction.None;
|
||||
}
|
||||
public int DetectLeftHandRaise(List<Human> humans)
|
||||
{
|
||||
if (humans == null || humans.Count == 0)
|
||||
return (int)WavingAction.None;
|
||||
|
||||
foreach (var human in humans)
|
||||
{
|
||||
if (human?.Keypoints == null)
|
||||
continue;
|
||||
|
||||
// --- 筛选右脚踝坐标 ---
|
||||
var rightAnkle = human.Keypoints.FirstOrDefault(k => k.Name == "right_ankle");
|
||||
if (rightAnkle == null)
|
||||
continue;
|
||||
double xNorm = rightAnkle.X / 1920;
|
||||
double yNorm = rightAnkle.Y / 1080;
|
||||
// 仅检测中心区域内的人
|
||||
if (!(xNorm >= 0.44 && xNorm <= 0.57 && yNorm >= 0.81))
|
||||
continue;
|
||||
|
||||
|
||||
// 获取左手关键点
|
||||
var leftWrist = human.Keypoints.FirstOrDefault(k => k.Name == "left_wrist");
|
||||
var leftElbow = human.Keypoints.FirstOrDefault(k => k.Name == "left_elbow");
|
||||
|
||||
if (leftWrist == null || leftElbow == null)
|
||||
continue;
|
||||
|
||||
const double raiseThreshold = 60; // 举手阈值
|
||||
|
||||
// 判断左手是否举起
|
||||
double verticalRise = leftWrist.Y - leftElbow.Y;
|
||||
if (verticalRise >= raiseThreshold)
|
||||
{
|
||||
return (int)WavingAction.RaiseHand; // 一旦检测到左手举起,立即返回
|
||||
}
|
||||
}
|
||||
|
||||
return (int)WavingAction.None; // 没有检测到举手
|
||||
}
|
||||
|
||||
private void ResetRaiseState()
|
||||
{
|
||||
@ -529,7 +571,8 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
number3.Text = list[2].Number.ToString();
|
||||
foreach (var item in list)
|
||||
{
|
||||
var grid = new Grid {
|
||||
var grid = new Grid
|
||||
{
|
||||
Width = 1344,
|
||||
Height = 71,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
|
||||
@ -30,6 +30,7 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
private HumanGraphicsRenderer _humanGraphicsRenderer;
|
||||
public SportOperate SportOperate { get; private set; }
|
||||
public WebcamClient WebcamClient { get; private set; }
|
||||
private readonly SportDetectionQueue _detectQueue;
|
||||
private readonly ConcurrentQueue<VideoFrame> _frameQueue = new();
|
||||
private readonly CancellationTokenSource _cts = new();
|
||||
private DateTime _lastFrameTime = DateTime.Now;
|
||||
@ -52,6 +53,7 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
_humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.MultiMedium);
|
||||
_humanGraphicsRenderer = new HumanGraphicsRenderer();
|
||||
_humanGraphicsRenderer.DrawLabel = false;
|
||||
_detectQueue = new SportDetectionQueue();
|
||||
|
||||
SportOperate = new SportOperate();
|
||||
WebcamClient = SportOperate.CreateRTSP();
|
||||
@ -108,6 +110,10 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
var humans = humanResult?.Humans?.ToList();
|
||||
if (humans == null || humans.Count == 0)
|
||||
return;
|
||||
foreach (var human in humans)
|
||||
{
|
||||
_detectQueue.Enqueue(frame.Number, human, null);
|
||||
}
|
||||
|
||||
// 触发全局事件
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user