Kinect屏幕边缘检测不灵敏的解决方案
在做体感项目时,在边缘部分的抓取动作识别非常差
于是我做出了优化,不采用原本的映射关系:
假设原本人物站在中间,保持位置不动,右手臂向右伸直,终点为屏幕的极限位置
此时我们并不将手臂伸直的位置映射到屏幕的极限位置,而是映射到屏幕的120%处,如此一来,原设备检测的区域就变为了20%——80%之间,保证了一定的精度
Rect rectCanvas = LeftCursor.canvas.pixelRect; float xoffset = (rectCanvas.width) / 2; float yoffset = rectCanvas.height / 2; float multiple = 2f; Vector3 posSprite = new Vector2(Mathf.Clamp(multiple * (leftHandScreenPos.x * rectCanvas.width - xoffset) ,- xoffset,xoffset) , Mathf.Clamp(multiple*(leftHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) ); Vector3 posSprite1 = new Vector2(Mathf.Clamp(multiple * (rightHandScreenPos.x * rectCanvas.width - xoffset), -xoffset, xoffset),Mathf.Clamp(multiple*(rightHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) );
此外,还可以使用List<Vector3>来存储历史数据,然后在每次更新时计算平均值,获得更稳定的位置更新。
// 存储关节历史数据,用于平滑 private readonly Queue<Vector3> LefthandData = new Queue<Vector3>(); private readonly Queue<Vector3> RighthandData = new Queue<Vector3>(); /// <summary> /// 设置空间坐标 /// </summary> private void ScreenSetting() { if (interactionManager!=null) { leftHandScreenPos = interactionManager.GetLeftHandScreenPos(); rightHandScreenPos = interactionManager.GetRightHandScreenPos(); Rect rectCanvas = LeftCursor.canvas.pixelRect; float xoffset = (rectCanvas.width) / 2; float yoffset = rectCanvas.height / 2; float multiple = 2f; Vector3 posSprite = new Vector2(Mathf.Clamp(multiple * (leftHandScreenPos.x * rectCanvas.width - xoffset) ,- xoffset,xoffset) , Mathf.Clamp(multiple*(leftHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) ); Vector3 posSprite1 = new Vector2(Mathf.Clamp(multiple * (rightHandScreenPos.x * rectCanvas.width - xoffset), -xoffset, xoffset),Mathf.Clamp(multiple*(rightHandScreenPos.y * rectCanvas.height - yoffset),-yoffset,yoffset) ); if (!isLerp) { if (LefthandData.Count < 20) { LefthandData.Enqueue(posSprite); } else { LefthandData.Dequeue(); LefthandData.Enqueue(posSprite); } if (RighthandData.Count < 20) { RighthandData.Enqueue(posSprite1); } else { RighthandData.Dequeue(); RighthandData.Enqueue(posSprite1); } LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition = new Vector3(LefthandData.Average(item => item.x), LefthandData.Average(item => item.y), LefthandData.Average(item => item.z)); if (BothHand) { RightCursor.transform.GetComponent<RectTransform>().anchoredPosition = new Vector3(RighthandData.Average(item => item.x), RighthandData.Average(item => item.y), RighthandData.Average(item => item.z)); } } else { LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition = Vector3.Lerp(LeftCursor.transform.GetComponent<RectTransform>().anchoredPosition, posSprite, Time.deltaTime * 10); if (BothHand) { RightCursor.transform.GetComponent<RectTransform>().anchoredPosition = Vector3.Lerp(RightCursor.transform.GetComponent<RectTransform>().anchoredPosition, posSprite1, Time.deltaTime * 10); ; } } } }