Unity3d 如何使用全息镜头前置摄像头

Unity3d 如何使用全息镜头前置摄像头,unity3d,hololens,Unity3d,Hololens,我正在使用全息镜头,我正在尝试获取前摄像头的图像。我唯一需要做的就是拍摄相机每一帧的图像,并将其转换为字节数组。在播放器设置中,启用对相机的访问,然后重试 遵循文档中的Unity示例。它有一个写得很好的例子: 从上面链接的unity文档中复制: 使用UnityEngine; 使用系统集合; 使用System.Linq; 使用UnityEngine.XR.WSA.WebCam; 公共类光捕获示例:MonoBehavior{ PhotoCapture photoCaptureObject=null

我正在使用全息镜头,我正在尝试获取前摄像头的图像。我唯一需要做的就是拍摄相机每一帧的图像,并将其转换为字节数组。

在播放器设置中,启用对相机的访问,然后重试

  • 遵循文档中的Unity示例。它有一个写得很好的例子:
  • 从上面链接的unity文档中复制:
    使用UnityEngine;
    使用系统集合;
    使用System.Linq;
    使用UnityEngine.XR.WSA.WebCam;
    公共类光捕获示例:MonoBehavior{
    PhotoCapture photoCaptureObject=null;
    Texture2D targetTexture=null;
    //用于初始化
    void Start(){
    分辨率cameraResolution=PhotoCapture.SupportedResolutions.OrderByDescending((res)=>res.width*res.height)。First();
    targetTexture=新纹理2D(cameraResolution.width、cameraResolution.height);
    //创建一个PhotoCapture对象
    CreateAsync(false,委托(PhotoCaptureObject){
    photoCaptureObject=captureObject;
    CameraParameters CameraParameters=新的CameraParameters();
    摄像机参数。全息容量=0.0f;
    cameraParameters.cameraResolutionWidth=cameraResolution.width;
    cameraParameters.cameraResolutionHeight=cameraResolution.height;
    cameraParameters.pixelFormat=CapturePixelFormat.BGRA32;
    //启动摄像机
    photoCaptureObject.StartPhotoModeAsync(cameraParameters,委托(PhotoCapture.PhotoCaptureResult){
    //拍照
    TakePhotoAsync(OnCapturedPhotoToMemory);
    });
    });
    }
    void onCapturedPhototomory(PhotoCapture.PhotoCaptureResult结果,PhotoCaptureFrame PhotoCaptureFrame){
    //将原始图像数据复制到目标纹理中
    photoCaptureFrame.UploadImageDataToTexture(targetTexture);
    //创建一个可以应用纹理的游戏对象
    GameObject quad=GameObject.CreatePrimitive(PrimitiveType.quad);
    Renderer quadRenderer=quad.GetComponent()作为渲染器;
    quadrender.material=新材质(Shader.Find(“自定义/未照明/未照明结构”);
    quad.transform.parent=this.transform;
    quad.transform.localPosition=新矢量3(0.0f、0.0f、3.0f);
    quadrender.material.SetTexture(“_MainTex”,targetTexture);
    //关闭相机
    photoCaptureObject.StopHotoModeAsync(OnStoppedPhotoMode);
    }
    无效OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult){
    //关闭照片捕获资源
    photoCaptureObject.Dispose();
    photoCaptureObject=null;
    }
    }
    
    要获取字节:请替换以下方法:
    void OnCapturedPhotoToMemory(PhotoCapture.photocapturesult结果,PhotoCaptureFrame PhotoCaptureFrame){
    //将原始图像数据复制到目标纹理中
    photoCaptureFrame.UploadImageDataToTexture(targetTexture);
    //创建一个可以应用纹理的游戏对象
    GameObject quad=GameObject.CreatePrimitive(PrimitiveType.quad);
    Renderer quadRenderer=quad.GetComponent()作为渲染器;
    quadrender.material=新材质(Shader.Find(“自定义/未照明/未照明结构”);
    quad.transform.parent=this.transform;
    quad.transform.localPosition=新矢量3(0.0f、0.0f、3.0f);
    quadrender.material.SetTexture(“_MainTex”,targetTexture);
    //关闭相机
    photoCaptureObject.StopHotoModeAsync(OnStoppedPhotoMode);
    }
    
    使用以下方法:
    void OnCapturedPhotoToMemory(PhotoCapture.photocapturesult结果,PhotoCaptureFrame PhotoCaptureFrame)
    {
    List imageBufferList=新列表();
    imageBufferList.Clear();
    photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList);
    var bytesArray=imageBufferList.ToArray();
    }
    
  • 如果您现在正在使用Unity 2018.1或2018.2(我认为也是2017.4),那么它将不起作用。Unity有公共追踪器解决此问题:
  • 在Unity修复bug之前,我创建了一个解决方案:
  • 不使用unity的PhotoCapture作为解决方案的基本示例:更多详细信息,请参见上面的链接 您必须添加35;如果WINDOWS_UWP能够使用MediaCapture:理想情况下,您希望使用unity的PhotoCapture来避免这种情况,但在unity解决问题之前,您可以使用类似的方法

    #if WINDOWS_UWP
            public async System.Threading.Tasks.Task<byte[]> GetPhotoAsync()
            {
                //Get available devices info
                var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(
                    Windows.Devices.Enumeration.DeviceClass.VideoCapture);
                var numberOfDevices = devices.Count;
    
                byte[] photoBytes = null;
    
                //Check if the device has camera
                if (devices.Count > 0)
                {
                    Windows.Media.Capture.MediaCapture mediaCapture = new Windows.Media.Capture.MediaCapture();
                    await mediaCapture.InitializeAsync();
    
                    //Get Highest available resolution
                    var highestResolution = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(
                        Windows.Media.Capture.MediaStreamType.Photo).
                        Select(item => item as Windows.Media.MediaProperties.ImageEncodingProperties).
                        Where(item => item != null).
                        OrderByDescending(Resolution => Resolution.Height * Resolution.Width).
                        ToList().First();
    
                    using (var photoRandomAccessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                    {
                        await mediaCapture.CapturePhotoToStreamAsync(highestResolution, photoRandomAccessStream);
    
                        //Covnert stream to byte array
                        photoBytes = await ConvertFromInMemoryRandomAccessStreamToByteArrayAsync(photoRandomAccessStream);
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("No camera device detected!");
                }
    
                return photoBytes;
            }
    
            public static async System.Threading.Tasks.Task<byte[]> ConvertFromInMemoryRandomAccessStreamToByteArrayAsync(
                Windows.Storage.Streams.InMemoryRandomAccessStream inMemoryRandomAccessStream)
            {
                using (var dataReader = new Windows.Storage.Streams.DataReader(inMemoryRandomAccessStream.GetInputStreamAt(0)))
                {
                    var bytes = new byte[inMemoryRandomAccessStream.Size];
                    await dataReader.LoadAsync((uint)inMemoryRandomAccessStream.Size);
                    dataReader.ReadBytes(bytes);
    
                    return bytes;
                }
            }
    #endif
    
    #如果WINDOWS\u UWP
    public async System.Threading.Tasks.Task GetPhotoAsync()
    {
    //获取可用设备信息
    var devices=wait Windows.devices.Enumeration.DeviceInformation.findalsync(
    Windows.Devices.Enumeration.DeviceClass.VideoCapture);
    var numberOfDevices=设备。计数;
    字节[]photoBytes=null;
    //检查设备是否有摄像头
    如果(devices.Count>0)
    {
    Windows.Media.Capture.MediaCapture MediaCapture=新的Windows.Media.Capture.MediaCapture();
    等待mediaCapture.InitializeAsync();
    //获得最高的可用分辨率
    var highestResolution=mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(
    Windows.Media.Capture.MediaStreamType.Photo)。
    选择(项=>项作为Windows.Media.MediaProperties.ImageEncodingProperties)。
    其中(item=>item!=null)。
    OrderByDescending(分辨率=>Resolution.Height*Resolution.Width)。
    ToList().First();
    使用(var photoRandomAccessStream=new Windows.Storage.Streams.InMemoryRandomAccessStream())
    {
    等待mediaCapture.CapturePhotoToStreamAsync(高分辨率,photoRandomAccessStream);
    //Covnert流到字节数组
    photoBytes=等待从InMemoryRandomAccessStream到ByteArrayAsync(photoRandomAccessStream)的转换;
    }
    }
    其他的
    {
    
        void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame) {
        // Copy the raw image data into the target texture
        photoCaptureFrame.UploadImageDataToTexture(targetTexture);
    
        // Create a GameObject to which the texture can be applied
        GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
        Renderer quadRenderer = quad.GetComponent<Renderer>() as Renderer;
        quadRenderer.material = new Material(Shader.Find("Custom/Unlit/UnlitTexture"));
    
        quad.transform.parent = this.transform;
        quad.transform.localPosition = new Vector3(0.0f, 0.0f, 3.0f);
    
        quadRenderer.material.SetTexture("_MainTex", targetTexture);
    
        // Deactivate the camera
        photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
    }
    
    void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
    {
        List<byte> imageBufferList = new List<byte>();
        imageBufferList.Clear();
        photoCaptureFrame.CopyRawImageDataIntoBuffer(imageBufferList);
        var bytesArray = imageBufferList.ToArray();
    }
    
    #if WINDOWS_UWP
            public async System.Threading.Tasks.Task<byte[]> GetPhotoAsync()
            {
                //Get available devices info
                var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(
                    Windows.Devices.Enumeration.DeviceClass.VideoCapture);
                var numberOfDevices = devices.Count;
    
                byte[] photoBytes = null;
    
                //Check if the device has camera
                if (devices.Count > 0)
                {
                    Windows.Media.Capture.MediaCapture mediaCapture = new Windows.Media.Capture.MediaCapture();
                    await mediaCapture.InitializeAsync();
    
                    //Get Highest available resolution
                    var highestResolution = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(
                        Windows.Media.Capture.MediaStreamType.Photo).
                        Select(item => item as Windows.Media.MediaProperties.ImageEncodingProperties).
                        Where(item => item != null).
                        OrderByDescending(Resolution => Resolution.Height * Resolution.Width).
                        ToList().First();
    
                    using (var photoRandomAccessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                    {
                        await mediaCapture.CapturePhotoToStreamAsync(highestResolution, photoRandomAccessStream);
    
                        //Covnert stream to byte array
                        photoBytes = await ConvertFromInMemoryRandomAccessStreamToByteArrayAsync(photoRandomAccessStream);
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("No camera device detected!");
                }
    
                return photoBytes;
            }
    
            public static async System.Threading.Tasks.Task<byte[]> ConvertFromInMemoryRandomAccessStreamToByteArrayAsync(
                Windows.Storage.Streams.InMemoryRandomAccessStream inMemoryRandomAccessStream)
            {
                using (var dataReader = new Windows.Storage.Streams.DataReader(inMemoryRandomAccessStream.GetInputStreamAt(0)))
                {
                    var bytes = new byte[inMemoryRandomAccessStream.Size];
                    await dataReader.LoadAsync((uint)inMemoryRandomAccessStream.Size);
                    dataReader.ReadBytes(bytes);
    
                    return bytes;
                }
            }
    #endif