图像识别与跟踪精度问题
特征点检测与匹配误差
Vuforia 通过识别图像中的特征点来确定目标的位置和姿态。当环境光线不稳定、目标图像纹理不丰富或者存在遮挡时,特征点的检测和匹配可能会出现误差。例如,在光线较暗的环境下,图像的对比度降低,特征点的提取变得困难,导致匹配的特征点数量减少或匹配不准确,从而使 AR 模型的位置和姿态计算出现偏差,表现为抖动。
跟踪丢失与重定位延迟
当目标被短暂遮挡或移出摄像头视野时,Vuforia 的跟踪可能会丢失。在重新跟踪时,需要一定的时间来重新检测和匹配特征点进行重定位。在这个过程中,由于位置和姿态信息的不稳定,AR 模型会出现抖动。而且,如果重定位算法不够高效,抖动的时间会更长。
- 设备硬件与性能问题
摄像头稳定性
移动设备的摄像头在拍摄过程中容易受到手持抖动的影响。当摄像头发生微小的晃动时,拍摄到的图像会产生位移,Vuforia 根据这些变化的图像来计算目标的位置和姿态,就会导致 AR 模型出现抖动。例如,用户手持设备时手部的轻微颤抖,会使摄像头拍摄的画面产生细微的偏移,进而影响 AR 模型的稳定显示。
设备处理性能不足
Vuforia 的图像识别和跟踪算法需要一定的计算资源来运行。如果设备的 CPU 或 GPU 性能较低,无法及时处理大量的图像数据和复杂的计算任务,就会导致跟踪结果的更新不及时,出现延迟和抖动。比如,在一些老旧的移动设备上运行 AR 应用,由于硬件性能有限,可能无法实时准确地计算 AR 模型的位置和姿态,从而出现明显的抖动现象。 - 模型与坐标系问题
模型自身的不稳定性
如果 AR 模型的重心设置不合理或者模型的碰撞体与实际模型不匹配,可能会导致模型在跟踪过程中出现不稳定的情况。例如,一个重心偏移的模型在虚拟空间中容易发生倾斜或晃动,即使跟踪算法准确地计算出了目标的位置和姿态,模型本身也会因为自身的不稳定性而抖动。
坐标系转换误差
Vuforia 使用的坐标系与 Unity 场景中的坐标系需要进行转换。在转换过程中,如果存在误差,会导致 AR 模型的位置和姿态与实际跟踪结果不一致,从而出现抖动。例如,坐标原点的不一致或者坐标轴的方向差异,都可能影响模型的正确显示。 - 算法与参数设置问题
跟踪算法的局限性
Vuforia 的跟踪算法虽然不断优化,但仍然存在一定的局限性。某些复杂的场景或目标可能超出了算法的处理能力,导致跟踪效果不佳,出现抖动。例如,对于快速移动的目标或者具有复杂纹理和形状的目标,算法可能无法准确地跟踪其位置和姿态。
参数设置不合理
Vuforia 提供了一些可调整的参数,如跟踪的灵敏度、平滑度等。如果这些参数设置不合理,可能会影响跟踪的稳定性。例如,跟踪灵敏度设置过高,会使模型对微小的变化过于敏感,容易出现抖动;而平滑度设置过低,无法有效过滤掉一些噪声,也会导致模型不稳定。
新建脚本挂载到模型上面即可
代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 防抖动
/// </summary>
public class FangDouDong : MonoBehaviour
{
private float lastX = 0;
private float lastY = 0;
private float lastZ = 0;
private float lastRX = 0;
private float lastRY = 0;
private float lastRZ = 0;
protected void Update()
{
//base.Update();
float myrx = 0;
myrx = this.transform.localEulerAngles.x;
while (myrx >= 360)//为了让判断条件时方便,强制把所有不在1~270以内的数字,转换为-270~270
{
myrx -= 360;
}
while (myrx <= -360)
{
myrx += 360;
}
while (myrx > 270 && 360 - myrx >= 0)
myrx = -(360 - myrx);
float myry = 0;
myry = this.transform.localEulerAngles.y;
while (myry >= 360)
{
myry -= 360;
}
while (myry <= -360)
{
myry += 360;
}
while (myry > 270 && 360 - myry >= 0)
myry = -(360 - myry);
float myrz = 0;
myrz = this.transform.localEulerAngles.z;
while (myrz >= 360)
{
myrz -= 360;
}
while (myrz <= -360)
{
myrz += 360;
}
while (myrz > 270 && 360 - myrz >= 0)
myrz = -(360 - myrz);
//关键,当模型抖动超过一定范围时,不修正模型的坐标角度,记录坐标和角度
if (((Math.Abs(this.transform.position.x - lastX) > 0.06 || Math.Abs(this.transform.position.y - lastY) > 0.06 || Math.Abs(this.transform.position.z - lastZ) > 0.06) &&
(Math.Abs(this.transform.position.x - lastX) > 0.13|| Math.Abs(this.transform.position.y - lastY) > 0.13 || Math.Abs(this.transform.position.z - lastZ) > 0.13)) ||
((Math.Abs(myrx - lastRX) > 3 && Math.Abs(myry - lastRY) > 3 && Math.Abs(myrz - lastRZ) > 3) && (Math.Abs(myrx - lastRX) > 6 || Math.Abs(myry - lastRY) > 6 || Math.Abs(myrz - lastRZ) > 6)))
{
lastX = this.transform.position.x;
lastY = this.transform.position.y;
lastZ = this.transform.position.z;
lastRX = myrx;
lastRY = myry;
lastRZ = myrz;
this.transform.rotation = Quaternion.Euler(lastRX, lastRY, lastRZ);
this.transform.position = new Vector3(lastX, lastY, lastZ);
}
else//模型抖动范围过小时,修正模型坐标为上一次正确的坐标
{
this.transform.rotation = Quaternion.Euler(lastRX, lastRY, lastRZ);
this.transform.position = new Vector3(lastX, lastY, lastZ);
}
}
}
再次测试模型就不抖动了