手势识别优化
This commit is contained in:
parent
2a24d26ce4
commit
9c63156551
@ -34,6 +34,9 @@ namespace Wpf_AiSportsMicrospace.Common
|
|||||||
private Point? _lastRightWrist = null;
|
private Point? _lastRightWrist = null;
|
||||||
private DateTime? _raiseStartTime = null;
|
private DateTime? _raiseStartTime = null;
|
||||||
private DateTime? _wristStartTime = null;
|
private DateTime? _wristStartTime = null;
|
||||||
|
private double _leftWristDeltaX = 0;
|
||||||
|
private double _rightWristDeltaX = 0;
|
||||||
|
private bool _firstHandTriggered = false;
|
||||||
|
|
||||||
|
|
||||||
public SportOperate()
|
public SportOperate()
|
||||||
@ -62,80 +65,32 @@ namespace Wpf_AiSportsMicrospace.Common
|
|||||||
var rightWrist = human.Keypoints.FirstOrDefault(x => x.Name == "right_wrist");
|
var rightWrist = human.Keypoints.FirstOrDefault(x => x.Name == "right_wrist");
|
||||||
var rightElbow = human.Keypoints.FirstOrDefault(x => x.Name == "right_elbow");
|
var rightElbow = human.Keypoints.FirstOrDefault(x => x.Name == "right_elbow");
|
||||||
|
|
||||||
// 左手逻辑
|
// --- 左手挥手 ---
|
||||||
if (leftWrist != null && leftElbow != null)
|
if (leftWrist != null && leftElbow != null)
|
||||||
{
|
{
|
||||||
var result = RecognizeLeftHandGesture(
|
int leftResult = DetectHorizontalWave(
|
||||||
new Point(leftWrist.X, leftWrist.Y),
|
new Point(leftWrist.X, leftWrist.Y),
|
||||||
new Point(leftElbow.X, leftElbow.Y));
|
new Point(leftElbow.X, leftElbow.Y),
|
||||||
if (result != 0) return result;
|
ref _lastLeftWrist,
|
||||||
|
ref _leftWristDeltaX,
|
||||||
|
true);
|
||||||
|
if (leftResult != (int)WavingAction.None) return leftResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 右手逻辑
|
// --- 右手挥手或举手 ---
|
||||||
if (rightWrist != null && rightElbow != null)
|
if (rightWrist != null && rightElbow != null)
|
||||||
{
|
{
|
||||||
var result = RecognizeRightHandGesture(
|
int rightWaveResult = DetectHorizontalWave(
|
||||||
new Point(rightWrist.X, rightWrist.Y),
|
new Point(rightWrist.X, rightWrist.Y),
|
||||||
new Point(rightElbow.X, rightElbow.Y));
|
new Point(rightElbow.X, rightElbow.Y),
|
||||||
if (result != 0) return result;
|
ref _lastRightWrist,
|
||||||
}
|
ref _rightWristDeltaX,
|
||||||
|
false);
|
||||||
return 0;
|
if (rightWaveResult != (int)WavingAction.None) return rightWaveResult;
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 统一的水平挥手检测
|
|
||||||
/// </summary>
|
|
||||||
private int DetectHorizontalWave(Point wrist, Point elbow, Point? lastWrist, bool isLeft)
|
|
||||||
{
|
|
||||||
if (lastWrist != null)
|
|
||||||
{
|
|
||||||
double dx = wrist.X - lastWrist.Value.X;
|
|
||||||
double dy = Math.Abs(wrist.Y - lastWrist.Value.Y);
|
|
||||||
|
|
||||||
// 挥手:水平位移明显,垂直位移小,且接近肘部水平
|
|
||||||
if (Math.Abs(dx) > 30 && dy < 40 && Math.Abs(wrist.Y - elbow.Y) < 150)
|
|
||||||
{
|
|
||||||
if (CheckCooldown())
|
|
||||||
{
|
|
||||||
if (isLeft && dx > 0)
|
|
||||||
return (int)WavingAction.LeftWave; // 左手往右挥
|
|
||||||
if (!isLeft && dx < 0)
|
|
||||||
return (int)WavingAction.RightWave; // 右手往左挥
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (int)WavingAction.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 识别左手动作
|
|
||||||
/// </summary>
|
|
||||||
public int RecognizeLeftHandGesture(Point wrist, Point elbow)
|
|
||||||
{
|
|
||||||
int result = DetectHorizontalWave(wrist, elbow, _lastLeftWrist, true);
|
|
||||||
_lastLeftWrist = wrist; // 更新记录
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
private bool _firstHandTriggered = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 识别右手动作
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="wrist"></param>
|
|
||||||
/// <param name="elbow"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public int RecognizeRightHandGesture(Point wrist, Point elbow)
|
|
||||||
{
|
|
||||||
// --- 先判断水平挥手 ---
|
|
||||||
int waveResult = DetectHorizontalWave(wrist, elbow, _lastRightWrist, false);
|
|
||||||
_lastRightWrist = wrist; // 更新记录
|
|
||||||
if (waveResult != (int)WavingAction.None)
|
|
||||||
return waveResult;
|
|
||||||
|
|
||||||
// --- 举手逻辑 ---
|
// --- 举手逻辑 ---
|
||||||
double verticalRise = elbow.Y - wrist.Y; // 手腕在肘上方 → 正值
|
double verticalRise = rightElbow.Y - rightWrist.Y; // 手腕在肘上方 → 正值
|
||||||
if (verticalRise > 60) // 举手阈值
|
if (verticalRise >= 60) // 举手阈值
|
||||||
{
|
{
|
||||||
// 初始化计时
|
// 初始化计时
|
||||||
if (_raiseStartTime == null)
|
if (_raiseStartTime == null)
|
||||||
@ -174,14 +129,42 @@ namespace Wpf_AiSportsMicrospace.Common
|
|||||||
_wristStartTime = null;
|
_wristStartTime = null;
|
||||||
_firstHandTriggered = false;
|
_firstHandTriggered = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (int)WavingAction.None;
|
return (int)WavingAction.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 统一的水平挥手检测
|
||||||
|
/// </summary>
|
||||||
|
private int DetectHorizontalWave(Point wrist, Point elbow, ref Point? lastWrist, ref double deltaX, bool isLeft)
|
||||||
|
{
|
||||||
|
if (lastWrist != null)
|
||||||
|
{
|
||||||
|
double dx = wrist.X - lastWrist.Value.X;
|
||||||
|
double dy = Math.Abs(wrist.Y - lastWrist.Value.Y);
|
||||||
|
|
||||||
|
// 累计水平位移
|
||||||
|
deltaX += dx;
|
||||||
|
|
||||||
|
if (Math.Abs(deltaX) > 40 && dy < 60 && Math.Abs(wrist.Y - elbow.Y) < 60)
|
||||||
|
{
|
||||||
|
deltaX = 0; // 重置
|
||||||
|
if (CheckCooldown())
|
||||||
|
{
|
||||||
|
return isLeft ? (int)WavingAction.LeftWave : (int)WavingAction.RightWave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastWrist = wrist;
|
||||||
|
return (int)WavingAction.None;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 冷却防抖(避免重复触发)
|
/// 冷却防抖(避免重复触发)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool CheckCooldown(int cooldownMs = 800)
|
private bool CheckCooldown(int cooldownMs = 1000)
|
||||||
{
|
{
|
||||||
if ((DateTime.Now - _lastActionTime).TotalMilliseconds < cooldownMs)
|
if ((DateTime.Now - _lastActionTime).TotalMilliseconds < cooldownMs)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -173,10 +173,10 @@ namespace Wpf_AiSportsMicrospace
|
|||||||
var wavingaction = _sportOperate.VerifyWavingAction(human);
|
var wavingaction = _sportOperate.VerifyWavingAction(human);
|
||||||
|
|
||||||
// 把低 8 位作为动作类型,高 8 位作为进度
|
// 把低 8 位作为动作类型,高 8 位作为进度
|
||||||
int actionType = wavingaction & 0xFF;
|
//int actionType = wavingaction & 0xFF;
|
||||||
int progress = (wavingaction >> 8) & 0xFF;
|
//int progress = (wavingaction >> 8) & 0xFF;
|
||||||
|
|
||||||
switch (actionType)
|
switch (wavingaction)
|
||||||
{
|
{
|
||||||
case (int)WavingAction.LeftWave: // 左手挥动
|
case (int)WavingAction.LeftWave: // 左手挥动
|
||||||
Dispatcher.BeginInvoke(() => coverFlow.SlideRight());
|
Dispatcher.BeginInvoke(() => coverFlow.SlideRight());
|
||||||
@ -194,8 +194,8 @@ namespace Wpf_AiSportsMicrospace
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)WavingAction.RaiseHand: // 举手完成
|
case (int)WavingAction.RaiseHand: // 举手完成
|
||||||
|
_cts.Cancel();
|
||||||
coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
|
coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
|
||||||
// _cts.Cancel();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // 没有动作 → 取消进度
|
default: // 没有动作 → 取消进度
|
||||||
|
|||||||
@ -136,6 +136,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void StopProgress()
|
private void StopProgress()
|
||||||
|
|
||||||
{
|
{
|
||||||
if (_renderHandler != null)
|
if (_renderHandler != null)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user