我们正在尝试在Hololens上使用多线程,但是失败了。 由于我们不知道如何以及在附加线程中实现什么。
当前,我们的应用程序正在主线程中运行许多操作,如果我们启动“实时流”(与WebcamTexture一起使用),全息图将不再显示。
因此,从一开始,我们想问一下如何使用线程更有效地运行图像捕获代码的一部分(如下所示)?这样我们就可以了解哪些部分可以在不同的线程中运行。
我们正在使用Unity 2018.4.10f1
using UnityEngine;
using System.Linq;
using UnityEngine.XR.WSA.WebCam;
public partial class PhotocaptureFrame : MonoBehaviour
{
public PhotoCapture photoCaptureObject = null;
public GameObject quad;
public static PhotocaptureFrame Instance { get; set; }
private Texture2D imageTexture;
private CameraParameters c;
private Resolution cameraResolution;
private void Start()
{
cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
//CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32;
captureObject.StartPhotoModeAsync(c, delegate (PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
Instance = this;
}
public void MakePhoto()
{
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
captureObject.StartPhotoModeAsync(c, delegate (PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
public void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First(); // Create our Texture2D for use and set the correct resolution
Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
photoCaptureFrame.UploadImageDataToTexture(targetTexture); // Copy the raw image data into our target texture
imageTexture = targetTexture; //Save image to new Texture to not loose it
quad.GetComponent<Renderer>().material.mainTexture = imageTexture; // Do as we wish with the texture such as apply it to a material, etc.
//photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoModeEnd);
// Clean up
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoModeEnd);
}
public void OnStoppedPhotoModeEnd(PhotoCapture.PhotoCaptureResult result)
{
photoCaptureObject.Dispose();
photoCaptureObject = null;
Debug.Log("Photo object disposed.");
}
}
我们的预期输出是知道我们可以在不同线程中运行哪些块,以及如何在Hololens上调用不同线程。
感谢分配,感谢您的帮助。
答案 0 :(得分:1)
尽管这不能直接回答您的问题,但我真的可以推荐此插件:HololensCameraStream,该插件内部使用MediaCapture
类。
帧是异步获取的,这意味着Videocapture本身实际上在其自己的线程中运行。此外,与使用PhotoCapture
的方法相比,性能更好(可以获取更多帧)。
您将在回调函数中获得每一帧。
由于此回调未在Unity主线程上运行,因此您将需要利用某种作业系统来调用Unity函数。我使用了这个方便的脚本:https://github.com/PimDeWitte/UnityMainThreadDispatcher
如果这有帮助,并且您还有其他问题,我可以添加更多有关如何进行设置的详细信息。
答案 1 :(得分:0)
Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
...
quad.GetComponent<Renderer>().material.mainTexture = imageTexture;
您只能在Unity的主线程上创建和分配纹理。正确且唯一的解决方案是调查WebCamTexture
。您可能会遇到权限问题。
答案 2 :(得分:0)
我建议您异步使用MediaCapture
类进行视频流捕获。在实际示例中,Microsoft HoloLensCamera中的SpectatorView类使用MediaCapture类访问HoloLens摄像机的视频流。在861行中,它声明MediaCapture类的实例,并在下一个代码中异步地从摄像机获取视频帧。