当前位置: 首页 > article >正文

基于 Quest 摄像头数据开发的原理介绍【Unity Meta Quest MR 开发教程】

XR 开发者社区:https://www.spatialxr.tech/

Meta 官方开发者文档的部分:https://developers.meta.com/horizon/documentation/unity/unity-pca-overview

样例工程:

https://github.com/oculus-samples/Unity-PassthroughCameraApiSamples?tab=readme-ov-file​

https://github.com/xrdevrob/QuestCameraKit/tree/main?tab=readme-ov-file

Quest 的相机访问功能是在安卓的 Camera2 之上构建的。即使 Quest 实际上是一个 Android 系统,在之前我们也不能获取到 Quest 的摄像头数据,因为当时 Meta 关闭了 Quest 摄像头权限。而在 Quest v74 版本开始,相机访问功能已重新启用。

在 Unity 中,几乎没有人直接使用 Camera2 类,因为它需要与 JNI 调用混合使用。

Android JNI(Java Native Interface)是一个用于在 Java 代码与本地代码(通常是C或C++)之间进行交互的接口。JNI 允许 Java 程序调用本地代码中的方法,并且可以通过本地代码访问 Java 虚拟机(JVM)中的对象和方法。这种机制主要用于 Android 应用中需要高性能或者需要访问设备底层功能时,开发者可以通过JNI来调用系统底层的C或C++代码。

是不是看起来比较复杂?不过不要担心,Unity 已经帮我们封装好了一些功能,我们 Unity 开发者通常会使用 WebCamTexture 类。Unity 的 WebCamTexture 是一个用于访问设备摄像头并将摄像头捕捉到的图像数据输出到纹理(Texture)的类。它可以用来实时获取摄像头图像并显示在游戏中的物体上。在 Quest 中,可以获取设备左边或右边的前置摄像头帧的 WebCamTexture,然后在底层,WebCamTexture 将查询 Camera2,将摄像头拍摄到的画面输出到 WebCamTexture 上。

后续我们就是基于 WebCamTexture 来进行摄像头功能的开发。Quest 能给到我们的是摄像头拍摄的原始画面(不包含 MR 应用中的虚拟物体),可以理解为捕捉到的每一帧是一个 2D 的照片(不包含真实世界的三维信息)。至于怎么处理这些照片上的画面就需要看我们自己的需求了,比如说把画面发送给 AI,让 AI 分析画面内容,进行一些物体识别的操作。

因此我们在基于摄像头数据开发功能时,主要就是处理两个方面的内容:

  1. 如何处理摄像头拍摄的画面。比如要进行图像识别、物体识别,一般会使用第三方的 SDK 或者识别算法,把 WebCamTexture 喂给 AI 处理。

  2. 将 2D 的屏幕坐标转化成 3D 的世界坐标。比如想在识别到的现实物体上叠加虚拟物体,需要知道这个现实物体在 Unity 的世界坐标下的哪个位置,是带有 x,y,z 三个轴的数据的。而 WebCamTexture 捕捉到的图像只是个 2D 的平面,没有三维世界的深度信息,我们通过物体识别算法识别到的物体坐标只是在这个 2D 平面上的一个屏幕坐标,可以理解为 Quest 拍摄了一张照片,我们识别到这张照片上的某个像素点为需要识别的现实物体的中心。但如果要在现实物体上叠加 3D 虚拟物体,我们要把识别到的这个像素点的 2D 屏幕坐标转换成 Unity 中的 3D 世界坐标,让程序知道这个现实物体具体在 Unity 世界中的哪个位置。不过好在 Meta 的 Passthrough Camera API 中已经提供了将 2D 屏幕坐标转换成 3D 世界坐标的方法,在后续的课程中,我们也会详细介绍

在这里插入图片描述

需要注意的是,将数据从 GPU(WebCamTexture 输出的画面)移动到 CPU(我们读取并处理相机像素数据的地方)是一项比较耗费性能的操作,所以尽量不要对摄像头拍摄的每一帧画面都进行分析处理,比如可以每隔几帧处理一次。


http://www.kler.cn/a/592438.html

相关文章:

  • 微前端 qiankun vite vue3
  • 使用码云搭建CocoaPods远程私有库
  • 人事档案管理系统基于Spring BootSSM
  • LS-NET-006-思科MDS 9148S 查看内存
  • 【微服务】基于Lambda ESM的预留模式调整Kafka ESM吞吐量的实战
  • Spring Boot集成MyBatis与MySQL
  • Swagger-告别手写文档
  • 第十五届蓝桥杯C/C++组:宝石组合题目(从小学奥数到编程题详解)
  • 【嵌入式Linux】基于ArmLinux的智能垃圾分类系统项目
  • 构建高效复杂系统的关键:架构与模块详解
  • 【Java】Mybatis学习笔记
  • k8s常用知识点总结
  • Matlab 汽车振动多自由度非线性悬挂系统和参数研究
  • USB(Universal Serial Bus)详解
  • ETL中的实用功能以及数据集成方式
  • 基于Spring Boot的流浪动物救助平台的设计与实现(LW+源码+讲解)
  • Vmware中的centos7连接上网
  • ==和equals的区别?
  • VLLM专题(三十六)—自动前缀缓存
  • Java 中的引导类加载器(Bootstrap ClassLoader) 详解