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

【ARFoundation学习笔记】平面检测

在这里插入图片描述


写在前面的话

本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏,更多详细内容请阅读原文。


文章目录

  • 平面检测属性
    • 可视化平面
    • 平面检测的开关控制
      • 显示与隐藏已检测平面


平面检测属性

AR中检测平面的原理:AR Foundation对摄像机获取的图像进行分析处理,分离图像中的特征点(这些特征点往往是图像中明暗、强弱、颜色变化较大的点);利用VIO和IMU跟踪这些特征点的三维空间信息;在跟踪过程中,对特征点信息进行处理,并尝试用空间中位置相近或者符合一定规律的特征点构建平面,如果成功就是检测出了平面。平面有位置、方向和边界信息,AR Plane Manager负责检测平面以及管理这些检测出来的平面,但它并不负责渲染平面。

在AR Plane Manager中,我们可以设置平面检测的方式,如水平平面(Horizontal)、垂直平面(Vertical)、水平平面&垂直平面(Everything)或者不检测平面(Nothing),检测平面也是一个消耗性能的工作,而根据应用需要选择合适的检测方式可以优化应用性能。

平面本身是一个Trackable对象,因此在AR Session Origin上检测到的时候,AR Plane Manager会实例化一个平面Prefab并挂载AR Plane组件。


可视化平面

在这里插入图片描述

AR Plane Manager只负责平面的检测,并不负责平面的渲染。平面渲染通常在检测构建的Prefab上执行,预制体上的脚本如上所示:

红框中的顶点偏差阈值表示只有偏差值在阈值范围内的特征点才被归为同一平面,因此阈值越小检测越精确。AR Plane Mesh Visualizer组件主要是从边界特征点与其他特征点三角化生成一个平面网格,而这个网格由Mesh Renderer进行渲染。默认平面预制体还有一个Line Renderer用于渲染边缘。

书中示例了自定义Shader和渲染脚本以实现定制化的平面渲染。


平面检测的开关控制

15public void TogglePlaneDetection()
16{
17.       m_ARPlaneManager.enabled = !m_ARPlaneManager.enabled;
18string planeDetectionMessage = "";
19if (m_ARPlaneManager.enabled)
20{
21.          planeDetectionMessage = "禁用平面检测";
22SetAllPlanesActive(true);
23}
24else
25{
26.          planeDetectionMessage = "启用平面检测";
27SetAllPlanesActive(false);
28}34void SetAllPlanesActive(bool value)
35{
36foreach (var plane in m_ARPlaneManager.trackables)
37.          plane.gameObject.SetActive(value);
38}

对书内的代码进行了小小的裁剪。对于平面而言,我们可以通过设置平面物体的Active状态来控制平面的显示。还记得我们说平面是受Manager自动管理的,因此如果我们手动销毁平面可能会引发异常。

显示与隐藏已检测平面

直接关闭平面检测的话,那么程序后续也不会再检测新的平面。有时我们想要隐藏已检测平面的同时保留平面检测功能,以便在显示平面检测时直接显示那些新检测的平面,而不是重新开始检测。

1using System.Collections;
2using System.Collections.Generic;
3using UnityEngine;
4using UnityEngine.XR.ARFoundation;
5using UnityEngine.UI;
67public class PlaneDisplay : MonoBehaviour
8{
9public Text m_TogglePlaneDetectionText;
10private ARPlaneManager m_ARPlaneManager;
11private bool isShow = true;
12private List<ARPlane> mPlanes;
13void Start()
14{
15.       m_ARPlaneManager = GetComponent<ARPlaneManager>();
16.       mPlanes = new List<ARPlane>();
17.       m_ARPlaneManager.planesChanged += OnPlaneChanged;
18}
19void OnDisable()
20{
21.       m_ARPlaneManager.planesChanged -= OnPlaneChanged;
22}
23.    #region 显示与隐藏检测的平面
24public void TogglePlaneDisplay()
25{
26string planeDisplayMessage = "";
27if (isShow)
28{
29.          planeDisplayMessage = "隐藏平面";
30}
31else
32{
33.          planeDisplayMessage = "显示平面";
34}
35for (int i = mPlanes.Count - 1; i >= 0; i--)
36{
37if (mPlanes[i] == null || mPlanes[i].gameObject == null)
38.             mPlanes.Remove(mPlanes[i]);
39else
40.             mPlanes[i].gameObject.SetActive(isShow);
41}
42if (m_TogglePlaneDetectionText != null)
43.          m_TogglePlaneDetectionText.text = planeDisplayMessage;
4445.       isShow = !isShow;
46}
4748private void OnPlaneChanged(ARPlanesChangedEventArgs arg)
49{
50for (int i = 0; i < arg.added.Count; i++)
51{
52.          mPlanes.Add(arg.added[i]);
53.          arg.added[i].gameObject.SetActive(isShow);
54}
55}
56.    #endregion
57}

上述代码实现了在不关闭平面检测时隐藏已检测平面的功能。原理就是对平面变化的委托添加一个OnPlaneChanged的处理事件,并从附带的事件参数中获取检测到的平面信息,保存在一个私有的List<ARPlane>中。由于PanelManager中对平面的检测由Manager进行自动管理,因此附带参数Args会产生变化,例如增加新的面,更新已有的面,删除过期的面。

所以我们切换平面检测状态的时候,还需要检测参数Args回传的面是否依旧存在,若不存在,则应当移除。否则切换已经过期的面的状态会引发异常。

37if (mPlanes[i] == null || mPlanes[i].gameObject == null)
38.             mPlanes.Remove(mPlanes[i]);

事件注册与撤销一定是成双成对的,上述代码在Start()方法中进行了注册,在OnDisable()方法中撤消了注册,如果事件没有在适当的时机撤销会引发难已排查的错误。

在这里插入图片描述

相关文章:

【ARFoundation学习笔记】平面检测

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 文章目录 平面检测属性可视化平面平面检测的开关控制显示与隐藏已检测平面 平面检测属性 AR中检测平面的原理&#xff1a;AR Fou…...

Python---ljust()--左对齐、rjust()--右对齐、center()--居中对齐

作用&#xff1a;返回原字符串左对齐、右对齐以及居中对齐&#xff0c;不足的使用 指定字符 进行填充。 ljust 左对齐 rjust 右对齐 center 居中对齐 类似于Excel、Word文档中的对齐。 基本语法&#xff1a; 字符串序列.ljust(长度, 填充字符) 案例&#xff1a; …...

spdk用户态块层详解

先通过回顾内核态的通用块层来详细介绍SPDK通用块层&#xff0c;包括通用块层的架构、核心数据结构、数据流方面的考量等。最后描述基于通用块层之上的两个特性&#xff1a;一是逻辑卷的支持&#xff0c;基于通用块设备的Blobstore和各种逻辑卷的特性&#xff0c;精简配置&…...

双通道 H 桥电机驱动芯片AT8833,软硬件兼容替代DRV8833,应用玩具、打印机等应用

上期小编给大家分享了单通道 H 桥电机驱动芯片&#xff0c;现在来讲一讲双通道的驱动芯片。 双通道 H 桥电机驱动芯片能通过控制电机的正反转、速度和停止等功能&#xff0c;实现对电机的精确控制。下面介绍双通道H桥电机驱动芯片的工作原理和特点。 一、工作原理 双通道 H 桥电…...

WPF布局与控件分类

Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) https://www.zhihu.com/column/c_1397867519101755392 https://blog.csdn.net/qq_44034384/article/details/106154954 https://www.cnblogs.com/mq0…...

复杂逻辑的开发利器—Mendix快速实现AQL质量抽检

Mendix低代码开发平台适用于复杂的业务逻辑场景&#xff0c;这句话大家早有耳闻&#xff0c;本期小编就为您打开智慧之光&#xff0c;仅从AQL小侧面&#xff0c;来管窥一二——Mendix如何形成第五代编程语言&#xff0c;来完成数据逻辑与建模、业务算法逻辑与建模的。&#xff…...

RFID系统

目录 在物联网应用中有三项关键技术 读写器 电子标签 工作原理 阅读器的组成及作用&#xff1a; 电子标签的组成及作用&#xff1a; RFID系统的组成 接口方式 在物联网应用中有三项关键技术 在物联网应用中有三项关键技术 1、传感器技术&#xff1a;这也是计算机应用中…...

Markov Chain Fingerprinting to Classify Encrypted Traffic 论文笔记

0.Abstract 在本文中&#xff0c;提出了用于SSL/TLS会话中传输的应用程序流量的随机指纹。这个指纹基于一阶齐次马尔可夫链&#xff0c;模型识别应用程序的准确率&#xff0c;并提供了检测异常对话的可能性。 1.Introduction 通过SSL/TLS会话时的头部信息创建统计指纹&#xff…...

vue 跨标签页的数据共享(即跨标签页通信)

跨标签页通信的常见方案 LocalStorage 或 SessionStorage BroadCast Channel Service Worker Shared Worker Window.postMessage() Cookies IndexedDB 什么是跨标签页通信&#xff1f; 指在同一个浏览器窗口中的多个标签页之间进行数据交流和信息传递的过程。通常情况…...

什么是拉宾-斯科特定理?

拉宾-斯科特定理(Rabin-Scott theorem )是数学上最深刻的数学结果之一。拉宾-斯科特定理是人们最喜欢的计算机科学概念之一。 当正确理解拉宾-斯科特定理时&#xff0c;它会以一种相当基本的方式改变你对现实的看法。然而&#xff0c;它典型的教科书式的呈现方式掩盖了这种深…...

Java并发编程第11讲——AQS设计思想及核心源码分析

Java并发包&#xff08;JUC&#xff09;中提供了很多并发工具&#xff0c;比如前面介绍过的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore、FutureTask等锁或者同步部件&#xff0c;它们的实现都用到了一个共同的基类——AbstractQueuedSynchronizer&…...

什么是数据库?数据库有哪些基本分类和主要特点?

数据库是以某种有组织的方式存储的数据集合。本文从数据库的基本概念出发&#xff0c;详细解读了数据库的主要类别和基本特点&#xff0c;并就大模型时代备受瞩目的数据库类型——向量数据库进行了深度剖析&#xff0c;供大家在了解数据库领域的基本概念时起到一点参考作用。 …...

flutter显示出底部控件的引导页

需求&#xff1a;同一个页面的两个不同的入口&#xff0c;同一个控件的位置有变化&#xff0c;显示引导页时对应这个控件的引导内容的位置也需要改变&#xff1b;同时半透明底部显示出真实的页面内容。 这样的需要如果切图然后再往页面上贴位置无法精确的对准。 思路&#xff1…...

常用设计模式——模板方法模式

什么是模板方法模式 模板方法模式&#xff1a;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 主要解决&#xff1a;一些方法通用&#xff0c;却要在每一个子类都重写这些方法…...

idea使用git删除本地提交(未推送)

1、找到reset head 2、打开弹窗&#xff0c;在HEAD后面输入^ 结果为HEAD^ 注释&#xff1a; Reset Type 有三种&#xff1a; Mixed&#xff08;默认方式&#xff09;&#xff0c;保留本地源码&#xff0c;回退 commit 和 index 信息&#xff0c;最常用的方式Soft 回退到某个版本…...

centos 7部署Mysql8.0主从

Mysql官网中关于部署主从的网址 环境准备&#xff1a; 搭建虚拟机和安装Mysql之前的文章中已经涉及&#xff0c;在此不再赘述。 主从IPMysql账号密码主192.168.213.4root/Root1234!从192.168.213.5root/Root1234! 1、主数据库设置 配置my.cnf 一般存放于/etc/。 主从配…...

asp.net docker-compose添加es search

打开docker-compose.yml添加 es-search:image: docker.elastic.co/elasticsearch/elasticsearch:7.17.14 打开docker-compose.override.yml添加 es-search:volumes:- data01:/usr/share/elasticsearch/dataports:- 9200:9200 docker集群中添加es search成功...

工业路由器网关的网络协议之NAT技术

在物联网通讯领域&#xff0c;NAT技术能将内网的一个私有IP转换成一个公网IP去接入互联网&#xff0c;解决组建局域网络时私有IP地址无法在公网上进行路由的问题。 NAT&#xff08;Network Address Translation&#xff09;的三种方式&#xff1a; 静态NAT 1、一个私有IP对应…...

【亲测可用】SpringBoot使用Redis的Lettuce连接池报RedisCommandTimeoutException

目录 一、问题详情 二、根本原因 三、解决方案 一、问题详情 在最近新项目的开发当中,当项目刚启动的时候访问Redis服务一切正常,但是过了几分钟后再次访问Redis就报如下错误。 Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutExcept…...

When Urban Region Profiling Meets Large Language Models

本文是LLM系列文章&#xff0c;针对《When Urban Region Profiling Meets Large Language Models》的翻译。 当城市区域轮廓遇到大型语言模型时 摘要1 引言2 前言3 方法4 实验5 结论与未来工作 摘要 基于网络数据的城市区域概况对城市规划和可持续发展至关重要。我们见证了LL…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...