# Conflicts:
#	Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs
#	Wpf_AiSportsMicrospace/Views/JumpRope/MusicJumpRope.xaml.cs
This commit is contained in:
ltx 2026-02-03 12:06:39 +08:00
commit c61c3c8a98
2 changed files with 109 additions and 11 deletions

View File

@ -43,7 +43,6 @@ using Yztob.AiSports.Postures;
using Yztob.AiSports.Postures.Sports; using Yztob.AiSports.Postures.Sports;
using Yztob.AiSports.Sensors.Abstractions; using Yztob.AiSports.Sensors.Abstractions;
using Yztob.AiSports.Sensors.Things; using Yztob.AiSports.Sensors.Things;
using static HumanUtils;
using static System.Formats.Asn1.AsnWriter; using static System.Formats.Asn1.AsnWriter;
namespace Wpf_AiSportsMicrospace.Views namespace Wpf_AiSportsMicrospace.Views
@ -67,7 +66,6 @@ namespace Wpf_AiSportsMicrospace.Views
private readonly object _updateLock = new object(); private readonly object _updateLock = new object();
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>(); private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
private GroupJumpRopeContext _groupJumpRopeContext; private GroupJumpRopeContext _groupJumpRopeContext;
private List<CircleArea> _circles;
public GroupJumpRope() public GroupJumpRope()
{ {
@ -148,8 +146,8 @@ namespace Wpf_AiSportsMicrospace.Views
}; };
// 增加图片的大小,调整比例 // 增加图片的大小,调整比例
tipImage.Width = AppSettings.Resolution_X * 0.9; tipImage.Width = 1920 * 0.9; // 宽度为 Canvas 宽度的 90%
tipImage.Height = AppSettings.Resolution_Y * 0.6; tipImage.Height = 1080 * 0.6; // 高度为 Canvas 高度的 60%
// 将图片添加到 Overlay Canvas // 将图片添加到 Overlay Canvas
userBox.Children.Add(tipImage); userBox.Children.Add(tipImage);
@ -196,7 +194,7 @@ namespace Wpf_AiSportsMicrospace.Views
} }
private bool _isCountdownStarted = false; // 新增标记 private bool _isCountdownStarted = false; // 新增标记
public void OnHumanFrameUpdated(object sender, List<Human> humans) private void OnHumanFrameUpdated(object sender, List<Human> humans)
{ {
if (humans == null || humans.Count == 0) return; if (humans == null || humans.Count == 0) return;
//var sportOperate = new SportOperate(); //var sportOperate = new SportOperate();
@ -356,6 +354,78 @@ namespace Wpf_AiSportsMicrospace.Views
private bool _firstHandTriggered; private bool _firstHandTriggered;
private int _lastCountdownSecond = 3; private int _lastCountdownSecond = 3;
private DateTime? _countdownStartTime; private DateTime? _countdownStartTime;
public int DetectRightHandRaise(Human human)
{
var calculator = PostureCalculate.CreateCalculator();
var rule = RaiseHand.RaiseRightHand();
var pass = calculator.Calculating(human, rule);
const double holdDuration = 1; // 持续时间(秒)
const int countdownSeconds = 3; // 倒计时长度
// ---------- 第一步:持续举手触发倒计时 ----------
if (!_firstHandTriggered)
{
if (pass)
{
_raiseStartTime ??= DateTime.Now;
var holdElapsed = (DateTime.Now - _raiseStartTime.Value).TotalSeconds;
if (holdElapsed >= holdDuration)
{
// 举手达到指定时间,启动倒计时
_firstHandTriggered = true;
_countdownStartTime = DateTime.Now;
_lastCountdownSecond = countdownSeconds;
return (int)WavingAction.FirstHand;
}
}
else
{
// 手放下,重置举手开始时间
_raiseStartTime = DateTime.Now;
}
// 没有任何中心区域内的人举手
return (int)WavingAction.None;
}
// ---------- 第二步:倒计时逻辑 ----------
var countdownElapsed = (DateTime.Now - _countdownStartTime.Value).TotalSeconds;
int currentSecond = countdownSeconds - (int)Math.Floor(countdownElapsed);
if (currentSecond > 0 && currentSecond != _lastCountdownSecond)
{
_lastCountdownSecond = currentSecond;
Console.WriteLine($"倒计时:{currentSecond}");
return (int)WavingAction.Raising; // 倒计时中
}
if (countdownElapsed >= countdownSeconds)
{
ResetRaiseState();
return (int)WavingAction.RaiseHand; // 举手完成
}
return (int)WavingAction.Raising;
}
public int DetectLeftHandRaise(Human human)
{
var calculator = PostureCalculate.CreateCalculator();
var rule = RaiseHand.RaiseLeftHand();
var pass = calculator.Calculating(human, rule);
if (pass)
{
// 一旦检测到左手举起,立即返回
return (int)WavingAction.RaiseHand;
}
// 没有检测到举手
return (int)WavingAction.None;
}
private void ResetRaiseState() private void ResetRaiseState()
{ {
@ -406,8 +476,8 @@ namespace Wpf_AiSportsMicrospace.Views
} }
private void UpdateCircleCounts(List<Human> humans) private void UpdateCircleCounts(List<Human> humans)
{ {
double radiusNormX = AppSettings.AreaSize.X; double radiusNormX = 0.07;
double radiusNormY = AppSettings.AreaSize.Y; double radiusNormY = 0.14;
for (int i = 0; i < _groupJumpRopeContext.CirclePositions.Count; i++) for (int i = 0; i < _groupJumpRopeContext.CirclePositions.Count; i++)
{ {

View File

@ -135,8 +135,8 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
}; };
// 增加图片的大小,调整比例 // 增加图片的大小,调整比例
tipImage.Width = AppSettings.Resolution_X * 0.9; // 宽度为 Canvas 宽度的 90% tipImage.Width = 1920 * 0.9; // 宽度为 Canvas 宽度的 90%
tipImage.Height = AppSettings.Resolution_Y * 0.6; // 高度为 Canvas 高度的 60% tipImage.Height = 1080 * 0.6; // 高度为 Canvas 高度的 60%
// 将图片添加到 Overlay Canvas // 将图片添加到 Overlay Canvas
userBox.Children.Add(tipImage); userBox.Children.Add(tipImage);
@ -588,6 +588,34 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
} }
} }
private void UpdateScore(double to, TextBlock score)
{
DoubleAnimation animation = new DoubleAnimation
{
From = double.Parse(score1.Text),
To = to,
Duration = TimeSpan.FromSeconds(0.2),
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut },
FillBehavior = FillBehavior.HoldEnd
};
score.BeginAnimation(TextBlock.TextProperty, animation);
}
//private void ChangeImgState(int index , string state)
//{
// if(index== 0)
// {
// left1.Visibility = state == "1" ? Visibility.Visible : Visibility.Hidden;
// left2.Visibility = state == "2" ? Visibility.Visible : Visibility.Hidden;
// left3.Visibility = state == "3" ? Visibility.Visible : Visibility.Hidden;
// }else if (index == 1)
// {
// right1.Visibility = state == "1" ? Visibility.Visible : Visibility.Hidden;
// right2.Visibility = state == "1" ? Visibility.Visible : Visibility.Hidden;
// right3.Visibility = state == "1" ? Visibility.Visible : Visibility.Hidden;
// }
//}
public void ShowMusicAnimation() public void ShowMusicAnimation()
{ {
ImageBehavior.SetRepeatBehavior(leftm, RepeatBehavior.Forever); ImageBehavior.SetRepeatBehavior(leftm, RepeatBehavior.Forever);
@ -598,8 +626,8 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
private void UpdateCircleCounts(List<Human> humans) private void UpdateCircleCounts(List<Human> humans)
{ {
double radiusNormX = AppSettings.Resolution_X; double radiusNormX = 0.07;
double radiusNormY = AppSettings.Resolution_Y; double radiusNormY = 0.14;
for (int i = 0; i < _musicJumpRopeContext.CirclePositions.Count; i++) for (int i = 0; i < _musicJumpRopeContext.CirclePositions.Count; i++)
{ {