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); ;

                }
            }
        }

    }

 

posted @ 2025-09-26 14:40  SummerTrainnn  阅读(7)  评论(0)    收藏  举报