使用 MediaPipe 在 Unity 中将虚拟头与真实面孔对齐

使用 MediaPipe 在 Unity 中将虚拟头与真实面孔对齐
使用 MediaPipe 在 Unity 中将虚拟头与真实面孔对齐

AR 开发的虚拟头部放置面临的挑战

从事增强现实 (AR) 项目既令人兴奋又充满挑战。在使用 Unity 开发 Android 应用程序时,我的目标是通过将虚拟头部放置在现实世界的面孔上来无缝地融合数字世界和现实世界。此功能在很大程度上依赖于精度来创造身临其境的体验。 🕶️

为了实现这一目标,我利用 Google 的 MediaPipe 来检测眼睛、鼻子和嘴巴等面部标志。然后根据这些关键点生成并放置虚拟头部。看到现代工具如何改变 AR 的可能性真是令人着迷,但这段旅程远非完美。

当虚拟头部未按预期与实际面部对齐时,问题就出现了。无论角度或设备如何,放置总是有点“偏离”,导致不自然的效果。就好像虚拟表现与现实脱节一样。这引发了一系列故障排除实验。

从调整 Unity 的相机设置到尝试 MediaPipe 的算法,每一次尝试都带来了渐进式的改进,但没有确定的解决方案。本文深入探讨了问题的核心、经验教训以及面临类似挑战的开发人员的潜在解决方案。 🚀

命令 使用示例
mainCamera.usePhysicalProperties 此命令允许使用 Unity 的物理相机属性,从而可以更精确地控制焦距和镜头畸变,以对齐虚拟和现实世界的对象。
faceMesh.GetDetectedFaceTransform() 从 MediaPipe 的面部网格中检索检测到的面部的变换数据(位置和旋转),这对于将虚拟头部准确地放置在真实面部上至关重要。
UnityObjectToClipPos 着色器特定的函数,可将顶点位置从对象空间转换到剪辑空间,用于镜头畸变校正着色器以确保对齐。
tex2D 用于在指定 UV 坐标处对纹理进行采样的着色器命令,这对于对相机输入应用失真校正至关重要。
length(distUV) 计算 UV 坐标距原点的欧几里德距离,利用该距离应用渐进的镜头畸变调整。
adjuster.virtualHead 引用虚拟头部游戏对象的脚本变量,使其位置和旋转能够根据面部跟踪数据动态更新。
[TestFixture] 一个 NUnit 属性,将类标记为测试装置,表明它包含单元测试。这对于验证虚拟头对齐逻辑很有用。
Assert.AreEqual 一种 NUnit 方法,用于在单元测试期间比较预期值和实际值,确保虚拟头部放置与所需结果相匹配。
_DistortionStrength 一个着色器属性,用于调整镜头畸变的强度,微调现实世界和虚拟世界之间的对齐。
Quaternion.Euler 创建基于欧拉角的旋转,通常用于对齐 Unity 3D 空间中的虚拟头部等对象。

使用 Unity 和 MediaPipe 提高 AR 准确性

我们探索的第一个脚本重点关注使用 Unity 的物理相机属性。通过启用 使用物理特性,我们调整相机的行为以更接近现实世界的光学。这在使用 AR 时尤其重要,即使焦距或视野的微小差异也会使虚拟对象看起来未对齐。例如,将焦距设置为 35mm 等精确值可以帮助将虚拟头部与检测到的脸部对齐。这种调整类似于微调望远镜,使远处的物体完美聚焦,确保 AR 体验感觉自然且身临其境。 📸

脚本的另一个重要组成部分是使用以下方法检索检测到的面部位置和旋转 FaceMesh.GetDetectedFaceTransform()。此功能提供 MediaPipe 脸部网格的实时更新,这对于同步虚拟头部与用户的动作至关重要。想象一下,在玩一款视频游戏时,你的角色的头部与你的头部不同步;这种体验会很不和谐。通过确保精确对齐,该脚本将 AR 从一种新奇事物转变为一种可以支持虚拟会议或高级游戏等应用程序的工具。

第二个脚本深入研究着色器编程,特别是解决镜头失真问题。着色器使用 _DistortionStrength 之类的属性来控制 UV 坐标映射到纹理的方式,从而纠正相机输入中的扭曲。这在处理具有独特畸变曲线的广角镜头或相机时特别有用。例如,如果虚拟头部根据角度看起来比实际脸部更大或更小,则调整扭曲设置可确保更好的对齐。这就像调整镜子的框架以消除游乐场效应,使反射更加真实。 🎨

最后,第三个脚本的单元测试验证了解决方案。这些测试将虚拟头的预期位置和旋转与实际结果进行比较,确保在各种条件下都能进行调整。使用 NUnit 断言.AreEqual,开发人员可以模拟不同的场景,例如快速移动头部或以极端角度倾斜头部,以确认对齐。例如,在开发过程中,我注意到,当面朝前方时,对齐效果很好,但当头部转向一侧时,对齐效果会发生漂移。这些单元测试突出了这个问题并指导了进一步的改进,强调了彻底测试在创建强大的 AR 应用程序中的重要性。 🚀

使用 Unity 和 MediaPipe 调整 AR 中的虚拟对象放置

方案一:使用Unity的物理相机调整FOV和镜头畸变

// Import necessary Unity libraries
using UnityEngine;
using Mediapipe.Unity;

public class VirtualHeadAdjuster : MonoBehaviour
{
    public Camera mainCamera; // Assign Unity's physical camera
    public GameObject virtualHead; // Assign the virtual head prefab
    private MediapipeFaceMesh faceMesh; // MediaPipe's face mesh component

    void Start()
    {
        // Enable Unity's physical camera
        mainCamera.usePhysicalProperties = true;
        mainCamera.focalLength = 35f; // Set a standard focal length
    }

    void Update()
    {
        if (faceMesh != null && faceMesh.IsTracking)
        {
            // Update the virtual head's position and rotation
            Transform detectedHead = faceMesh.GetDetectedFaceTransform();
            virtualHead.transform.position = detectedHead.position;
            virtualHead.transform.rotation = detectedHead.rotation;
        }
    }
}

探索虚拟头部对齐的替代调整

解决方案 2:使用自定义着色器来校正镜头畸变

Shader "Custom/LensDistortionCorrection"
{
    Properties
    {
        _DistortionStrength ("Distortion Strength", Float) = 0.5
    }

    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            float _DistortionStrength;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 distUV = i.uv - 0.5;
                distUV *= 1.0 + _DistortionStrength * length(distUV);
                distUV += 0.5;
                return tex2D(_MainTex, distUV);
            }
            ENDCG
        }
    }
}

测试 Unity AR 项目中的增强兼容性

解决方案 3:实施虚拟头对齐单元测试

using NUnit.Framework;
using UnityEngine;
using Mediapipe.Unity;

[TestFixture]
public class VirtualHeadAlignmentTests
{
    private VirtualHeadAdjuster adjuster;
    private GameObject testHead;

    [SetUp]
    public void Init()
    {
        GameObject cameraObject = new GameObject("MainCamera");
        adjuster = cameraObject.AddComponent<VirtualHeadAdjuster>();
        testHead = new GameObject("VirtualHead");
        adjuster.virtualHead = testHead;
    }

    [Test]
    public void TestVirtualHeadAlignment()
    {
        Vector3 expectedPosition = new Vector3(0, 1, 2);
        Quaternion expectedRotation = Quaternion.Euler(0, 45, 0);

        adjuster.virtualHead.transform.position = expectedPosition;
        adjuster.virtualHead.transform.rotation = expectedRotation;

        Assert.AreEqual(expectedPosition, testHead.transform.position);
        Assert.AreEqual(expectedRotation, testHead.transform.rotation);
    }
}

通过增强的校准技术完善 AR 放置

AR 对准问题中经常被忽视的一个方面是相机校准的重要性。在 AR 项目中,例如将虚拟头部放置在真实头部上,镜头的 内在参数 发挥着至关重要的作用。这些参数包括焦距、光学中心和畸变系数。当这些值不准确时,虚拟头可能会出现未对准或扭曲的情况。为了解决这个问题,可以使用校准工具来计算特定设备相机的这些参数。例如,OpenCV 等软件提供强大的校准实用程序来生成精确的相机矩阵和畸变曲线。 📐

另一种方法涉及利用 Unity 后处理堆栈。通过应用景深或色差校正等效果,您可以消除渲染的虚拟头部与真实环境之间的差异。后处理增加了一层修饰,弥合了虚拟对象和物理空间之间的差距。例如,微妙的模糊效果可以减少使未对准变得明显的粗糙边缘。这在用户高度关注场景的沉浸式应用程序中特别有用。

最后,不要低估运行时动态适应的力量。将机器学习模型纳入 AR 管道中可以让系统随着时间的推移进行学习和调整放置。例如,人工智能模型可以分析用户反馈或检测到的不一致之处,并动态调整对齐方式。这使得系统更加稳健,能够处理照明、设备性能或用户行为的变化。这些改进确保了无缝的 AR 体验,让虚拟世界和现实世界真正融为一体。 🚀

有关 MediaPipe 和 Unity AR 放置的常见问题

  1. 为什么我的虚拟头部与真实脸部不一致?
  2. 该问题通常源于相机校准不当。使用OpenCV等工具来计算 camera matrixdistortion coefficients 可以大大改善对齐。
  3. 焦距在 AR 对准中起什么作用?
  4. focal length 定义相机如何将 3D 点投影到 2D 平面上。在Unity的物理相机设置中调整它可以提高准确性。
  5. Unity 可以处理镜头畸变校正吗?
  6. 是的,Unity 支持用于失真校正的着色器。实现一个具有如下属性的着色器 _DistortionStrength 根据您的镜头配置文件自定义校正。
  7. 如何测试虚拟对象的对齐情况?
  8. 在 NUnit 中使用单元测试,命令如下 Assert.AreEqual 允许您验证虚拟对象在各种条件下的定位和旋转。
  9. AR项目需要后期处理吗?
  10. 虽然不是强制性的,但后处理效果如 depth of fieldchromatic aberration 可以增强AR场景的视觉质量和真实感。
  11. MediaPipe 可以检测人脸以外的物体吗?
  12. 是的,MediaPipe 提供了针对手部、姿势甚至整体跟踪的解决方案,使其适用于不同的 AR 用例。
  13. 哪些硬件最适合 Unity AR 应用程序?
  14. 具有高性能 GPU 和精确相机的设备是理想的选择。类似的工具 ARCoreARKit 进一步增强兼容性。
  15. 为什么在某些角度对准效果较差?
  16. 这可能是由于相机和虚拟环境之间的视野不匹配造成的。调整 Unity 相机的 fieldOfView 财产可能会有所帮助。
  17. 着色器如何改善 AR 对齐?
  18. 着色器允许实时调整渲染,例如校正扭曲或模拟镜头效果,确保虚拟和真实对象之间更好的同步。
  19. AR 系统可以随着时间的推移进行自我调整吗?
  20. 是的,集成机器学习模型使系统能够动态适应,从反馈中学习,以随着时间的推移提高一致性和性能。

提高 AR 准确性:最终想法

实现虚拟和现实世界对象之间的精确对齐对于沉浸式 AR 体验至关重要。通过仔细的校准和先进的技术,可以减轻镜头畸变和焦距不匹配等问题,确保更好的精度和用户满意度。

集成 Unity 的工具、MediaPipe 算法和动态调整为 AR 开发人员提供了强大的解决方案。这些改进实现了数字世界和物理世界的无缝融合,为游戏、虚拟会议等带来了新的可能性。通过坚持和创新,AR 对齐挑战变得可控。 🚀

来源和参考文献
  1. 有关在 Unity 中使用 MediaPipe 的详细信息,请参考 MediaPipe 官方文档。探索它 这里
  2. 有关 Unity 相机校准和物理属性的指南可以在 Unity 文档网站上找到。访问 Unity相机设置 了解更多详情。
  3. AR 应用程序和镜头畸变校正的着色器编程受到有关着色器开发的文章的启发,例如 猫式编码
  4. ARCore 的 Android 开发功能和限制已在 Google 的 ARCore 开发者网站上进行了审核。了解更多信息,请访问 谷歌ARCore