diff --git a/Wpf_AiSportsMicrospace/Common/SportOperate.cs b/Wpf_AiSportsMicrospace/Common/SportOperate.cs
index 3335a80..4c12a8a 100644
--- a/Wpf_AiSportsMicrospace/Common/SportOperate.cs
+++ b/Wpf_AiSportsMicrospace/Common/SportOperate.cs
@@ -28,11 +28,12 @@ namespace Wpf_AiSportsMicrospace.Common
IPointTracker _rightElbow;
WebcamClient _webcamClient;
+ private DateTime _lastActionTime = DateTime.MinValue;
+
private Point? _lastLeftWrist = null;
private Point? _lastRightWrist = null;
- private DateTime _lastActionTime = DateTime.MinValue;
- // 记录举手开始时间
private DateTime? _raiseStartTime = null;
+ private DateTime? _wristStartTime = null;
public SportOperate()
@@ -42,10 +43,10 @@ namespace Wpf_AiSportsMicrospace.Common
_leftElbow = PostureCalculate.CreatePointTracker("left_elbow", 0);
_rightElbow = PostureCalculate.CreatePointTracker("right_elbow", 0);
- _leftTracker.Amplitude = 0.05f;
- _rightTracker.Amplitude = 0.05f;
- _leftElbow.Amplitude = 0.05f;
- _rightElbow.Amplitude = 0.05f;
+ //_leftTracker.Amplitude = 0.05f;
+ //_rightTracker.Amplitude = 0.05f;
+ //_leftElbow.Amplitude = 0.05f;
+ //_rightElbow.Amplitude = 0.05f;
}
public WebcamClient CreateRTSP()
@@ -83,49 +84,82 @@ namespace Wpf_AiSportsMicrospace.Common
}
///
- /// 识别左手动作(左→右为 1)
+ /// 统一的水平挥手检测
///
- public int RecognizeLeftHandGesture(Point wrist, Point elbow)
+ private int DetectHorizontalWave(Point wrist, Point elbow, Point? lastWrist, bool isLeft)
{
- if (_lastLeftWrist != null)
+ if (lastWrist != null)
{
- double dx = wrist.X - _lastLeftWrist.Value.X;
- double dy = Math.Abs(wrist.Y - _lastLeftWrist.Value.Y);
+ double dx = wrist.X - lastWrist.Value.X;
+ double dy = Math.Abs(wrist.Y - lastWrist.Value.Y);
- if (Math.Abs(dx) > 30 && dy < 40)
+ // 挥手:水平位移明显,垂直位移小,且接近肘部水平
+ if (Math.Abs(dx) > 30 && dy < 40 && Math.Abs(wrist.Y - elbow.Y) < 100)
{
if (CheckCooldown())
{
- if (dx > 0)
- return 1; // 左手往右挥
+ if (isLeft && dx > 0)
+ return (int)WavingAction.LeftWave; // 左手往右挥
+ if (!isLeft && dx < 0)
+ return (int)WavingAction.RightWave; // 右手往左挥
}
}
}
-
- _lastLeftWrist = wrist;
- return 0;
+ return (int)WavingAction.None;
}
///
- /// 识别右手动作(右→左为 2,举手为 3)
+ /// 识别左手动作
///
+ public int RecognizeLeftHandGesture(Point wrist, Point elbow)
+ {
+ int result = DetectHorizontalWave(wrist, elbow, _lastLeftWrist, true);
+ _lastLeftWrist = wrist; // 更新记录
+ return result;
+ }
+ private bool _firstHandTriggered = false;
+ ///
+ /// 识别右手动作
+ ///
+ ///
+ ///
+ ///
public int RecognizeRightHandGesture(Point wrist, Point elbow)
{
- // 判断手腕是否在肘部上方,并且达到高度阈值
- //if (wrist.Y + 40 < elbow.Y && wrist.Y < minRaiseHeight)
- if (wrist.Y + 40 < elbow.Y)
+ // --- 先判断水平挥手 ---
+ int waveResult = DetectHorizontalWave(wrist, elbow, _lastRightWrist, false);
+ _lastRightWrist = wrist; // 更新记录
+ if (waveResult != (int)WavingAction.None)
+ return waveResult;
+
+ // --- 举手逻辑 ---
+ double verticalRise = elbow.Y - wrist.Y; // 手腕在肘上方 → 正值
+ if (verticalRise > 100) // 举手阈值
{
+ // 初始化计时
if (_raiseStartTime == null)
- {
_raiseStartTime = DateTime.Now;
- return (int)WavingAction.FirstHand;
+
+ if (_wristStartTime == null)
+ _wristStartTime = DateTime.Now;
+
+ var wristDuration = DateTime.Now - _wristStartTime.Value;
+
+ // 保持 >1 秒才触发一次 FirstHand
+ if (!_firstHandTriggered && wristDuration.TotalSeconds >= 1)
+ {
+ _firstHandTriggered = true;
+ return (int)WavingAction.FirstHand; // 举手开始,只触发一次
}
+ // 判断是否完成3秒举手
var duration = DateTime.Now - _raiseStartTime.Value;
- if (duration.TotalSeconds >= 3)
+ if (duration.TotalSeconds >= 4)
{
_raiseStartTime = null;
+ _wristStartTime = null;
+ _firstHandTriggered = false; // 重置状态
return (int)WavingAction.RaiseHand; // 举手完成
}
else
@@ -135,33 +169,20 @@ namespace Wpf_AiSportsMicrospace.Common
}
else
{
+ // 手放下,重置计时和状态
_raiseStartTime = null;
+ _wristStartTime = null;
+ _firstHandTriggered = false;
}
- // 挥手逻辑
- if (_lastRightWrist != null)
- {
- double dx = wrist.X - _lastRightWrist.Value.X;
- double dy = Math.Abs(wrist.Y - _lastRightWrist.Value.Y);
-
- if (Math.Abs(dx) > 30 && dy < 40)
- {
- if (CheckCooldown())
- {
- if (dx < 0)
- return 2; // 右手往左挥
- }
- }
- }
-
- _lastRightWrist = wrist;
- return 0;
+ return (int)WavingAction.None;
}
+
///
/// 冷却防抖(避免重复触发)
///
- private bool CheckCooldown(int cooldownMs = 500)
+ private bool CheckCooldown(int cooldownMs = 1000)
{
if ((DateTime.Now - _lastActionTime).TotalMilliseconds < cooldownMs)
return false;
diff --git a/Wpf_AiSportsMicrospace/Enum/WavingAction.cs b/Wpf_AiSportsMicrospace/Enum/WavingAction.cs
index 323e2fd..5a6058b 100644
--- a/Wpf_AiSportsMicrospace/Enum/WavingAction.cs
+++ b/Wpf_AiSportsMicrospace/Enum/WavingAction.cs
@@ -8,12 +8,12 @@ namespace Wpf_AiSportsMicrospace.Enum
{
public enum WavingAction
{
- None = 0, // 没动作
- LeftWave = 1, // 左挥手
- RightWave = 2, // 右挥手
- RaiseHand = 3, // 举手完成
- Raising = 4, // 举手中,未完成
- FirstHand = 5,//首次举手
+ None = 0,
+ LeftWave = 1,
+ RightWave = 2,
+ FirstHand = 3, // 举手开始
+ Raising = 4, // 举手中
+ RaiseHand = 5 // 举手完成
}
}
diff --git a/Wpf_AiSportsMicrospace/Home.xaml b/Wpf_AiSportsMicrospace/Home.xaml
index a152e2e..630bf8c 100644
--- a/Wpf_AiSportsMicrospace/Home.xaml
+++ b/Wpf_AiSportsMicrospace/Home.xaml
@@ -2,8 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
- Title="Home" Height="600" Width="800" Loaded="Window_Loaded">
-
+ Title="Home" Height="1080" Width="1920" Loaded="Window_Loaded">
+
diff --git a/Wpf_AiSportsMicrospace/Home.xaml.cs b/Wpf_AiSportsMicrospace/Home.xaml.cs
index dd8c1c6..7d32cff 100644
--- a/Wpf_AiSportsMicrospace/Home.xaml.cs
+++ b/Wpf_AiSportsMicrospace/Home.xaml.cs
@@ -80,6 +80,7 @@ namespace Wpf_AiSportsMicrospace
_webcamClient.StartExtract();
StartFrameProcessing();
+ coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
}
private void CoverFlow_ProgressCompleted(CoverFlowItem item)
@@ -90,6 +91,7 @@ namespace Wpf_AiSportsMicrospace
_cts.Cancel(); // 停止后台处理线程
_webcamClient?.StopExtract(); // 停止摄像头抽帧
_webcamClient = null;
+
}
catch (Exception ex)
{
@@ -97,7 +99,7 @@ namespace Wpf_AiSportsMicrospace
}
// 解绑事件,防止重复触发
- coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted;
+ //coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted;
// 根据图片跳转新窗口
string uri = item.ImageUri.ToString();
@@ -132,6 +134,15 @@ namespace Wpf_AiSportsMicrospace
}
else
{
+ //_webcamClient.OnExtractFrame += frame =>
+ //{
+ // if (frame != null)
+ // _frameQueue.Enqueue(frame);
+ //};
+ //_webcamClient.StartExtract();
+
+
+ _webcamClient.StartExtract();
Thread.Sleep(5);
}
}
@@ -163,32 +174,33 @@ namespace Wpf_AiSportsMicrospace
//检测挥手动作
var wavingaction = _sportOperate.VerifyWavingAction(human);
- if (wavingaction == (int)WavingAction.Raising)
+ // 把低 8 位作为动作类型,高 8 位作为进度
+ int actionType = wavingaction & 0xFF;
+ int progress = (wavingaction >> 8) & 0xFF;
+
+ switch (actionType)
{
- return;
- }
- else
- {
- switch (wavingaction)
- {
- case (int)WavingAction.LeftWave: // 1
- Dispatcher.BeginInvoke(() => coverFlow.SlideLeft());
- break;
- case (int)WavingAction.RightWave: // 2
- Dispatcher.BeginInvoke(() => coverFlow.SlideRight());
- break;
- case (int)WavingAction.RaiseHand: // 3 举手完成
- coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted;
- coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
- break;
- case (int)WavingAction.Raising: // 4 举手中
- break;
- case 5: // 如果还有其他动作
- Dispatcher.BeginInvoke(() => coverFlow.StartSelectedProgress());
- break;
- default:
- break;
- }
+ 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();
+ break;
+ default: // 没有动作 → 取消进度
+ Dispatcher.BeginInvoke(() => coverFlow.CancelSelectedProgress());
+ break;
}
}
catch (Exception ex)
diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml
index 3715957..abe1ca0 100644
--- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml
+++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml
@@ -10,7 +10,7 @@
-
+
@@ -30,12 +30,12 @@
-