【ARFoundation自学04】AR Tracked Image 图像追踪识别

图像识别是很常用的AR功能!AR foundation 可以帮助我们轻松实现!

1.安装插件

首先还是在资源包中导入ARfoundation 。然后搭建基本的AR ARFoundation框架!

2.创建AR session 和XR origin结构!

3.然后在XR Origin 物体身上添加AR Tracker Image Manager组件!

这个组件主要负责实现目标图像的识别和追踪! 但是我们需要思考,识别那个图片,识别后让谁追踪图片!他的主要原理是,创建一个图像库Library(Serialized Library),把要被识别的图都放进去,将来所有在库里面的图都可以被单独识别!

然后,识别图片后,为了让我们能够看到追踪图片的视觉效果,AR Tracker Image Manager会为识别后的图像克隆一份Tracked Image Prefab 用于跟随识别到的图像一起运动(移动或者旋转)!如何创建一个Tracked Image Prefab ,我们后面再讲!

4.创建图像识别库

这个图像库,需要用户安装插件后,在Assets 仓库面板空白点右键-Create-XR-Reference Image Library ,然后点击创建的图像库,在右侧属性面板添加将来要被识别的图!

这些图将来都会可识别!

5.创建识别后追踪的预制体(UI、模型等)Tracked Image Prefab  

这个预制体是图像识别专用的,因此需要挂载AR Tracked Image 组件!任何物体挂在了这个组件都可以作为识别图像后的追踪预制体!

那么我们自己的模型放在那里才可以追踪图片呢?只需要放在搭载AR Tracked Image 组件的父物体下面即可!

例如创建一个空物体,挂载AR Tracked Image 组件。把我们的模型放在这个空物体的子物体下面即可!

6. 把创建好可识别图像库以及追踪预制体赋值给 AR Tracker Image Manager组件!完毕

最后 AR Tracker Image Manager组件!还有个属性Max Number Of Moving Image 是最大可跟踪的动态图像数量!

7.其他参数介绍

图像跟踪技术,是指通过图像处理技术对摄像头中拍摄到的2D图像进行定位,并对其姿态进行跟踪的技术。图像跟踪技术的基础是图像识别,图像识别是指识别和检测出数字图像或视频中对象或特征的技术,图像识别技术是信息时代的一门重要技术,其产生目的是为了让计算机代替人类去处理大量的图形图像及真实物体信息,因而成为其他许多重要技术的基

  1. 最大并发跟踪数(Max Simultaneous Tracked Images):

    指定同时能够被识别和跟踪的图像数量。由于图像跟踪较为耗能,限制此数值可以避免性能问题。

    2. 参考图像(Reference Image)    

  • 这些是您希望AR应用能够识别的特定2D图像。比如,一张海报或标志。您需要事先在Unity项目中定义这些图像作为资源。别2D图像的过程实际是一个特征值对比的过程,ARFoundation将从摄像头中获取的图像信息与参考图像库的图像特征点信息进行对比,存储在参考图像库中的用于对比的图像就叫做参考图像。一旦对比成功,真实环境中的图像将与参考图像库的参考图像建立对应关系,每一个真实2D图像的姿态信息也一并被检测。

      3.参考图像库(Reference Image Library)    :

参考图像库用来存储一系列的参考图像用于对比,每一个图像跟踪程序都必须有一个参考图像库,但需要注意的是,参考图像库中存储的实际是参考图像的特征值信息而不是原始图像,这有助于提高对比速度与鲁棒性。参考图像库越大,图像对比就会越慢,建议参考图像库的图像不要超过1000张。跟踪组件提供方(Provider)    ARFoundation是架构在底层SDK图像跟踪API之上的,也即是说ARFoundation并不具体负责图像识别过程的算法,它只提供一个接口,具体图像识别由算法提供方提供。

8.动态修改TrackedImageManager的状态

  • 在代码中,你可以访问TrackedImageManager实例并根据需要动态改变其行为。例如,你可以暂时禁用所有图像的跟踪,或者针对特定图像进行开关控制
    public class ImageTrackingController : MonoBehaviour
    {
        public TrackedImageManager trackedImageManager;
        
        public void DisableImageTracking()
        {
            if (trackedImageManager != null)
            {
                trackedImageManager.enabled = false; // 关闭图像跟踪
            }
        }
    
        public void EnableImageTracking()
        {
            if (trackedImageManager != null)
            {
                trackedImageManager.enabled = true; // 启用图像跟踪
            }
        }
    }

    8.多图像跟踪

对于多图像跟踪,你可能不只希望实例化一个Prefab,而是根据识别到的不同图像实例化不同的Prefab。这时,传统的方式是为每个图像在数据集中指定对应的Prefab。但ARFoundation本身并不直接支持每个图像直接关联不同Prefab,因此需要一些额外的编程逻辑来实现这一功能。

实现逻辑

编写自定义脚本

创建一个C#脚本,用于处理图像识别后的逻辑。在这个脚本中,你需要监听TrackedImageUpdated事件,该事件会在图像被识别或跟踪状态改变时触发。

using UnityEngine; // 引入Unity引擎的基本功能
using UnityEngine.XR.ARFoundation; // 引入ARFoundation相关的功能
using UnityEngine.XR.ARSubsystems; // 引入AR子系统功能,用于更底层的AR操作

public class MultiImageTracking : MonoBehaviour // 创建一个可挂在Unity对象上的自定义脚本组件
{
    // 创建一个字典来存储每个图像ID(TrackableId)与应实例化的预制体(Prefab)之间的对应关系
    public Dictionary<TrackableId, GameObject> prefabMap; 

    // 声明一个变量来引用ARTrackedImageManager组件,稍后我们将用它来监听图像跟踪的变化
    private ARTrackedImageManager m_TrackedImageManager;

    // 当游戏开始运行时执行的函数
    void Start()
    {
        // 获取当前游戏对象上的ARTrackedImageManager组件
        m_TrackedImageManager = GetComponent<ARTrackedImageManager>();

        // 注册一个事件监听器,当跟踪的图像发生变化时(增加、更新或移除),会调用OnTrackedImagesChanged方法
        m_TrackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
    }

    // 当跟踪的图像集合发生变化时,这个方法会被调用
    void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        // 遍历所有新添加的跟踪图像
        foreach (var trackedImage in eventArgs.added)
        {
            // 检查我们是否为这个图像ID设置了特定的Prefab
            if (prefabMap.ContainsKey(trackedImage.trackableId))
            {
                // 如果设置了,就在这个图像的位置实例化对应的Prefab
                Instantiate(prefabMap[trackedImage.trackableId], trackedImage.transform);

                // 注意:这里的`Instantiate`意味着每当图像首次被识别时,都会创建一个新的虚拟对象实例。
                // 若要控制对象的生命周期(如避免重复创建),你可能需要添加额外的逻辑来检查对象是否已存在。
            }
        }

        // 这里还可以添加对updated(已存在的图像位置或状态改变)和removed(图像不再被跟踪)的处理逻辑
        // 例如,你可以在此处销毁不再跟踪的图像对应的虚拟对象,或者更新已移动图像上的内容。
    }
}

下面是一些关于上面代码中核心类和方法的详细解释:

没有调用过ARTrackedImageManager 类下面的相关方法,尤其是 trackedImagesChanged,他是什么意思呢,什么作用? 

trackedImagesChanged 是 ARFoundation 中 ARTrackedImageManager 类的一个事件(可以去复习C#中的委托和事件的使用)。这个事件在图像跟踪状态发生改变时被触发!就会调用这个事件委托的函数(自己定义的)
在程序中如何使用呢?

 trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;

其中 trackedImageManager 是AR Tracked Image Manager 组件的对应类变量。存储了你场景中的一个AR Tracked Image Manager 组件!

+= OnTrackedImagesChanged;

这个意思是这个  trackedImageManager.trackedImagesChanged ,组件调用了一个委托事件trackedImagesChanged(代表识别的物体有变化,不管是位置、旋转、还是内容都算),一旦有变化我就委托一个函数去执行一个事情。trackedImageManager.trackedImagesChanged+=OnTrackedImagesChanged;

OnTrackedImagesChanged;就是一个自己定义的函数,被委托了!下面是这个函数的标准定义

 private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        //具体事情
    }

函数里面有个形式参数,这个参数是必须带的,就像我让你去办一件事,去把车门打开,我得给你钥匙,这个钥匙就是形式参数 ARTrackedImagesChangedEventArgs eventArgs!

ARTrackedImagesChangedEventArgs eventArgs

ARTrackedImagesChangedEventArgs 是 ARFoundation 提供的一个类,它作为参数传递给 ARTrackedImageManagertrackedImagesChanged 事件处理方法。这个类封装了在图像跟踪状态发生改变时的所有相关信息,包括哪些图像被新增、哪些被更新以及哪些被移除。通过分析 eventArgs 参数,开发者可以得知当前跟踪图像集合的具体变化情况,并据此做出相应的逻辑处理,比如实例化或销毁游戏对象、更新UI、执行特定动画等。

ARTrackedImagesChangedEventArgs 类包含三个主要的属性:

  1. added: 这是一个 NativeArray<ARTrackedImage> 类型的集合,包含了所有新被识别和开始跟踪的图像。每一个 ARTrackedImage 对象代表一个被跟踪的图像,包含了图像的 ID、大小、位置、旋转等信息。

  2. updated: 同样是 NativeArray<ARTrackedImage> 类型,包含了所有已跟踪图像中状态有所更新的图像(比如位置、姿态的微小变动)。开发者可以通过这些信息来实时调整已存在的AR内容,确保与实际跟踪状态同步。

  3. removed: 包含了 NativeArray<ARTrackedImage> 类型的集合,表示那些不再被跟踪的图像,可能是由于图像离开视野、遮挡或是其他原因导致跟踪丢失。对于这些图像,开发者通常需要清理与其关联的任何游戏对象或资源,以避免内存泄漏或视觉混乱。

在实际应用中,通过检查和响应 eventArgs 的这三个集合,开发者可以灵活地管理AR体验中的图像跟踪逻辑,保证应用的动态性和响应性。

完整示例代码:

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ImageTrackingEventHandler : MonoBehaviour
{
    public ARTrackedImageManager trackedImageManager;

    void Start()
    {
        // 确保ARTrackedImageManager组件已经附加到了某个游戏对象上
        if (trackedImageManager == null)
        {
            trackedImageManager = GetComponent<ARTrackedImageManager>();
        }

        // 订阅trackedImagesChanged事件
        if (trackedImageManager != null)
        {
            trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
        }
    }

    // 当跟踪的图像集合发生变化时,此方法会被调用
    private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        // 遍历新增的图像
        foreach (var trackedImage in eventArgs.added)
        {
            Debug.Log("新增图像: " + trackedImage.name);
            // 这里可以添加实例化预设体或其他处理逻辑
        }

        // 遍历更新的图像
        foreach (var trackedImage in eventArgs.updated)
        {
            Debug.Log("更新图像: " + trackedImage.name);
            // 可以在这里根据需要更新图像相关联的游戏对象状态
        }

        // 遍历移除的图像
        foreach (var trackedImage in eventArgs.removed)
        {
            Debug.Log("移除图像: " + trackedImage.name);
            // 这里可以添加销毁相关联游戏对象的逻辑
        }
    }

    void OnDestroy()
    {
        // 当这个脚本被销毁时,取消订阅事件,防止内存泄漏
        if (trackedImageManager != null)
        {
            trackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
        }
    }
}

9. 再来一份代码,实现图像不在被追踪是清除克隆的Image prefab

using UnityEngine; // 引入Unity基本库,提供游戏对象、组件、物理等基础功能
using UnityEngine.XR.ARFoundation; // 引入ARFoundation库,用于AR开发的核心功能
using UnityEngine.XR.ARSubsystems; // 引入AR子系统,提供低级AR支持
using System.Collections.Generic; // 引入通用集合类型,如List、Dictionary等

public class TrackedImageHandler : MonoBehaviour // 定义一个Unity组件类,可以挂载到游戏对象上
{
    public ARTrackedImageManager trackedImageManager; // 公开的ARTrackedImageManager组件引用,用于管理图像跟踪
    public GameObject imagePrefab; // 公开的GameObject预设体,当识别到图像时将克隆这个预设体

    private Dictionary<XRCameraImageId, GameObject> trackedObjects = new Dictionary<TrackableId, GameObject>(); // 私有的字典,用于存储跟踪图像ID与对应实例化游戏对象的关系

    void Start() // Unity生命周期方法,当游戏对象启动时调用
    {
        if (trackedImageManager == null) // 检查是否已经指定了trackedImageManager
        {
            trackedImageManager = FindObjectOfType<ARTrackedImageManager>(); // 如果没有指定,则尝试在场景中自动查找ARTrackedImageManager组件
        }

        if (trackedImageManager != null) // 确保找到了ARTrackedImageManager
        {
            trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged; // 注册事件处理器,当跟踪图像变化时调用OnTrackedImagesChanged方法
        }
        else
        {
            Debug.LogError("ARTrackedImageManager not found in the scene."); // 如果找不到ARTrackedImageManager,打印错误信息
        }
    }

    void OnDestroy() // Unity生命周期方法,在游戏对象被销毁前调用
    {
        if (trackedImageManager != null) // 确保trackedImageManager仍然有效
        {
            trackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged; // 解除事件注册,避免内存泄漏
        }
    }

    void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs) // 处理图像跟踪状态变化的事件方法
    {
        foreach (var trackedImage in eventArgs.removed) // 遍历移除的图像
        {
            GameObject trackedObject;
            if (trackedObjects.TryGetValue(trackedImage.trackableId, out trackedObject)) // 尝试从字典中获取关联的GameObject
            {
                Destroy(trackedObject); // 销毁关联的GameObject
                trackedObjects.Remove(trackedImage.trackableId); // 从字典中移除该条目
            }
        }

        foreach (var trackedImage in eventArgs.added) // 遍历新增的图像
        {
            if (!trackedObjects.ContainsKey(trackedImage.trackableId)) // 确保这个图像还没有被处理过
            {
                GameObject newObject = Instantiate(imagePrefab, trackedImage.transform.position, trackedImage.transform.rotation); // 实例化预设体,并放置在图像的位置和旋转
                trackedObjects.Add(trackedImage.trackableId, newObject); // 记录新实例化对象与图像ID的关联
            }
        }

        foreach (var trackedImage in eventArgs.updated) // 遍历更新的图像(位置或状态改变)
        {
            GameObject trackedObject;
            if (trackedObjects.TryGetValue(trackedImage.trackableId, out trackedObject)) // 获取关联的GameObject
            {
                trackedObject.transform.position = trackedImage.transform.position; // 更新游戏对象的位置
                trackedObject.transform.rotation = trackedImage.transform.rotation; // 更新游戏对象的旋转
            }
        }
    }
}

其他部分读者根据前面的理解应该能看懂!

解释一下其中的 if (trackedObjects.TryGetValue(trackedImage.trackableId, out trackedObject)) { Destroy(trackedObject); trackedObjects.Remove(trackedImage.trackableId); }

这段代码的作用是从一个字典(trackedObjects)中查找与特定跟踪图像ID(trackedImage.trackableId)关联的游戏对象,并在找到后进行销毁和从字典中移除的操作。让我逐步解释每一部分:

  1. if (trackedObjects.TryGetValue(trackedImage.trackableId, out trackedObject)):

    • TryGetValue 是 Dictionary 类的一个方法,用于尝试从字典中获取与指定键(这里是 trackedImage.trackableId)相关联的值(即游戏对象 GameObject)。
    • 方法有两个参数:键(key,这里是 trackedImage.trackableId)和一个输出参数(out parameter),用于接收查找到的值。如果找到了对应的键值对,这个值会被输出到 out 参数中;如果没有找到,输出参数会被赋予类型的默认值(对于引用类型,如 GameObject,默认值是 null)。
    • 这行代码的意思是尝试从 trackedObjects 字典中查找 trackedImage.trackableId 对应的 GameObject,并将找到的对象赋值给 trackedObject 变量。如果找到,TryGetValue 方法会返回 true,让 if 条件成立,执行后续代码。
  2. Destroy(trackedObject);:

    • 如果 trackedObject 不为 null(即字典中找到了与之关联的游戏对象),Destroy 函数会被调用,用来销毁这个 GameObject 实例。在Unity中,Destroy 方法用于清理游戏对象及其所有的子对象,释放它们占用的资源。
  3. trackedObjects.Remove(trackedImage.trackableId);:

    • 在销毁了游戏对象之后,这行代码从 trackedObjects 字典中移除与 trackedImage.trackableId 关联的条目。这样做是为了保持字典的整洁,避免保留不再使用的键值对,也有助于内存管理。

综上所述,这段代码块旨在处理图像跟踪移除事件,当一个AR跟踪图像不再被识别或跟踪时,它会安全地销毁与该图像关联的任何游戏对象实例,并清理字典中的记录,确保系统资源得到合理释放和管理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

继承-进阶

父子类成员共享 普通成员对象/父子间不共享&#xff0c; 成员独立 函数成员共享&#xff08;函数不存储在对象中&#xff09; 子类由两部分构成&#xff1a;父类中继承的成员和子类中新定义成员 继承方式 子类中存在父类private成员但不可直接访问&#xff08;及时在类中&am…

Istio_1.17.8安装

项目背景 按照istio官网的命令一路安装下来&#xff0c;安装好的istio版本为目前的最新版本&#xff0c;1.22.0。而我的k8s集群的版本并不支持istio_1.22的版本&#xff0c;导致ingress-gate网关安装不上&#xff0c;再仔细查看istio的发布文档&#xff0c;如果用istio_1.22版本…

链表题目练习----重排链表

这道题会联系到前面写的一篇文章----快慢指针相关经典问题。 重排链表 指针法 这道题乍一看&#xff0c;好像有点难处理&#xff0c;但如果仔细观察就会发现&#xff0c;这道题是查找中间节点反转链表链表的合并问题&#xff0c;具体细节有些不同&#xff0c;这个在反装中间链…

Linux守护进程揭秘-无声无息运行在后台

在Linux系统中&#xff0c;有一些特殊的进程悄无声息地运行在后台&#xff0c;如同坚实的基石支撑着整个系统的运转。它们就是众所周知的守护进程(Daemon)。本文将为你揭开守护进程的神秘面纱&#xff0c;探讨它们的本质特征、创建过程&#xff0c;以及如何重定向它们的输入输出…

有待挖掘的金矿:大模型的幻觉之境

人工智能正在迅速变得无处不在&#xff0c;在科学和学术研究中&#xff0c;自回归的大型语言模型&#xff08;LLM&#xff09;走在了前列。自从LLM的概念被整合到自然语言处理&#xff08;NLP&#xff09;的讨论中以来&#xff0c;LLM中的幻觉现象一直被广泛视为一个显著的社会…

记录汇川:红绿灯与HMI-ST

项目要求&#xff1a; 子程序&#xff1a; 子程序&#xff1a; 实际动作如下&#xff1a; 红绿灯与HMI-ST

电赛报告书写

一、总体要求 &#xff08;1&#xff09;摘要&#xff1a;一页&#xff0c;小于300字 &#xff08;2&#xff09;正文&#xff1a;不超过8页 &#xff08;3&#xff09;附录&#xff1a;可以没有&#xff0c;但是不能超过2页 二、摘要书写 摘要要小于等于300字&#xff0c…

牛客java基础(一)

A 解析 : java源程序只允许一个public类存在 &#xff0c;且与文件名同名 ; D hashCode方法本质就是一个哈希函数&#xff0c;这是Object类的作者说明的。Object类的作者在注释的最后一段的括号中写道&#xff1a;将对象的地址值映射为integer类型的哈希值。但hashCode()并不…

【Text2SQL 论文】C3:使用 ChatGPT 实现 zero-shot Text2SQL

论文&#xff1a;C3: Zero-shot Text-to-SQL with ChatGPT ⭐⭐⭐⭐ arXiv:2307.07306&#xff0c;浙大 Code&#xff1a;C3SQL | GitHub 一、论文速读 使用 ChatGPT 来解决 Text2SQL 任务时&#xff0c;few-shots ICL 的 setting 需要输入大量的 tokens&#xff0c;这有点昂贵…

【C语言】05.数组

一、数组的概念 本文来介绍数组&#xff0c;首先我们需要了解数组是什么&#xff1f; 数组是⼀组相同类型元素的集合。 • 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。 • 数组中存放的多个数据&#xff0c;类型是相同的。 数组分为⼀维数组和多维数组…

自用的2个chatpgt plus拼车渠道!!!

两个渠道&#xff0c;银河和环球&#xff0c;各有优劣 由于平台限制&#xff0c;链接和优惠码&#xff0c;可看原文 原文&#xff1a;https://www.aiutools.fun/archives/4978 先说结论 gpt重度用户&#xff1a;一天50次以上&#xff0c;选 环球 gpt轻度用户&#xff1a;一天用…

有关大学的搜题软件?六个不限次的公众号和软件分享啦 #其他#职场发展

有些同学虽然喜欢刷题&#xff0c;但是如果参考答案遗失、找不到参考答案&#xff0c;导致做好的题目无法校对&#xff0c;就会比较烦恼了。不过不用担心&#xff0c;今天就给大家分享一些超好用的搜题工具 1.彩虹搜题 这是个老公众号了 它不仅可以查到大学题目&#xff0c;…

Unity3D入门基础知识汇总

1. unity界面 右上边可以切换布局。 左边选择Shaded wireframe&#xff0c;可以看到3D物体的都是由三角形组成的。 2. 物体显示 网格&#xff08;三角形构成&#xff09; 材质 3. 资源商店 Windows -> Asset Store 挑出喜欢的资源之后&#xff0c;点击”添加至我的…

Qwen-VL论文阅读

论文地址 其他同学的详细讲解 模型结构和参数大小 &#xff08;1&#xff09;LLM&#xff1a;Qwen-7B &#xff08;2&#xff09;Vision Encoder&#xff1a;ViT架构&#xff0c;初始化参数是 Openclip’s ViT-bigG。 在训练和推理过程中&#xff0c;输入的图像都被调整到…

git(其六)--总结

配置基础信息 //1.配置用户名和邮箱 git config --global user.name "带着引号写一个昵称" git config --global user.email "带着引号写一个邮箱"//2.建立一个git本地库 git init//3.查看本地内容 git status //可以看到那些处于待加入本地库的文件&a…

​​​​​​ 基于Nmap的异步无状态端口扫描技术

​​​​​​ 基于Nmap的异步无状态端口扫描技术 传统的端口扫描&#xff0c;主要是依靠TCP三次握手去连接&#xff0c;而建立连接的各个过程都存在连接状态&#xff0c;这些状态由操作系统在底层实现存储&#xff0c;可利用这些状态对应用层的数据进行处理。但是&#xff0c;…

【Flutter】 TextField限制长度时, 第三方手写输入法、ios原始拼音输入法输入被吞问题

问题描述 TextField限制长度时&#xff0c; 当你的输入字符长度已经到了最大值-1时&#xff0c;使用第三方手写输入法或者ios原生拼音输入法输入liang&#xff08;什么拼音都行&#xff0c;这里只是举例&#xff09;&#xff0c;输到i那么li都会消失。 原因分析 这是因为第三…

[论文笔记]AIOS: LLM Agent Operating System

引言 这是一篇有意思的论文AIOS: LLM Agent Operating System&#xff0c;把LLM智能体(代理)看成是操作系统。 基于大语言模型(LLMs)的智能代理的集成和部署过程中存在着许多挑战&#xff0c;其中问题包括代理请求在LLM上的次优调度和资源分配&#xff0c;代理和LLM之间在交互…

苹果将推出“Apple Intelligence”AI系统,专注于隐私和广泛应用|TodayAI

据彭博社报道,苹果公司将在下周的 WWDC 2024 开发者大会上揭晓其全新的 AI 系统——“Apple Intelligence”,该系统将适用于 iPhone、iPad 和 Mac 设备。这一新系统将结合苹果自身技术和 OpenAI 的工具,为用户提供一系列新的 AI 功能,同时重点关注隐私保护和广泛应用。 与…

如何在virtualbox上安装Linux系统(centerOS)

提示&#xff1a;共同学习 注意&#xff1a;一定要在BIOS中的虚拟化打开。 文章目录 第一步&#xff1a; 第一步&#xff1a; 启动 、显示开启 centos基础安装 ​ ​