如何用vuforia修复脚本捕获错误,统一脚本hololens

时间:2019-03-26 11:12:05

标签: c# unity3d vuforia hololens

我正在尝试使用我的PhotoCapture统一脚本通过Hololens拍照。我想使用Vuforia Engine ARCamera,以便在我看到自己创建的AR-GUI(用于将来的功能)的同时看到现实。

我得到的主要错误是:

  

无法捕获照片(hr = 0xC00D3704)

为什么会发生?我该如何解决?

  

FocusManager单例尚未初始化。   UnityEngine.Debug:Assert(布尔值,字符串)   HoloToolkit.Unity.Singleton`1:AssertIsInitialized()(在   资产/ HoloToolkit /通用/脚本/Singleton.cs:51)   HoloToolkit.Unity.CanvasHelper:Start()(在   Assets / HoloToolkit / Utilities / Scripts / CanvasHelper.cs:30)

也是启动统一场景时发生的错误,但我以前没有遇到过...

这是我正在使用的代码,放置在ARCamera上(还尝试了带有vuforia行为脚本的混合现实相机,但没有收到第二个错误)。另外,我想向借这个代码的人表示歉意,因为我不记得您网站的链接。

public class PhotoCaptureExample : MonoBehaviour
{
    PhotoCapture photoCaptureObject = null;
    Texture2D targetTexture = null;
    public string path = "";
    CameraParameters cameraParameters = new CameraParameters();

void Start()
{

}

void Update()
{
    if (Input.GetKeyDown("k"))
    {
        Debug.Log("k was pressed");

        Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
        targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);

        // Create a PhotoCapture object
        PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
        {
            photoCaptureObject = captureObject;
            cameraParameters.hologramOpacity = 0.0f;
            cameraParameters.cameraResolutionWidth = cameraResolution.width;
            cameraParameters.cameraResolutionHeight = cameraResolution.height;
            cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;

            // Activate the camera
            photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result)
            {
                // Take a picture
                photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
            });
        });
    }
}

string FileName(int width, int height)
{
    return string.Format("screen_{0}x{1}_{2}.png", width, height, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
}

void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
    // Copy the raw image data into the target texture
    photoCaptureFrame.UploadImageDataToTexture(targetTexture);

    Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();

    targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);
    targetTexture.Apply();

    byte[] bytes = targetTexture.EncodeToPNG();

    string filename = FileName(Convert.ToInt32(targetTexture.width), Convert.ToInt32(targetTexture.height));
    //save to folder under assets
    File.WriteAllBytes(Application.dataPath + "/Snapshots/" + filename, bytes);
    Debug.Log("The picture was uploaded");

    // Deactivate the camera
    photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}

void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
    // Shutdown the photo capture resource
    photoCaptureObject.Dispose();
    photoCaptureObject = null;
}
}

似乎无法到达OnCapturedPhotoToMemory或方法调用已经中断了它。现在再次尝试该代码有时不会注册我完全按下k的地方...

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

问题是:相机上的Vuforia的VuforiaBehaviour将访问权保留在设备的真实相机硬件上=>同时没有其他东西可以使用它。


要解决此问题,您可以使用专用于Vuforia的相机(只需在场景中的某个地方放置新的GameObject,例如VuforiaCamera,并在其上附加一个Camera组件和一个VuforiaBehaviour

enter image description here

在Vuforia相机上,将Culling Mask设置为Nothing(我们不使用该相机渲染任何内容),将Depth设置为例如-2(较高的值显示在顶部->将其置于所有其他摄像机的后面)。

enter image description here

您必须执行此操作,否则Vuforia会自动将其添加到主摄像头(我们不想禁用它,因为那样我们就看不到任何东西)。通过手动将其中一个添加到场景中,Vuforia会自动使用它。

您需要在任何地方使用摄像机的场景中的任何地方,都使用Holo-Tookit上的原始摄像机(通常使用MainCamera)。问题是您无法完全依赖脚本中的Camera.main,因为在运行时VuforiaBehaviour也会自动将其Camera标记为MainCamera ...(-_-)Vuforia。 ..因此,我总是禁用和启用VuforiaBehaviour以及GameObject,但也许仅禁用和启用GameObject就足够了。我猜至少应该在GameStart上将其禁用,直到所有依赖Camera.main的事物都结束为止。

然后,您只需禁用上面带有VuforiaCamera的{​​{1}}。

VuforiaBehaviour

通过这样做,设备的相机是“免费的”,并且PhotoCapture现在可以使用它。

VuforiaBehaviour.Instance.gameObject.SetActive(false);

// Note: that part I'm just inventing since I did it different
// using reference etc. I hope vuforia does not destroy the Instance
// OnDisable .. otherwise you would need the reference instead of using Instance here
// but maybe it is already enough to just enable and disable the GameObject
VuforiaBehaviour.Instance.enabled = false;

如果您随后需要再次使用照相机进行拍子,请先停止PhotoCapture

PhotoCapture.StartPhotoModeAsync(....

,然后在回调中停止后,重新启用PhotoCapture.StopPhotoModeAsync(.. (带有ARCamera的对象)和VuforiaBehaviour


类似

VuforiaBehaviour

但是,该异常也可能与this issue有关。