1. 学习demo - HandColorOverlayer
- 跟踪手部关节,拍一拍屏幕中的小黄人
- 代码学习 - 注释
using UnityEngine;
using System.Collections;
//using Windows.Kinect;
public class HandColorOverlayer : MonoBehaviour
{
// [Tooltip("GUI-texture used to display the color camera feed on the scene background.")]
// public GUITexture backgroundImage;
[Tooltip("Camera used to estimate the overlay positions of 3D-objects over the background. By default it is the main camera.")]
public Camera foregroundCamera;
[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
public int playerIndex = 0;
[Tooltip("Game object used to overlay the left hand.")]
public Transform leftHandOverlay;
[Tooltip("Game object used to overlay the right hand.")]
public Transform rightHandOverlay;
//public float smoothFactor = 10f;
// reference to KinectManager
private KinectManager manager;
void Update ()
{
if (foregroundCamera == null)
{
// by default use the main camera
foregroundCamera = Camera.main;
}
if(manager == null)
{
manager = KinectManager.Instance;
}
if(manager && manager.IsInitialized() && foregroundCamera)
{
// //backgroundImage.renderer.material.mainTexture = manager.GetUsersClrTex();
// if(backgroundImage && (backgroundImage.texture == null))
// {
// backgroundImage.texture = manager.GetUsersClrTex();
// }
// get the background rectangle (use the portrait background, if available)
Rect backgroundRect = foregroundCamera.pixelRect;
PortraitBackground portraitBack = PortraitBackground.Instance;
if(portraitBack && portraitBack.enabled)
{
backgroundRect = portraitBack.GetBackgroundRect();
}
// overlay the joints
if(manager.IsUserDetected(playerIndex))
{
long userId = manager.GetUserIdByIndex(playerIndex);
OverlayJoint(userId, (int)KinectInterop.JointType.HandLeft, leftHandOverlay, backgroundRect);
OverlayJoint(userId, (int)KinectInterop.JointType.HandRight, rightHandOverlay, backgroundRect);
}
}
}
// overlays the given object over the given user joint
// 将给定的物体覆盖在用户指定的关节位置上
private void OverlayJoint(long userId, int jointIndex, Transform overlayObj, Rect imageRect)
{
if(manager.IsJointTracked(userId, jointIndex)) //检查用户的指定关节是否被追踪
{
// 获取关节在Kinect传感器坐标系中的位置
Vector3 posJoint = manager.GetJointKinectPosition(userId, jointIndex);
if(posJoint != Vector3.zero)
{
// 3d position to depth
// 将关节的三维空间位置映射到深度图像的二维坐标
Vector2 posDepth = manager.MapSpacePointToDepthCoords(posJoint);
// 获取深度值
ushort depthValue = manager.GetDepthForPixel((int)posDepth.x, (int)posDepth.y);
// 将深度坐标映射到颜色图像的二维坐标
if(posDepth != Vector2.zero && depthValue > 0)
{
// depth pos to color pos
Vector2 posColor = manager.MapDepthPointToColorCoords(posDepth, depthValue);
// 计算颜色坐标在屏幕中的实际位置
if (!float.IsInfinity(posColor.x) && !float.IsInfinity(posColor.y))
{
// float xNorm = (float)posColor.x / manager.GetColorImageWidth();
// float yNorm = 1.0f - (float)posColor.y / manager.GetColorImageHeight();
float xScaled = (float)posColor.x * imageRect.width / manager.GetColorImageWidth();
float yScaled = (float)posColor.y * imageRect.height / manager.GetColorImageHeight();
float xScreen = imageRect.x + xScaled;
float yScreen = imageRect.y + imageRect.height - yScaled;
if(overlayObj && foregroundCamera)
{
float distanceToCamera = overlayObj.position.z - foregroundCamera.transform.position.z;
//posJoint = foregroundCamera.ViewportToWorldPoint(new Vector3(xNorm, yNorm, distanceToCamera));
// 将屏幕坐标转换为世界坐标,更新覆盖物体的位置
posJoint = foregroundCamera.ScreenToWorldPoint(new Vector3(xScreen, yScreen, distanceToCamera));
overlayObj.position = posJoint;
}
}
}
}
}
}
}
2. 资源结构
添加了一个背景相机,用于将Kinect识别的图像直接展示在UI里,也就是这群小黄人的后面。
调用KinectManager里的色彩图像处理函数,绑定在backgroundimage里,就能实现图像出现在UI里而不是右下角小窗口。
using UnityEngine;
using System.Collections;
/// <summary>
/// Background color image is component that displays the color camera feed on GUI texture, usually the scene background.
/// </summary>
public class BackgroundColorImage : MonoBehaviour
{
[Tooltip("RawImage used to display the color camera feed.")]
public UnityEngine.UI.RawImage backgroundImage;
void Start()
{
if (backgroundImage == null)
{
backgroundImage = GetComponent<UnityEngine.UI.RawImage>();
}
}
void Update ()
{
KinectManager manager = KinectManager.Instance;
if (manager && manager.IsInitialized())
{
if (backgroundImage && (backgroundImage.texture == null))
{
backgroundImage.texture = manager.GetUsersClrTex();
backgroundImage.rectTransform.localScale = manager.GetColorImageScale();
backgroundImage.color = Color.white;
}
}
}
}