使用ARCore深度API实现点云采集

一、深度API

本小节内容摘自ARCore官方文档。

ARCore 深度API

Depth API 可助力实现对象遮挡、提升沉浸感和新颖的互动体验,从而增强 AR 体验的真实感。

在下图中,右侧画面是采用深度API进行遮挡后的效果,与左侧图相比更加真实。

ARCore深度示例图

深度值

给定实测几何图形上的点 A 和代表深度图像中同一点的 2D 点 a,Depth API 在 a 处给出的值等于投影到主轴上的 CA 的长度。这也可称为 A 相对于相机原点 C 的 z 坐标。使用 Depth API 时,请务必注意,深度值不是光线 CA 本身的长度,而是光线的投影。

图

应用场景

启用遮挡
遮挡(即准确渲染虚拟物体在现实物体后面)对于沉浸式 AR 体验至关重要。假设有一个虚拟 Andy,用户可能需要放置在包含门边有后备箱的场景中。渲染时没有遮挡,Andy 会不切实际地与树干边缘重叠。如果您使用场景的深度来了解虚拟 Andy 相对于木箱等周围环境的距离,就可以准确地渲染 Andy 的遮挡效果,使其在周围环境中看起来更逼真。

ARCore文档截图

改变场景
您可以渲染虚拟雪花,让其坐在沙发的扶手和枕头上,或者在雾气弥漫的客厅中飘散,让用户进入身临其境的新世界。您可以使用“深度”创建虚拟光线互动、隐藏后方以及重新照亮真实物体的场景。

ARCore文档截图

距离和景深
需要显示距离较远的物体?您可以通过 Depth API 使用距离测量并添加景深效果,例如对场景的背景或前景进行模糊处理。

ARCore文档截图

支持用户与 AR 对象互动
让虚拟内容通过碰撞和物理与现实世界互动,让用户能够通过您的应用“触摸”世界。让虚拟物体绕过现实世界的障碍物,或让虚拟彩弹击中并泼洒到真实的树上。将基于深度的碰撞与游戏物理学相结合,可以打造栩栩如生的体验。

ARCore文档截图

改进点击测试
深度可用于改进点击测试结果。平面点击测试仅适用于具有纹理的平面表面,而深度点击测试则更加详细,甚至适用于非平面和低纹理区域。这是因为深度命中测试使用来自场景的深度信息来确定点的正确深度和方向。

在以下示例中,绿色 Andys 代表标准平面命中测试,红色 Andys 代表深度命中测试。

ARCore文档截图

ARCore文档截图

二、 AR Foundation

本小节记录如何在Unity中开发,通过 AR Foundation 使用“深度”功能。

配置安卓权限

这里需要配置安卓清单,以下方式二选一。

自定义AndroidManifest

在清单中添加<users-feature>其值设为“com.google.ar.core.depth>

配置Unity 项目

导航到 Edit > Project Settings > XR Plug-in Management > ARCore。
Depth 默认设置为 Required。修改为optional

启用深度

为节省资源,ARCore 默认情况下不会启用 Depth API。如需在支持的设备上充分利用深度,您必须通过 Camera 和 ARCameraBackground 组件手动将 AROcclusionManager 组件添加到 AR 相机游戏对象。如需了解详情,请参阅 Unity 文档中的自动遮盖。

在新的AR Session中,检查用户的设备是否支持深度,示例如下:

// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager = …// Check whether the user's device supports the Depth API.
if (occlusionManager.descriptor?.supportsEnvironmentDepthImage)
{// If depth mode is available on the user's device, perform// the steps you want here.
}

获取深度图像

从AROcclusionManager中获取环境的深度图

// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager = …if (occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image))
{using (image){// Use the texture.}
}

提取深度图的距离

如需将 Depth API 用于遮蔽虚拟对象或直观呈现深度数据之外的用途,请从深度图像中提取信息。

Texture2D _depthTexture;
short[] _depthArray;void UpdateEnvironmentDepthImage()
{if (_occlusionManager &&_occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image)){using (image){UpdateRawImage(ref _depthTexture, image, TextureFormat.R16);_depthWidth = image.width;_depthHeight = image.height;}}var byteBuffer = _depthTexture.GetRawTextureData();Buffer.BlockCopy(byteBuffer, 0, _depthArray, 0, byteBuffer.Length);
}// Obtain the depth value in meters at a normalized screen point.
public static float GetDepthFromUV(Vector2 uv, short[] depthArray)
{int depthX = (int)(uv.x * (DepthWidth - 1));int depthY = (int)(uv.y * (DepthHeight - 1));return GetDepthFromXY(depthX, depthY, depthArray);
}// Obtain the depth value in meters at the specified x, y location.
public static float GetDepthFromXY(int x, int y, short[] depthArray)
{if (!Initialized){return InvalidDepthValue;}if (x >= DepthWidth || x < 0 || y >= DepthHeight || y < 0){return InvalidDepthValue;}var depthIndex = (y * DepthWidth) + x;var depthInShort = depthArray[depthIndex];var depthInMeters = depthInShort * MillimeterToMeter;return depthInMeters;
}

三、示例Demo

这里记录当前ARFoundation关于深度API使用点云的示例Demo。不同的是,这里新增的“点云采集”和“点云导入”功能。

官方示例:arcore-depth-lab

版本信息

        "com.unity.xr.arfoundation": "4.1.5","com.unity.xr.arcore": "4.1.5","com.unity.xr.arkit": "4.1.5"

相机配置

在“AR Session Origin”->“AR Camera"中添加"AROcclusion Manager组件”

组件

此外在示例demo中,这里挂载了"DepthSource"脚本。(这个脚本一个场景只可有且仅有一个激活)
这个脚本主要作用是处理深度图纹理。

点云采集

示例场景

Demo场景路径:Assests/ARRealismDemos/PointCloud/Scenes/RawPointClouds.unity

点云渲染

场景中找到“RawPointCloudBlender”游戏对象,其挂载的组件如下图:

组件

"PointCloudMaterial"是ARCore示例提供的渲染点云的材质(这个后续会用到)。

“RawPointCloudBlender”是渲染点云的核心脚本,它会在MeshFilter上生成Mesh。

点云保存

在运行时,点云实时渲染的Mesh在“RawPointCloudBlender”->MeshFilter上。

因此这里可直接获取Mesh的顶点数据进行保存。

保存为PTS

   public void SaveMeshToFile(string filePath){if (meshFilter == null || meshFilter.sharedMesh == null){Debug.LogWarning("MeshFilter or Mesh not assigned.");return;}Mesh mesh = meshFilter.sharedMesh;// 获取网格数据Vector3[] vertices = mesh.vertices;//int[] triangles = mesh.triangles;//点云无需三角顶点索引,Color[] colors = mesh.colors;int minCount = Math.Min(vertices.Length, colors.Length);// 创建保存网格数据的文件using (StreamWriter writer = new StreamWriter(filePath)){// 写入顶点数据for (int i = 0; i < minCount; i++){//PTS格式前三个是 (x,y,z) 坐标 其中,第四个是“强度”值,最后三个是“颜色值”(R,G,B) Vector3 vertex = vertices[i];Color c = colors[i];//这里暂用ALPHA表示强度值writer.WriteLine(vertex.x + " " + vertex.y + " " + vertex.z+ " " + (int)(c.a * 255) + " " + (int)(c.r * 255) + " " + (int)(c.g * 255) + " " + (int)(c.b * 255));}}}

保存为OBJ

将上述循环中替换为如下内容:

        // 创建保存网格数据的文件using (StreamWriter writer = new StreamWriter(filePath)){// 写入顶点数据foreach (Vector3 vertex in vertices){writer.WriteLine("v " + vertex.x + " " + vertex.y + " " + vertex.z);}//...}

点云加载

扩展编辑器

编写脚本,新增点云数据导入功能

public class PTSLoaderEditor : EditorWindow
{private string ptsFilePath;private Material material;[MenuItem("EQ/点云数据/\"加载 *.pts\"")]public static void ShowWindow(){EditorWindow.GetWindow(typeof(PTSLoaderEditor));}private void OnGUI(){//...LoadPointCloud(string filePath);//...}private void LoadPointCloud(string filePath){//...// 创建点云 MeshMesh pointCloudMesh = new Mesh();for (int i = 0; i < count; i++){string[] parts = lines[i].Split(' ');if (parts.Length >= 7){float x = float.Parse(parts[0]);float y = float.Parse(parts[1]);float z = float.Parse(parts[2]);_vertices[i] = new Vector3(x, y, z);byte a = byte.Parse(parts[3]);byte r = byte.Parse(parts[4]);byte g = byte.Parse(parts[5]);byte b = byte.Parse(parts[6]);_colors[i] = new Color32(r, g, b, a);_indices[i] = i;}}#if UNITY_2019_3_OR_NEWERpointCloudMesh.SetVertices(_vertices, 0, count);pointCloudMesh.SetIndices(_indices, 0, count, MeshTopology.Points, 0);pointCloudMesh.SetColors(_colors, 0, count);
#else// Note that we recommend using Unity 2019.3 or above to compile this scene.List<Vector3> vertexList = new List<Vector3>();List<Color32> colorList = new List<Color32>();List<int> indexList = new List<int>();for (int i = 0; i < count; ++i){vertexList.Add(_vertices[i]);indexList.Add(_indices[i]);colorList.Add(_colors[i]);}pointCloudMesh.SetVertices(vertexList);pointCloudMesh.SetIndices(indexList.ToArray(), MeshTopology.Points, 0);pointCloudMesh.SetColors(colorList);
#endif // UNITY_2019_3_OR_NEWER//...}
}

查看点云

导入点云

在编辑器中操作如下:

“EQ/点云数据/“加载 *.pts””

查看点云

查看点云

注:这里使用点云材质,可以给点赋予之前传入的颜色值

查看点云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/294127.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node.js的模块化 与 CommonJS规范

一、node.js的模块化 (1)什么是模块化&#xff1f; 将一个复杂的程序文件依据一定的规则拆分成为多个文件的过程就是模块化 在node.js中&#xff0c;模块化是指把一个大文件拆分成独立并且相互依赖的多个小模块&#xff0c;将每个js文件被认为单独的一个模块&#xff1b;模块…

第十七章 Kafka

一、特性 - 高吞吐、低延迟 - 高伸缩性 - 持久性、可靠性 - 容错性 - 高并发 通过 O(1)的磁盘数据结构提供消息的持久化&#xff0c;这种结构对于即使数以 TB 的消息存储也能够保持长时间的稳定性能。 高吞吐量&#xff1a;即使是非常普通的硬件 Kafka 也可以支持每秒数百…

深入理解数据结构——堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…

Image-Adaptive YOLO for Object Detection in Adverse Weather Conditions(IA-YOLO)

1、总体概述 基于深度学习的目标检测在常规条件的数据集可以获得不错的结果&#xff0c;但是在环境、场景、天气、照度、雾霾等自然条件的综合干扰下&#xff0c;深度学习模型的适应程度变低&#xff0c;检测结果也随之下降&#xff0c;因此研究在复杂气象条件下的目标检测方法…

【软件工程导论】——面向对象与UML(学习笔记)

&#x1f4d6; 前言&#xff1a;面向对象是以问题空间中出现的物体为中心进行模型化的一种技术。建立模型是软件工程中最常使用的技术之一。无论软件分析或软件设计&#xff0c;都需要建立模型。UML 就是OO 软件工程使用的统一建模语言。它是一种图形化的语言&#xff0c;主要用…

vue3中播放flv流视频,以及组件封装超全

实现以上功能的播放&#xff0c;只需要传入一个流的地址即可&#xff0c;当然组件也只有简单的实时播放功能 下面直接上组件 里面的flvjs通过npm i flv.js直接下载 <template><div class"player" style"position: relative;"><p style&…

linux:生产者消费者模型

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、生产者消费者模型二、基于阻塞队列的生产者消费者模型代码实现 总结 前言 本文是对于生产者消费者模型的知识总结 一、生产者消费者模型 生产者消费者模型就是…

Mac电脑Jmeter集成到Jenkins,压测多个接口并生成测试报告

Jenkins支持的JDK版本17、21&#xff0c;通过java -version查看当前JDK版本&#xff0c;确认是否匹配 打开网址https://www.jenkins.io/download 点击下载&#xff0c;选择mac版本 commend空格打开终端&#xff0c;输入安装命令brew install jenkins 安装完成后输入brew servi…

2021-08-06

yarn的简介&#xff1a; Yarn是facebook发布的一款取代npm的包管理工具。 yarn的特点&#xff1a; 速度超快。 Yarn 缓存了每个下载过的包&#xff0c;所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率&#xff0c;因此安装速度更快。超级安全。 在执行代码…

AI绘图cuda与stable diffusion安装部署始末与避坑

stable diffusion的安装说起来很讽刺&#xff0c;最难的不是stable diffusion&#xff0c;而是下载安装cuda。下来我就来分享一下我的安装过程&#xff0c;失败了好几次&#xff0c;几近放弃。 一、安装cuda 我们都知道cuda是显卡CPU工作的驱动&#xff08;或者安装官网的解释…

Stable Diffusion WebUI 附加功能/图片放大(Extras):单张图片/批量处理/从目录进行批量处理

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 篇文章主要讲解 Stable Diffusion WebUI 的附加功能/图片放大&#xff08;Extras&#xff09;的使用&#xff0c;主要…

计算机网络——33多点访问协议

多点访问协议 多路访问链路和协议 两种类型的链路&#xff08;一个子网内部链路连接形式&#xff09; 点对点 拨号访问的PPP以太网交换机和主机之间的点对点链路 广播 传统以太网HFC上行链路802.11无线局域网 多路访问协议 单个共享的广播型链路 2个过更多结点同时传送&am…

数据结构——二叉树——二叉搜索树(Binary Search Tree, BST)

目录 一、98. 验证二叉搜索树 二、96. 不同的二叉搜索树 三、538. 把二叉搜索树转换为累加树 二叉搜索树&#xff1a;对于二叉搜索树中的每个结点&#xff0c;其左子结点的值小于该结点的值&#xff0c;而右子结点的值大于该结点的值 一、98. 验证二叉搜索树 给你一个二叉树的…

uni app 扫雷

闲来无聊。做个扫雷玩玩吧&#xff0c;点击打开&#xff0c;长按标记&#xff0c;标记的点击两次或长按取消标记。所有打开结束 <template><view class"page_main"><view class"add_button" style"width: 100vw; margin-bottom: 20r…

深入了解 Vue 3 中的 Transition 过渡动画

在本文中&#xff0c;我们将深入探讨 Vue 3 中实现 Transition 过渡动画的技术细节。过渡动画可以为用户界面增添平滑和生动的效果&#xff0c;提升用户体验。 首先新建一个基于uni-app框架为transition.vue的测试文件&#xff0c;在其中编写如下JavaScript、HTML和CSS代码&…

CSS3 Transform变形理解与应用

Transform&#xff1a;对元素进行变形&#xff1b; Transition&#xff1a;对元素某个属性或多个属性的变化&#xff0c;进行控制&#xff08;时间等&#xff09;&#xff0c;类似flash的补间动画。但只有两个关键贞。开始&#xff0c;结束。 Animation&#xff1a;对元素某个属…

vulhub中Apache solr XML 实体注入漏洞复现(CVE-2017-12629)

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发&#xff0c;主要基于 HTTP 和 Apache Lucene 实现。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个XML/JSON响应来实现。此次7.1.0之前版本总共爆出两个漏洞&#xff1a;XML…

智慧安防监控EasyCVR视频调阅和设备录像回看无法自动播放的原因排查与解决

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

云计算迎变局:阿里云、腾讯云“各有千秋”

毋庸置疑&#xff0c;无论在什么时候什么行业&#xff0c;低价策略都是一柄利器。比如&#xff0c;在电商行业&#xff0c;除了拼多多将低价策略贯彻到底之外&#xff0c;淘宝、京东也将性价比作为发力重点&#xff0c;并通过补贴、秒杀等方式&#xff0c;再度强调自身的“价格…

目标检测——工业安全生产环境违规使用手机的识别

一、重要性及意义 首先&#xff0c;工业安全生产环境涉及到许多复杂的工艺和设备&#xff0c;这些设备和工艺往往需要高精度的操作和严格的监管。如果员工在生产过程中违规使用手机&#xff0c;不仅可能分散其注意力&#xff0c;降低工作效率&#xff0c;更可能因操作失误导致…