【问题标题】:HoloLens - How to get webcam texture 2D from VuforiaHoloLens - 如何从 Vuforia 获取网络摄像头纹理 2D
【发布时间】:2019-10-22 07:43:08
【问题描述】:

我正在使用 Unity 为 HoloLens 开发 Vuforia 应用程序。

当检测到图像目标时,此应用会显示一个简单的 3D 对象。

我还使用 Unity Asset Store 中的 fm Exhibition Tool Pack hololens 将 HoloLens 上运行的应用流式传输到 PC。

一切正常,但是当我将应用程序流式传输到 PC 时,我看到的是 3D Unity 场景而不是房间。

所以我尝试获取网络摄像头纹理并将其附加到场景内的立方体上,但 vuforia ARCamera 与它发生了某种冲突,我在立方体上看不到任何东西。相反,当我在 Unity Simulator 中运行应用程序时,我看到自己在立方体上。

有没有办法从 Vuforia 获取网络摄像头纹理 2D 并将其附加到场景内的游戏对象?也许与 Vuforia.Image 类?但我不知道它是如何工作的。

【问题讨论】:

  • 据我所知,一次只有一个进程可以访问相机。只要您使用 Vuforia 并且它正在流式传输,我认为您不能同时访问 cam。

标签: unity3d vuforia hololens


【解决方案1】:

以下脚本与 FMETP STREAM 兼容。 这些脚本在移动设备上进行了测试。

using UnityEngine;
using System.Collections;
using Vuforia;
using UnityEngine.UI;

public class VuforiaCamAccess : MonoBehaviour
{
    private bool mAccessCameraImage = true;
    public RawImage rawImage;
    public GameObject Mesh;
    private Texture2D texture;

#if UNITY_EDITOR
    private Vuforia.PIXEL_FORMAT mPixelFormat = Vuforia.PIXEL_FORMAT.GRAYSCALE;
#else
    private Vuforia.PIXEL_FORMAT mPixelFormat =  Vuforia.PIXEL_FORMAT.RGB888;
#endif

    private bool mFormatRegistered = false;

    void Start()
    {
#if UNITY_EDITOR
        texture = new Texture2D(Screen.width, Screen.height, TextureFormat.R8, false);
#else
        texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
#endif
        // Register Vuforia life-cycle callbacks:
        Vuforia.VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
        Vuforia.VuforiaARController.Instance.RegisterOnPauseCallback(OnPause);
        Vuforia.VuforiaARController.Instance.RegisterTrackablesUpdatedCallback(OnTrackablesUpdated);
    }

    private void OnVuforiaStarted()
    {
        // Try register camera image format
        if (CameraDevice.Instance.SetFrameFormat(mPixelFormat, true))
        {
            Debug.Log("Successfully registered pixel format " + mPixelFormat.ToString());
            mFormatRegistered = true;
        }
        else
        {
            Debug.LogError("Failed to register pixel format " + mPixelFormat.ToString() +
                "\n the format may be unsupported by your device;" +
                "\n consider using a different pixel format.");
            mFormatRegistered = false;
        }
    }

    private void OnPause(bool paused)
    {
        if (paused)
        {
            Debug.Log("App was paused");
            UnregisterFormat();
        }
        else
        {
            Debug.Log("App was resumed");
            RegisterFormat();
        }
    }

    private void OnTrackablesUpdated()
    {
        //skip if still loading image to texture2d
        if (LoadingTexture) return;

        if (mFormatRegistered)
        {
            if (mAccessCameraImage)
            {
                Vuforia.Image image = CameraDevice.Instance.GetCameraImage(mPixelFormat);
                //if (image != null && image.IsValid())
                if (image != null)
                {
                    byte[] pixels = image.Pixels;
                    int width = image.Width;
                    int height = image.Height;
                    StartCoroutine(SetTexture(pixels, width, height));
                }
            }
        }
    }

    bool LoadingTexture = false;
    IEnumerator SetTexture(byte[] pixels, int width, int height)
    {
        if (!LoadingTexture)
        {
            LoadingTexture = true;
            if (pixels != null && pixels.Length > 0)
            {
                if (texture.width != width || texture.height != height)
                {
#if UNITY_EDITOR
                    texture = new Texture2D(width, height, TextureFormat.R8, false);
#else
                    texture = new Texture2D(width, height, TextureFormat.RGB24, false);
#endif
                }

                texture.LoadRawTextureData(pixels);
                texture.Apply();

                if (rawImage != null)
                {
                    rawImage.texture = texture;
                    rawImage.material.mainTexture = texture;
                }

                if (Mesh != null) Mesh.GetComponent<Renderer>().material.mainTexture = texture;
            }
            yield return null;
            LoadingTexture = false;
        }
    }

    private void UnregisterFormat()
    {
        Debug.Log("Unregistering camera pixel format " + mPixelFormat.ToString());
        CameraDevice.Instance.SetFrameFormat(mPixelFormat, false);
        mFormatRegistered = false;
    }

    private void RegisterFormat()
    {
        if (CameraDevice.Instance.SetFrameFormat(mPixelFormat, true))
        {
            Debug.Log("Successfully registered camera pixel format " + mPixelFormat.ToString());
            mFormatRegistered = true;
        }
        else
        {
            Debug.LogError("Failed to register camera pixel format " + mPixelFormat.ToString());
            mFormatRegistered = false;
        }
    }
}

【讨论】:

  • 感谢您提供这个有用的答案。你知道为什么编辑器中的纹理是红色的以及如何修复它吗?
  • 据我记忆,它默认只返回编辑器中的单声道。这是我测试时的 Vuforia 限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多