在Unity中使用相机

调整相机以将聚焦良好的相机帧传送到Vuforia引擎。使用CameraDevice返回的Image类从应用程序访问相机帧。

设置相机、焦点和曝光模式

调整相机相关模式,以针对不断变化的环境条件优化其性能。

只要Vuforia Engine有权访问相机,其他设备应用程序就无法访问它。通过停止Vuforia Engine释放相机,以允许其他应用程序访问它:

Vuforia行为。Instance.enabled=false;

在Unity中,这是在应用程序暂停时自动完成的。

照相机模式

The 摄像头模式可以从照相机设备模式英寸Vuforia配置在中检查器窗口ARCamera游戏对象.

或者,您可以使用继承自单一行为。这将向注册回调Vuforia行为这将在Vuforia引擎启动时设置相机模式。

无效开始(){Vuforia应用程序。实例。OnVuforiaStarted+=OnVuforiaStarted;}私有无效OnVuforiaStarted(){Vuforia行为。实例。摄像头设备。设置摄像头模式(Vuforia.CameraMode.MODE_DEFAULT);}
的枚举器摄像头模式

模式默认值

速度和质量之间的最佳折衷。

模式_优化_速度

将Vuforia引擎对系统的影响降至最低。

模式_优化_质量

优化以获得更好的图像和跟踪质量。对系统应用更高的资源影响。

如果没有其他设置,则使用MODE_DEFAULT。

如果Vuforia引擎影响设备的性能,请将模式更改为mode_OPTIMIZE_SPEED。如果您希望目标连续移动,建议使用默认模式

对焦模式

这个焦点模式由设置摄像头设备类。我们建议在大多数情况下使用连续自动对焦模式。并非所有设备都支持所有对焦模式。

bool-focusModeSet=VuforiaBehaviour。实例。摄像头设备。设置焦点模式(FocusMode.FOCUS_MODE_CONTINUOUAUTO);if(!focusModeSet){调试。日志(“设置焦点模式失败”+focusModeSet);}

焦点模式枚举焦点模式

行为

聚焦模式固定

将相机设置为由相机驱动程序定义的固定焦点。

聚焦模式_触发自动

触发单个自动对焦操作。

操作完成后,焦点模式将自动更改为focus_mode_FIXED。

设置感兴趣的摄像头区域之后需要设置TRIGGERAUTO。

焦点模式持续使用自动

允许您为相机启用驾驶员级别的连续自动对焦。建议使用此模式,因为它可以确保相机始终聚焦在目标上。

焦点模式不确定性

将相机设置为无穷大,如相机驱动程序实现所提供的那样。此模式将设置摄影机始终聚焦于场景中的背景元素。(仅在没有ARCore的UWP和Android上支持)。

焦点模式话筒

将相机设置为宏模式,如相机驱动程序实现所提供的那样。此模式为大约15厘米的特写镜头提供清晰的相机图像,在AR设置中很少使用。(iOS和Magic Leap不支持)

如果没有其他设置,则使用平台的默认焦点模式。

焦点区域

允许用户只关注相机框架的一个区域。使用感兴趣的摄像头区域表示以像素为单位的感兴趣区域屏幕位置和相机帧宽度和高度大小的百分比范围。这允许用户轻触屏幕以关注特定的屏幕区域。

感兴趣的摄像头区域必须将聚焦模式设置为focus_mode_CONTINUOUSAUTO才能触发重新聚焦。重新对焦后,模式将自身设置为focus_mode_FIXED。

注意:仅聚焦摄影机视图的某个区域可能会干扰并降低该区域外Vuforia目标的检测和跟踪。

首先,确保设备支持使用支持的焦点区域发动机运行时。然后,使用感兴趣的地区数据结构:

无效更新(){if(Input.touchCount>0){var touch=输入。GetTouch(0);if(touch.phase==TouchPhase.Ended){设置焦点区域(触摸位置,0.25f);}}}void SetFocusRegion(矢量2焦点位置,浮动范围){var regionOfInterest=新的CameraRegionOfIntest(焦点位置,范围);如果(VuforiaBehavior.Instance.CameraDevice.FocusRegionSupported==true){var成功=VuforiaBehaviour。实例。摄像头设备。SetFocusRegion(感兴趣的区域);if(成功){Vuforia行为。实例。摄像头设备。设置焦点模式(FocusMode.FOCUS_MODE_TRIGGERAUTO);}其他的{调试。日志(“无法设置区域的焦点模式”+regionOfInterest.ToString());}}其他的{调试。日志(“支持焦点区域:”+VuforiaBehaviour.Instance.CameraDevice.FocusRegionSupported);Vuforia行为。实例。摄像头设备。设置焦点区域(CameraRegionOfInterest.Default());}}

使用以像素为单位的屏幕坐标作为触摸位置的替代,以在感兴趣的摄像头().
使用重置焦点区域感兴趣的摄像头区域。默认()或设置感兴趣的摄像头区域收件人:

Vuforia行为。实例。摄像头设备。SetFocusRegion(新的CameraRegionOfInterest(新的(屏幕宽度/2f,屏幕高度/2f),1.0f));

如果Vuforia引擎暂停,焦点区域将重置并恢复为其默认值。

注意:在UWP上,将范围(用于聚焦和曝光)设置为小于0.05(5%)会引发错误,因为平台认为该值太小。

使用get方法返回当前活动区域以进行自动对焦。

获取焦点区域();

注:在iOS上,只返回屏幕位置。iOS在内部更改此值时,范围(用于聚焦和曝光)将作为0返回。范围仍应设置在感兴趣的摄像头区域.

曝光模式

通过设置曝光模式以校正照明设置来调整相机帧上的曝光。请注意,并非所有设备都支持所有可用的曝光模式。

首先,验证设备是否支持要更改为的曝光模式:

var exposureMode=曝光模式。曝光_模式_固定;IsExposureModeSupported(exposureMode);

在Vuforia引擎运行时设置曝光模式:

Vuforia行为。实例。摄像头设备。设置曝光模式(曝光模式.EXPOSURE_MODE_TRIGGERAUTO);

如果没有其他设置,则使用平台的默认曝光模式。

曝光模式曝光模式

曝光_MODE_TRIGGERAUTO

触发单个自动曝光操作。

操作完成后,曝光模式将自动更改为exposure_mode_FIXED。

设置感兴趣的摄像头区域之后需要设置TRIGGERAUTO。

曝光_MODE_CONTINUOUSAUTO

允许设备连续控制自动曝光。建议使用此模式,因为它可以确保相机始终在相机视图上应用曝光校正。

曝光模式固定

将曝光设置为相机驱动程序定义的固定值。

在大多数情况下,建议使用EXPOSURE_MODE_CONTINUOUAUTO模式。当环境光线强或不足时,应用其他模式显示目标。

在Vuforia引擎运行时设置或更改曝光模式可能需要在特定设备上花费更长的时间,直到曝光发生变化。

暴露区域

允许用户使用感兴趣的摄像头区域数据结构。将曝光区域设置为以像素为单位的感兴趣区域屏幕位置,范围为相机帧宽度和高度大小的百分比。 感兴趣的摄像头区域之后必须将曝光模式设置为exposure_mode_TRIGGERAUTO以触发重新曝光。重新曝光后,模式将自身设置为exposure_mode_FIXED。

注意:仅在摄影机视图的某个区域上调整曝光会干扰并降低该区域外Vuforia目标的检测和跟踪。

首先,确保设备支持设置曝光区域受支持的ExposureRegionVuforia引擎运行时。然后,使用感兴趣的地区变量:

无效更新(){if(Input.touchCount>0){var touch=输入。GetTouch(0);if(touch.phase==TouchPhase.Ended){设置焦点区域(触摸位置,0.25f);}}}void SetExposureRegion(矢量2焦点位置,浮动范围){var regionOfInterest=新的CameraRegionOfIntest(焦点位置,范围);if(VuforiaBehaviour.Instance.CameraDevice.ExposureRegionSupported==true){var success=Vuforia行为。实例。摄像头设备。设置曝光区域(感兴趣的区域);if(成功){Vuforia行为。实例。摄像头设备。设置曝光模式(曝光模式.EXPOSURE_MODE_TRIGGERAUTO);}其他的{调试。日志(“无法设置区域的曝光模式”+regionOfInterest.ToString());}}其他的{调试。日志(“支持的曝光区域:”+VuforiaBehaviour.Instance.CameraDevice.ExposureRegionSupported);Vuforia行为。实例。摄像头设备。设置曝光区域(CameraRegionOfInterest.Default());}}

使用以像素为单位的屏幕坐标作为触摸位置的替代,以提供曝光区域位置感兴趣的摄像头().
使用重置焦点区域感兴趣的摄像头区域。默认()或设置感兴趣的摄像头区域收件人:

Vuforia行为。实例。摄像头设备。SetExposureRegion(新的CameraRegionOfInterest(新的(屏幕宽度/2f,屏幕高度/2f),1.0f));

注意:在iOS上,只返回屏幕位置。iOS在内部更改此值时,范围将作为0返回。范围仍应设置在感兴趣的摄像头区域.

如果Vuforia引擎暂停,曝光区域将重置并恢复为其默认值。

使用get方法返回当前活动区域以进行自动曝光。

获取曝光区域();

闪光灯

照明条件差会严重影响目标检测和跟踪。为了获得最佳效果,请确保环境中有足够的灯光,以便场景细节和目标特征在摄影机视图中清晰可见。

  • 跟踪在室内环境中效果最好,因为室内的照明条件通常更稳定,也更容易控制。
  • 如果您的应用程序用例和场景需要在黑暗环境中运行,请考虑启用设备闪光灯(如果您的设备有闪光灯)。
Vuforia行为。实例。摄像头设备。SetFlash(真);

剪裁平面

如果放大效果在距离图像目标一定距离处消失,则可能需要调整远剪裁平面(在OpenGL或Unity相机设置中)。这尤其适用于从远处查看的大型图像目标。

在Unity中,可以直接在ARCamera GameObject的检查器窗口或使用Unity的脚本API。

将着色器应用于摄影机图像

Image类以字节数组的形式提供相机像素。这种方法对于某些图像处理任务很有用,但有时最好将图像作为Unity Texture2D获取,如下面的示例所示。也可以将图像应用于着色器中“材质”的纹理。

访问相机图像

使用Vuforia图像类访问和设置所需的相机图像格式。将图像用作OpenGL纹理或将纹理应用于Unity材质。使用注册所需的图像格式Vuforia.PixelFormat(Vuforia像素格式)宣言。

Vuforia行为。实例。摄像头设备。SetFrameFormat(PixelFormat.RGB888,true);

注释Vuforia命名空间参考页面列出了可用的像素格式。

初始化并启动Vuforia引擎后调用此方法;为此,建议注册一个OnVuforia已启动中的回调开始()您的方法单一行为脚本:

私有void OnVuforiaStarted(){PixelFormat PixelFormat=像素格式。RGB888;bool success=VuforiaBehaviour。实例。摄像头设备。SetFrameFormat(像素格式,true);//Vuforia已启动,现在注册相机图像格式if(成功){调试。日志(“成功注册像素格式”+pixelFormat.ToString());}其他的{调试。日志错误(“注册像素格式失败”+pixelFormat。ToString()+“您的设备可能不支持该格式;”+“考虑使用不同的像素格式。”);}}

我们可以扩展此脚本,以便在设置格式后和回调期间检索相机图像。这样,可以确保获得与当前帧匹配的最新相机图像。

此外,确保相机图像非空因为注册图像格式后,图像可能需要几帧才能可用。

注销当引擎处于已停止登记再一次当发动机处于起动再次。

将相机图像应用于原始图像游戏对象在你的Unity场景中.

  1. 创建一个清空游戏对象并附上以下脚本摄像头图像访问.
  2. 创建一个原始图像游戏对象用户界面->原始图像.
  3. 拖动原始图像游戏对象到公共领域摄像头图像访问脚本。
使用UnityEngine;使用UnityEngine。用户界面;使用Vuforia;使用Image=Vuforia.Image;公共类CameraImageAccess:MonoBehaviour{const PixelFormat PIXEL_FORMAT=像素格式。RGB888;const TextureFormat TEXTURE_FORMAT=纹理格式。RGB24;公共RawImage;纹理2D mTexture;bool mFormatRegistered;无效开始(){//注册Vuforia引擎生命周期回调:Vuforia应用程序。实例。OnVuforiaStarted+=OnVuforiaStarted;Vuforia应用程序。实例。OnVuforiaStopped+=OnVuforiaStopped;if(VuforiaBehaviour.Instance!=空)Vuforia行为。实例。世界。OnStateUpdated+=OnVuforiaUpdated;}销毁时无效(){//注销Vuforia引擎生命周期回调:if(VuforiaBehaviour.Instance!=空)Vuforia行为。实例。世界。OnStateUpdated-=OnVuforia已更新;Vuforia应用程序。实例。OnVuforiaStarted-=OnVuforiaStarted;Vuforia应用程序。实例。OnVuforiaStopped-=OnVuforiaStopped;if(VuforiaApplication.Instance.IsRunning){//如果Vuforia引擎仍在运行,请注销相机像素格式以避免不必要的开销//只能在Vuforia引擎运行时注册和注销格式注销格式();}if(mTexture!=空)销毁(mTexture);}//////每次启动Vuforia引擎时调用/// VuforiaStarted()上无效{mTexture=新纹理2D(0,0,TEXTURE_FORMAT,false);//如果Vuforia引擎未运行,则无法注册格式RegisterFormat();}/// ///每次Vuforia引擎停止时调用/// Vuforia停止时无效(){//OnVuforiaStopped后无法注销格式注销格式();if(mTexture!=空)销毁(mTexture);}/// ///每次更新Vuforia引擎状态时调用/// 无效OnVuforiaUpdate(){var image=VuforiaBehaviour。实例。摄像头设备。获取摄像头图像(PIXEL_FORMAT);//在摄像机图像可用之前,可能会有几帧的延迟if(图像.IsNullOrEmpty(图像))回报;调试。日志(“图像格式:”+image.PixelFormat+“\n图像大小:”+图像。宽度+“x”+图像。高度+“缓冲区大小:”+图像。缓冲区宽度+“x”+图像。缓冲区高度+“\nImage Stride:”+图像。步幅+“\n”);//通过将Y轴上翻转的摄影机图像复制到当前纹理中来覆盖当前纹理//调整纹理大小以匹配相机图像大小图像。CopyToTexture(mTexture,true);RawImage.texture=mTexture;RawImage.material.minTexture=mTexture;}/// ///注册相机像素格式/// 无效寄存器格式(){//Vuforia引擎已启动,现在注册摄像机图像格式var成功=VuforiaBehaviour。实例。摄像机设备。SetFrameFormat(PIXEL_FORMAT,true);if(成功){调试。日志(“成功注册像素格式”+pixel_format);mFormatRegistered=true;}其他的{调试。日志错误(“注册像素格式失败”+pixel_format+“您的设备可能不支持该格式;”+“考虑使用不同的像素格式。”);mFormatRegistered=false;}}/// ///取消注册相机像素格式/// void注销格式(){调试。日志(“取消注册相机像素格式”+pixel_format);Vuforia行为。实例。摄像头设备。SetFrameFormat(PIXEL_FORMAT,false);mFormatRegistered=false;}}

使用OpenGL纹理

其他图像处理任务可能需要以OpenGL纹理的形式获取图像。您可以使用OcclusionManagement示例中演示的方法将图像作为OpenGL纹理获取。

  1. 使用Vuforia渲染器。视频背景纹理美国石油学会
  2. 请参阅遮挡管理此技术示例的示例脚本。

访问原始像素

对于涉及CV(计算机视觉)的自定义进程,可以使用Image类从相机访问原始像素。请参阅以下检索像素大小的示例方法:

私有字节[]GetPixels(图像图像){var pixelBufferPtr=图像。PixelBufferPtr;int imageSize=图像。跨步*图像。高度;byte[]像素=新字节[imageSize];系统。运行时。互操作服务。元帅。复制(pixelBufferPtr,像素,0,imageSize);返回像素;}

了解更多信息

设备性能优化