如何解决如何为 Azure Kinect 实现手势向左向右向上滑动?
我正在尝试为 azure kinect 实现 4 个滑动手势(向左、向右、向上、向下),我参考了为旧 kinect 实现手势的文章。我修改了 azure kinect 的代码。 (https://pterneas.com/2014/01/27/implementing-kinect-gestures/)
此外,我将这个库用于 azure kinect (https://github.com/bibigone/k4a.net)
另外,我意识到它的效果不是很好,我在手势之间添加了冷却时间。 如何更好地进行手势检测?
using K4AdotNet.BodyTracking;
using K4AdotNet.Samples.Unity;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum GesturePartResult
{
Failed,Succeeded
}
public enum GestureType
{
Left,Right,Up,Down,}
public interface IGestureSegment
{
GesturePartResult Update(Skeleton skeleton);
}
public class HandRightOfElbowSegment : IGestureSegment
{
public GesturePartResult Update(Skeleton skeleton)
{
//Debug.Log($"{skeleton[JointType.HandRight].ConfidenceLevel}");
// Hand above elbow
if (-skeleton[JointType.HandRight].PositionMm.Y >
-skeleton[JointType.ElbowRight].PositionMm.Y)
{
//Debug.Log($"hand above");
// Hand right of elbow
if (-skeleton[JointType.HandRight].PositionMm.X >
-skeleton[JointType.ElbowRight].PositionMm.X)
{
//Debug.Log($"hand right");
return GesturePartResult.Succeeded;
}
}
// Hand dropped
return GesturePartResult.Failed;
}
}
public class HandLeftOfElbowSegment : IGestureSegment
{
public GesturePartResult Update(Skeleton skeleton)
{
// Hand above elbow
if (-skeleton[JointType.HandRight].PositionMm.Y >
-skeleton[JointType.ElbowRight].PositionMm.Y)
{
// Hand left of elbow
if (-skeleton[JointType.HandRight].PositionMm.X <
-skeleton[JointType.ElbowRight].PositionMm.X)
{
return GesturePartResult.Succeeded;
}
}
// Hand dropped
return GesturePartResult.Failed;
}
}
public class ElbowAboveShoulderSegment : IGestureSegment
{
public GesturePartResult Update(Skeleton skeleton)
{
if (-skeleton[JointType.ElbowRight].PositionMm.Y > -skeleton[JointType.ShoulderRight].PositionMm.Y)
{
return GesturePartResult.Succeeded;
}
return GesturePartResult.Failed;
}
}
public class ElbowBelowShoulderSegment : IGestureSegment
{
public GesturePartResult Update(Skeleton skeleton)
{
if (-skeleton[JointType.ElbowRight].PositionMm.Y < -skeleton[JointType.ShoulderRight].PositionMm.Y)
{
return GesturePartResult.Succeeded;
}
return GesturePartResult.Failed;
}
}
public class Gesture
{
readonly int WINDOW_SIZE = 30;
IGestureSegment[] _segments;
int _currentSegment = 0;
int _frameCount = 0;
public event EventHandler GestureRecognized;
public GestureType type;
public GameObject gameObject;
public Gesture(GestureType type)
{
HandRightOfElbowSegment handRightOfElbow = new HandRightOfElbowSegment();
HandLeftOfElbowSegment handLeftOfElbow = new HandLeftOfElbowSegment();
ElbowAboveShoulderSegment elbowAboveShoulder = new ElbowAboveShoulderSegment();
ElbowBelowShoulderSegment elbowBelowShoulder = new ElbowBelowShoulderSegment();
this.type = type;
switch (type)
{
case GestureType.Left:
_segments = new IGestureSegment[]
{
handRightOfElbow,//handRightOfElbow,//handLeftOfElbow,handLeftOfElbow,//handRightOfhead,//handLeftOfhead
};
break;
case GestureType.Right:
_segments = new IGestureSegment[]
{
handLeftOfElbow,handRightOfElbow,};
break;
case GestureType.Up:
_segments = new IGestureSegment[]
{
elbowBelowShoulder,elbowAboveShoulder,};
break;
case GestureType.Down:
_segments = new IGestureSegment[]
{
elbowAboveShoulder,elbowBelowShoulder,};
break;
default:
break;
}
}
public void Update(Skeleton skeleton)
{
//Debug.Log($"current segment {_currentSegment}");
GesturePartResult result = _segments[_currentSegment].Update(skeleton);
if (result == GesturePartResult.Succeeded)
{
//Debug.Log($"Succeeded");
if (_currentSegment + 1 < _segments.Length)
{
_currentSegment++;
_frameCount = 0;
}
else
{
//Debug.Log($"hello");
if (GestureRecognized != null)
{
GestureRecognized(this,new EventArgs());
Reset();
}
}
}
else if (_frameCount == WINDOW_SIZE)
{
//Debug.Log($"Failed {_frameCount}");
Reset();
}
else
{
_frameCount++;
}
}
public void Reset()
{
_currentSegment = 0;
_frameCount = 0;
}
}
public class GestureDetect : MonoBehavIoUr
{
// gesture
private Gesture left = new Gesture(GestureType.Left);
private Gesture right = new Gesture(GestureType.Right);
private Gesture up = new Gesture(GestureType.Up);
private Gesture down = new Gesture(GestureType.Down);
// cooldown
[Serializefield]
private float cooldown = .5f;
[Serializefield]
private float currentCooldown = 0f;
// menu
[Serializefield]
private Menu menu;
public GameObject hand;
private void OnEnable()
{
var skeletonProvider = FindobjectOfType<SkeletonProvider>();
if (skeletonProvider != null)
{
skeletonProvider.SkeletonUpdated += OnSkeletonUpdate;
}
left.GestureRecognized += OnGestureRecognized;
right.GestureRecognized += OnGestureRecognized;
up.GestureRecognized += OnGestureRecognized;
down.GestureRecognized += OnGestureRecognized;
}
private void Ondisable()
{
var skeletonProvider = FindobjectOfType<SkeletonProvider>();
if (skeletonProvider != null)
{
skeletonProvider.SkeletonUpdated -= OnSkeletonUpdate;
}
}
private void OnSkeletonUpdate(object sender,SkeletonEventArgs e)
{
if (e.Skeleton == null) return;
var joint = e.Skeleton.Value.WristRight;
hand.transform.position = new Vector3(-joint.PositionMm.X,-joint.PositionMm.Y,0) * 0.001f * 10;
if (currentCooldown > 0f) return;
left.Update(e.Skeleton.Value);
if (currentCooldown > 0f) return;
right.Update(e.Skeleton.Value);
if (currentCooldown > 0f) return;
up.Update(e.Skeleton.Value);
if (currentCooldown > 0f) return;
down.Update(e.Skeleton.Value);
}
private void OnGestureRecognized(object sender,EventArgs e)
{
Debug.Log($"Gesture recognized {((Gesture)sender).type} {currentCooldown}");
left.Reset();
right.Reset();
up.Reset();
down.Reset();
currentCooldown = cooldown;
switch (((Gesture)sender).type)
{
case GestureType.Left:
// left
break;
case GestureType.Right:
// right
break;
case GestureType.Up:
// up
break;
case GestureType.Down:
// down
break;
}
}
private void Update()
{
if (currentCooldown > 0f)
{
currentCooldown -= Time.deltaTime;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。