如何使用 vuforia 修复照片捕获错误,hololens 统一脚本
How to fix photocapture error with vuforia, script in unity for hololens
我正在尝试使用我的 PhotoCapture unity 脚本通过 Hololens 拍照。我想使用 Vuforia 引擎 ARCamera,以便在看到我创建的 AR-GUI(用于未来功能)的同时看到现实。
我得到的主要错误是:
Failed capturing photo (hr = 0xC00D3704)
为什么会发生?我该如何解决?
The FocusManager singleton has not been initialized.
UnityEngine.Debug:Assert(Boolean, String)
HoloToolkit.Unity.Singleton`1:AssertIsInitialized() (at
Assets/HoloToolkit/Common/Scripts/Singleton.cs:51)
HoloToolkit.Unity.CanvasHelper:Start() (at
Assets/HoloToolkit/Utilities/Scripts/CanvasHelper.cs:30)
也是unity场景启动时出现的错误,不过我之前没有...
这是我正在使用的代码,放置在 ARCamera 上(还尝试了带有 vuforia 行为脚本的混合现实相机,但没有出现第二个错误)。另外,我想向借用此代码的人道歉,因为我不记得您网站上的 link。
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
...
感谢任何帮助!!
问题是:摄像头上的 Vuforia VuforiaBehaviour
拥有对设备真实摄像头硬件的访问权 => 同时没有其他东西可以使用它。
为了解决这个问题,您可以使用 Vuforia 的专用相机(只需在某个地方放置一个新的游戏对象,例如 VuforiaCamera
在场景中并附加一个 Camera
组件以及一个 VuforiaBehaviour
在 Vuforia 相机上,将 Culling Mask
设置为 Nothing
(我们不使用该相机渲染任何内容),并将 Depth
设置为例如-2
(更高的值呈现在顶部 -> 将其放在所有其他相机的后面)。
你必须这样做,否则 Vuforia 会自动将它添加到主摄像头(我们不想禁用它,因为那样我们就看不到任何东西)。通过手动将一个添加到场景中,Vuforia 会自动使用那个。
场景中任何需要相机的地方,当然你都使用 Holo-Tookit 中的原始相机(你常用的 MainCamera
)。问题是您不能完全依赖脚本中的 Camera.main
,因为在运行时 VuforiaBehaviour
也会自动将其 Camera
标记为 MainCamera
... (-_-) Vuforia ... 所以另外我总是禁用和启用 VuforiaBehaviour
以及游戏对象,但也许只禁用和启用游戏对象就足够了。我猜至少在 GameStart 应该禁用它,直到依赖 Camera.main
的所有内容都完成。
然后你可以简单地禁用上面有 VuforiaBehaviour
的 VuforiaCamera
。
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;
通过执行此操作,设备的相机是 "free",PhotoCapture 现在可以使用它了。
PhotoCapture.StartPhotoModeAsync(....
如果您随后再次需要 vuforia 的相机,请先停止 PhotoCapture
PhotoCapture.StopPhotoModeAsync(..
然后在回调中停止后重新启用 ARCamera
(带有 VuforiaBehaviour
的对象)和 VuforiaBehaviour
。
类似
private void Awake()
{
var cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, captureObject =>
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
});
}
private void Update()
{
// if not initialized yet don't take input
if (photoCaptureObject == null) return;
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, result =>
{
if (result.success)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Couldn't start photo mode!", this);
}
});
}
}
private static string FileName(int width, int height)
{
return $"screen_{width}x{height}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png";
}
private 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.streamingAssetsPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
VuforiaBehaviour.Instance.gameObject.SetActive(true);
}
但是,异常也可能与 this issue.
有关
我正在尝试使用我的 PhotoCapture unity 脚本通过 Hololens 拍照。我想使用 Vuforia 引擎 ARCamera,以便在看到我创建的 AR-GUI(用于未来功能)的同时看到现实。
我得到的主要错误是:
Failed capturing photo (hr = 0xC00D3704)
为什么会发生?我该如何解决?
The FocusManager singleton has not been initialized. UnityEngine.Debug:Assert(Boolean, String) HoloToolkit.Unity.Singleton`1:AssertIsInitialized() (at Assets/HoloToolkit/Common/Scripts/Singleton.cs:51) HoloToolkit.Unity.CanvasHelper:Start() (at Assets/HoloToolkit/Utilities/Scripts/CanvasHelper.cs:30)
也是unity场景启动时出现的错误,不过我之前没有...
这是我正在使用的代码,放置在 ARCamera 上(还尝试了带有 vuforia 行为脚本的混合现实相机,但没有出现第二个错误)。另外,我想向借用此代码的人道歉,因为我不记得您网站上的 link。
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
...
感谢任何帮助!!
问题是:摄像头上的 Vuforia VuforiaBehaviour
拥有对设备真实摄像头硬件的访问权 => 同时没有其他东西可以使用它。
为了解决这个问题,您可以使用 Vuforia 的专用相机(只需在某个地方放置一个新的游戏对象,例如 VuforiaCamera
在场景中并附加一个 Camera
组件以及一个 VuforiaBehaviour
在 Vuforia 相机上,将 Culling Mask
设置为 Nothing
(我们不使用该相机渲染任何内容),并将 Depth
设置为例如-2
(更高的值呈现在顶部 -> 将其放在所有其他相机的后面)。
你必须这样做,否则 Vuforia 会自动将它添加到主摄像头(我们不想禁用它,因为那样我们就看不到任何东西)。通过手动将一个添加到场景中,Vuforia 会自动使用那个。
场景中任何需要相机的地方,当然你都使用 Holo-Tookit 中的原始相机(你常用的 MainCamera
)。问题是您不能完全依赖脚本中的 Camera.main
,因为在运行时 VuforiaBehaviour
也会自动将其 Camera
标记为 MainCamera
... (-_-) Vuforia ... 所以另外我总是禁用和启用 VuforiaBehaviour
以及游戏对象,但也许只禁用和启用游戏对象就足够了。我猜至少在 GameStart 应该禁用它,直到依赖 Camera.main
的所有内容都完成。
然后你可以简单地禁用上面有 VuforiaBehaviour
的 VuforiaCamera
。
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;
通过执行此操作,设备的相机是 "free",PhotoCapture 现在可以使用它了。
PhotoCapture.StartPhotoModeAsync(....
如果您随后再次需要 vuforia 的相机,请先停止 PhotoCapture
PhotoCapture.StopPhotoModeAsync(..
然后在回调中停止后重新启用 ARCamera
(带有 VuforiaBehaviour
的对象)和 VuforiaBehaviour
。
类似
private void Awake()
{
var cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, captureObject =>
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
});
}
private void Update()
{
// if not initialized yet don't take input
if (photoCaptureObject == null) return;
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, result =>
{
if (result.success)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Couldn't start photo mode!", this);
}
});
}
}
private static string FileName(int width, int height)
{
return $"screen_{width}x{height}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png";
}
private 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.streamingAssetsPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
VuforiaBehaviour.Instance.gameObject.SetActive(true);
}
但是,异常也可能与 this issue.
有关