Kinect Manager
KinectManager:脚本说明
属性:
[Tooltip("离地面有多高的传感器(单位:米)。")]
public float sensorHeight = 1.0f;
[Tooltip("Kinect仰角(度)。可能是积极的还是消极的。")]
public float sensorAngle = 0f;
public enum AutoHeightAngle : int { DontUse, ShowInfoOnly, AutoUpdate, AutoUpdateAndShowInfo }
[Tooltip("是否自动设置传感器高度和角度。用户必须在前面的传感器,为了自动检测工作。")]
public AutoHeightAngle autoHeightAngle = AutoHeightAngle.DontUse;
public enum UserMapType : int { None, RawUserDepth, BodyTexture, UserTexture, CutOutTexture }
[Tooltip("是否以及如何利用用户和深度地图。")]
public UserMapType computeUserMap = UserMapType.RawUserDepth;
[Tooltip("是否利用彩色摄像机图像。")]
public bool computeColorMap = false;
[Tooltip("是否利用红外摄像机的图像。")]
public bool computeInfraredMap = false;
[Tooltip("是否显示屏幕上的用户映射。")]
public bool displayUserMap = false;
[Tooltip("是否显示彩色摄像机图像在屏幕上。")]
public bool displayColorMap = false;
[Tooltip("是否显示用户地图上骨架线。")]
public bool displaySkeletonLines = false;
// 如果百分比是零,这是计算内部以匹配所选的深度图像的宽度和高度
[Tooltip("深度和宽度彩色图像在屏幕上,相机宽度的百分比。图像高度取决于计算宽度。")]
public float DisplayMapsWidthPercent = 20f;
[Tooltip("是否要使用多源阅读器,如果有可用的(K2-only特性)。")]
public bool useMultiSourceReader = false;
// Public Bool to determine whether to use sensor's audio source, if available
//public bool useAudioSource = false;
[Tooltip("最小距离用户,为了考虑骨骼数据处理。")]
public float minUserDistance = 0.5f;
[Tooltip("最大距离用户,为了考虑骨骼数据处理。值为0时表示没有最大距离限制。")]
public float maxUserDistance = 0f;
[Tooltip("最大用户向左或向右的距离,为了考虑骨骼数据处理。值为0时表示没有左/右的距离限制。")]
public float maxLeftRightDistance = 0f;
[Tooltip("最大数量的用户,这可能是同时跟踪。")]
public int maxTrackedUsers = 6;
[Tooltip("是否显示跟踪用户只允许的范围内,或所有用户(fps)。")]
public bool showTrackedUsersOnly = true;
[Tooltip("是否先检测只有最接近用户。")]
public bool detectClosestUser = true;
[Tooltip("是否只利用跟踪关节(而忽略推断的)。")]
public bool ignoreInferredJoints = false;
[Tooltip("是否忽略关节的z坐标(即在2 d场景)中使用它们。")]
public bool ignoreZCoordinates = false;
[Tooltip("是否更新AvatarControllers LateUpdate(),而不是更新()。所需Mocap-Mecanim混合。")]
public bool lateUpdateAvatars = false;
public enum Smoothing : int { None, Default, Medium, Aggressive }
[Tooltip("联合平滑参数集。")]
public Smoothing smoothing = Smoothing.Default;
[Tooltip("是否应用骨方向约束。")]
public bool useBoneOrientationConstraints = false;
//public bool useBoneOrientationsFilter = false;
[Tooltip("是否允许检测身体的运作周期。")]
public bool allowTurnArounds = false;
public enum AllowedRotations : int { None = 0, Default = 1, All = 2 }
[Tooltip("允许他们的手和手腕旋转。没有——没有手旋转,允许违约——手旋转除了扭曲,所有——所有转动是允许的。")]
public AllowedRotations allowedHandRotations = AllowedRotations.Default;
[Tooltip("场景中的控制化身的列表。如果列表为空时,可用的《阿凡达》控制器将在启动检测。")]
public List<AvatarController> avatarControllers = new List<AvatarController>();
[Tooltip("玩家姿势校准")]
public KinectGestures.Gestures playerCalibrationPose;
[Tooltip("手势为每个球员被探测到的列表。")]
public List<KinectGestures.Gestures> playerCommonGestures = new List<KinectGestures.Gestures>();
[Tooltip("最低手势检测间隔时间(以秒为单位)。")]
public float minTimeBetweenGestures = 0.7f;
[Tooltip("手势经理,用于检测编程Kinect动作。")]
public KinectGestures gestureManager;
[Tooltip("列出可用的姿态听众。他们必须实现KinectGestures.GestureListenerInterface。如果列表是空的,可用手势听众会发现启动。")]
public List<MonoBehaviour> gestureListeners = new List<MonoBehaviour>();
[Tooltip("gui文本来显示用户检测消息。")]
public GUIText calibrationText;
[Tooltip("gui文本显示为当前手势跟踪调试消息。")]
public GUIText gesturesDebugText;
===============================================================================
部分方法解析:
//体感设备是否初始化完成
public bool IsInitialized()
//程序捕获的人物个数
public int GetBodyCount()
//程序捕获的关节个数
public int GetJointCount()
//返回骨骼节点的索引
public int GetJointIndex(KinectInterop.JointType joint)
//返回骨骼节点的类型
public KinectInterop.JointType GetParentJoint(KinectInterop.JointType joint)
//设备返回彩色图片的宽度
public int GetColorImageWidth()
//设备返回彩色图片的高度
public int GetColorImageHeight()
//设备返回深度图的宽度
public int GetDepthImageWidth()
//设备返回深度图的高度
public int GetDepthImageHeight()
//获取最原始的深度图
public ushort[] GetRawInfraredMap()
//获取深度图像
public Texture2D GetUsersLblTex()
//获取彩色数据图
public Texture2D GetUsersClrTex()
//是否检测到用户
public bool IsUserDetected()
//指定的用户是否被检测到
public bool IsUserTracked(Int64 userId)
//获取用户的个数
public int GetUsersCount()
//获取主要检测的用户
public Int64 GetPrimaryUserID()
//返回用户相对于体感探头的位置
public Vector3 GetUserPosition(Int64 userId)
//返回用户相对于体感探头的旋转
public Quaternion GetUserOrientation(Int64 userId, bool flip)
//获取关节的捕获状态
public KinectInterop.TrackingState GetJointTrackingState(Int64 userId, int joint)
//关节是否被检测追踪
public bool IsJointTracked(Int64 userId, int joint)
//返回关节相对于Kinect的位置
public Vector3 GetJointKinectPosition(Int64 userId, int joint)
//返回关节相对于场景摄像头的位置
public Vector3 GetJointPosition(Int64 userId, int joint)
//得到的三维叠加位置给depth-image联合。
public Vector3 GetJointPosDepthOverlay(Int64 userId, int joint, Camera camera, Rect imageRect)
//得到了3 d覆盖给定的联合在彩色图像的位置。
public Vector3 GetJointPosColorOverlay(Int64 userId, int joint, Camera camera, Rect imageRect)
//获取左手的状态(握拳,伸开,yes)
public KinectInterop.HandState GetLeftHandState(Int64 userId)
//获取右手的状态(握拳,伸开,yes)
public KinectInterop.HandState GetRightHandState(Int64 userId)
//坐标转换
//空间坐标转换到深度坐标
public Vector3 MapDepthPointToSpaceCoords(Vector2 posPoint, ushort depthValue, bool bWorldCoords)
//空间坐标转换到深度坐标
public Vector2 MapSpacePointToDepthCoords(Vector3 posPoint)
//深度坐标转换到彩色坐标
public Vector2 MapDepthPointToColorCoords(Vector2 posPoint, ushort depthValue)
//添加监听的手势
public void DetectGesture(Int64 UserId, KinectGestures.Gestures gesture)
//删除监听的手势
public bool DeleteGesture(Int64 UserId, KinectGestures.Gestures gesture)
//检测某个手势是否完成
public bool IsGestureComplete(Int64 UserId, KinectGestures.Gestures gesture, bool bResetOnComplete)
*************************************************************************************************************************
Kinect 功能的实现
开发部分实现方法:
===============================================================================
获取人物关节点的注意事项:
//1.先检查人物是否被检测
if (_manager.IsUserDetected())
//2.获取人物ID
long userId = _manager.GetPrimaryUserID();
//3.关节索引
int jointIndex = (int)KinectInterop.JointType.HandLeft;
//4.判断需要跟踪的关节点是否已经被识别
if (_manager.IsJointTracked(userId, jointIndex))
//5.获取骨骼节点信息
Vector3 leftHandPos = _manager.GetJointKinectPosition(userId, jointIndex);
===============================================================================
获取手势信息
//获取右手状态
KinectInterop.HandState rightHandState = _manager.GetRightHandState(userId);
//判断右手状态值
if (rightHandState == KinectInterop.HandState.Closed)
{
debugText.text = "右手握拳";
}
else if (rightHandState == KinectInterop.HandState.Open)
{
debugText.text = "右手展开";
}
else if (rightHandState == KinectInterop.HandState.Lasso)
{
debugText.text = "yes 手势";
}
===============================================================================
Kinect坐标到屏幕坐标的转换
//1.获取骨骼节点坐标
Vector3 jointKinectPos = _manager.GetJointKinectPosition(userId, jointIndex);
//2.空间坐标转换成深度坐标
Vector2 posDepth = _manager.MapSpacePointToDepthCoords(jointKinectPos);
//3.根据深度坐标获取深度值
ushort depthValue = _manager.GetDepthForPixel((int)posDepth.x, (int)posDepth.y);
if (depthValue > 0)//深度值大于0
{
//4.深度图像转换成彩色图像
Vector2 posColor = _manager.MapDepthPointToColorCoords(posDepth, depthValue);
//5.按彩色图像转换坐标
float xNorm = (float)posColor.x / _manager.GetColorImageWidth();
float yNorm = (float)posColor.y / _manager.GetColorImageHeight();
if (overlayObject)
{
//将视口坐标转换为空间坐标
Vector3 vpos = Camera.main.ViewportToWorldPoint(xNorm, yNorm, distanceToCamera);
overlayObject.transform.position = Vector3.Lerp(overlayObject.transform.position, vpos, Time.deltaTime * 5);
}
}
===============================================================================
//UI点击的实现
1.获取右手(左手/关节点)的3D坐标
Vector3 rightHandPos = _manager.GetJointKinectPosition(userId, jointIndex);//右手坐标
2.3D坐标转换成屏幕坐标
Vector3 rightScreenPos = Camera.main.WorldToScreenPoint(rightHandPos);//转换成屏幕坐标
Vector2 screenPosTemp = new Vector2(rightScreenPos.x, rightScreenPos.y);//屏幕坐标
3.屏幕坐标转换成UGUI坐标(得到手的位置在UGUI的位置)
Vector2 uguiPos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas, screenPosTemp, null, out uguiPos))
{
hand.anchoredPosition = uguiPos;
}
4.判断手的位置是否在UGUI控件上方
bool isOverBtn1 = RectTransformUtility.RectangleContainsScreenPoint(btn1, screenPosTemp, null);
5.手如果在控件上方,判断是否握拳
//获取右手状态
KinectInterop.HandState rightHandState = _manager.GetRightHandState(userId);
//判断右手状态值
if (rightHandState == KinectInterop.HandState.Closed)
{
if (isOverBtn1)
print("握住btn1");
}
else if (rightHandState == KinectInterop.HandState.Open){}
else if (rightHandState == KinectInterop.HandState.Lasso){}
***********************************************************************************
Kinect 骨骼数据和姿势监听
Kinect骨骼分析:
人物的数据
public struct BodyData
{
public Int64 liTrackingID;//人物是否被追踪
public Vector3 position;//人物的位置
public Quaternion orientation;
public JointData[] joint;//骨骼节点的数据
// KM calculated parameters
public Quaternion normalRotation;
public Quaternion mirroredRotation;
public Vector3 hipsDirection;
public Vector3 shouldersDirection;
public float bodyTurnAngle;
//public float bodyFullAngle;
public bool isTurnedAround;
public float turnAroundFactor;
public Quaternion leftHandOrientation;
public Quaternion rightHandOrientation;
public Quaternion headOrientation;
//public Vector3 leftArmDirection;
//public Vector3 leftThumbForward;
//public Vector3 leftThumbDirection;
////public float leftThumbAngle;
//
//public Vector3 rightArmDirection;
//public Vector3 rightThumbForward;
//public Vector3 rightThumbDirection;
////public float rightThumbAngle;
//public Vector3 leftLegDirection;
//public Vector3 leftFootDirection;
//public Vector3 rightLegDirection;
//public Vector3 rightFootDirection;
public HandState leftHandState;//左手状态
public TrackingConfidence leftHandConfidence;
public HandState rightHandState;//右手状态
public TrackingConfidence rightHandConfidence;
public uint dwClippedEdges;
public short bIsTracked;
public short bIsRestricted;
}
//骨骼点信息
public struct JointData
{
public TrackingState trackingState;
public Vector3 kinectPos;
public Vector3 position;
public Quaternion orientation; // deprecated
public Vector3 posPrev;
public Vector3 posRel;
public Vector3 posDrv;
// KM calculated parameters
public Vector3 direction;
public Quaternion normalRotation;
public Quaternion mirroredRotation;
// Constraint parameters
public float lastAngle;
}
//姿势检测的结构
public struct GestureData
{
public long userId;//要检测的用户ID
public Gestures gesture;//要检测的姿势类型
public int state;//姿势检测的状态,姿势是否正在检测
public float timestamp;
public int joint;
public Vector3 jointPos;
public Vector3 screenPos;
public float tagFloat;
public Vector3 tagVector;
public Vector3 tagVector2;
public float progress;
public bool complete;
public bool cancelled;
public List<Gestures> checkForGestures;
public float startTrackingAtTime;