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

Python 语言学习——应用1.2 数字图像处理(第二节,变换)

目录

1.基础知识

        1.图像几何变换概念

        2.图像几何变换方式 

        3.插值运算

        4.几何变换步骤 

2.各类变换 

        1.位置变换

         2.形状变换

        3.代数运算 

3.实战演练 


1.基础知识

        1.图像几何变换概念

  • 在图像处理过程中,为了观测需要,常常需要对 图像进行几何变换,如几何失真图像的校正、图 像配准、电影、电视和媒体广告等的影像特技处 理等,是图像变形以及校正变形的基础。
  • 图像几何变换将图像中任一像素映射到一个新位置,是一种空间变换,关键在于确定图像中点与点之间的映射关系

        2.图像几何变换方式 

  • 首先有齐次坐标:用n+1维向量表示n维向量的方法称为齐次坐标 表示法。原图像用点集[x,y,1]^{T}(转置的意思)表示。好处:齐次坐标中,对原图像进行平移、缩放、旋转等 几何变换,可用一个变换矩阵表示。
  • 然后是变换矩阵:a,b,c,d用于图形的比例、对称、 错切、旋转等基本变换;k,m用于 图形的平移变换;p,q用于投影变 换;s用于全比例变换。
  • 实现2D图像几何变换的基本变换的一般过程是:变换矩阵T×变换前的点集矩阵=变换后的点集矩阵。 

        3.插值运算

  • 为什么会有这玩意:当你调整图像的大小,特别是缩小图像时,由于目标大小的像素数量少于原图像的像素数量,就需要通过插值算法来估算新像素的值。在进行旋转、平移、拉伸等几何变换时,图像的像素位置可能会发生变化(比如原x,y的像素点变成0.8x,0.9y算出来是个小数,则相应位置像素值不知道是多少)应用一些滤波器或处理器时,如模糊、锐化等操作,会导致像素值的变化,需要通过插值来重新计算像素值。

  • 概念:指利用已知邻近像素点的灰度值来产生未知像素点的灰度值(各通道)

  • 常用插值运算方法:

  1. 最近邻插值:非整数像素灰度值就等于距离最近 的坐标都为整数的像素的灰度值。 
  2. 双线性插值:利用非整数像素点周围的四个像素 点的相关性,通过双线性算法计算得出。图1算法或图2算法(利用周边四个点)。

  3. 双三次插值:利用非整数像素点周围的16个像素 点进行计算。

        4.几何变换步骤 

  1. 根据不同的几何变换公式计算新图像的尺寸
  2. 根据几何变换的逆变换,对新图像中的每一点确 定其在原图像中的对应点
  3. 按对应关系给新图像中各个像素赋值
  • 若新图像中像素点在原图像中的对应点坐标存 在,直接赋值
  • 若新图像中像素点在原图像中的对应点坐标超 出图像宽高范围,直接赋背景色
  • 若新图像中像素点在原图像中的对应点坐标在 图像宽高范围内,采用插值的方法计算 

2.各类变换 

        1.位置变换

  • 图像的位置变换是指图像的大小和形状不发生变化,只是图像像素点的位置发生变化,含平 移、镜像、旋转
  • 平移:若不想丢失信息,可能需要扩大画布

  • 镜像:M为总行数,N为总列数 

  • 旋转: θ为正,代表逆时针旋转,若要确定变换后的尺寸大小:计算原图像四个角在 旋转后的坐标;确定新图像的分辨率,M'=max x'-min x'+1;N'=max y'-min y'+1(结果向上取整).对于不在原点旋转的,先要将坐标系平移到原点,再按绕原点旋转进行变换,然后平移回原坐标原点。得到新图像的M',N'后,需依次确定[0,M'-1]+minx',[0,N'-1]+miny'各个像素点的值。也就是再逆变换回去,根据步骤第三点的三条进行赋值。

         2.形状变换

  • 缩放

  • 错切:平面景物在投影平面上的非垂直投 影,使图像中的图形产生扭变

     

        3.代数运算 

  • 加法运算如下图,应用主要有:多幅图像相加求平均去除叠加性噪声,将一幅图像的内容经配准后叠加到另一幅图像 上去,以改善图像的视觉效果,在多光谱图像中,通过加法运算加宽波段,如 绿色波段和红色波段图像相加可以得到近似全色图像,用于图像合成和图像拼接。

  • 减法运算如下图,应用主要有:显示两幅图像的差异,检测同一场景两幅图像 之间的变化;去除不需要的叠加性图案,加性图案可能是缓 慢变化的背景阴影或周期性的噪声,或在图像 上每一个像素处均已知的附加污染等;图像分割:如分割运动的车辆,减法去掉静止 部分,剩余的是运动元素和噪声;生成合成图像。 

  • 乘法运算主要是部分图框出来,也就是图像的局部显示和提取:用二值模板图像与 原图像做乘法来实现 。

  • 逻辑运算:原理如图。


3.实战演练 

P1. 试编写程序,对图像逆时针旋转60°,采用双线性插值的方法

from PIL import Image  # 导入PIL库,用于图像处理
import math #用于旋转时计算三角函数def bilinear_interpolation(image, x, y):# 将坐标转换为整数x1, y1 = int(x), int(y)x2, y2 = x1 + 1, y1 + 1# 处理边界情况if x2 >= image.width:x2 = x1if y2 >= image.height:y2 = y1# 获取四个相邻像素的RGB值q11 = image.getpixel((x1, y1))q21 = image.getpixel((x2, y1))q12 = image.getpixel((x1, y2))q22 = image.getpixel((x2, y2))r = []#空列表的创建# 处理 RGB 值的每个通道for i in range(3):  # 0: 红色通道, 1: 绿色通道, 2: 蓝色通道r.append(q11[i] * (x2 - x) * (y2 - y) + q21[i] * (x - x1) * (y2 - y) + q12[i] * (x2 - x) * (y - y1) + q22[i] * (x - x1) * (y - y1))return tuple(map(int, r))  # 返回处理后的 RGB 值def rotate_image(image, angle):# 旋转图像函数angle = angle % 360if angle == 0:return imagerotated_image = Image.new("RGB", image.size)  # 创建旋转后的图像对象for x in range(rotated_image.width):for y in range(rotated_image.height):# 计算旋转后的坐标,即逆变换找到原坐标位置x_original = ((x - rotated_image.width / 2) * math.cos(math.radians(angle)) -(y - rotated_image.height / 2) * math.sin(math.radians(angle)) + image.width / 2)y_original = ((x - rotated_image.width / 2) * math.sin(math.radians(angle)) +(y - rotated_image.height / 2) * math.cos(math.radians(angle)) + image.height / 2)if 0 <= x_original < image.width - 1 and 0 <= y_original < image.height - 1:# 应用双线性插值rotated_image.putpixel((x, y), bilinear_interpolation(image, x_original, y_original))#注意写法,这个函数第二个参数是元组表示的一组rgb的值return rotated_image# 打开图像文件
image = Image.open("rainbow.jpg")# 逆时针旋转60°
rotated_image = rotate_image(image, 60)# 保存旋转后的图像
rotated_image.save("rotated_image.jpg")  # 保存旋转后的图像

说明:map(int, r): 这部分使用了Python内置的 map 函数,它接受一个函数和一个可迭代对象作为参数。在这里,int 函数被应用于可迭代对象 r 中的每个元素,将每个元素转换为整数。tuple(...): tuple() 函数用于将一个可迭代对象转换为元组(tuple)。在这里,map(int, r) 返回一个迭代器,然后 tuple() 将这个迭代器转换为一个由整数组成的元组。

P2. 打开一幅图像,依次完成下列要求:顺时针旋转20°,做水平镜像,做错切变换,缩小图像。若需要插值运算,采用双线性插值方法;要求输出显示原图、中间结果和最后结果。(作为模板题)

import math #用于旋转时计算三角函数
from PIL import Imagedef resize_image(image, width_scale, height_scale):# 获取图像的宽度和高度width, height = image.size# 计算放大或缩小后的宽度和高度new_width = int(width * width_scale)new_height = int(height * height_scale)# 创建一个新图像对象,用于存储放大或缩小后的图像resized_image = image.resize((new_width, new_height))return resized_imagedef shear_image(image, shear_factor):# 获取图像的宽度和高度width, height = image.size# 计算错切后的宽度,只需计算宽度即可new_width = width + int(abs(shear_factor) * height)# 创建一个新图像对象,用于存储错切后的图像sheared_image = Image.new("RGB", (new_width, height))# 错切处理for x in range(new_width):for y in range(height):# 计算错切后的坐标,逆旋转new_x = x - int(shear_factor * y)if 0 <= new_x < width:# 获取原始图像中的像素值pixel = image.getpixel((new_x, y))# 将像素值复制到错切图像中sheared_image.putpixel((x, y), pixel)return sheared_imagedef mirror_image(image):# 获取图像的宽度和高度width, height = image.size# 创建一个新图像对象,用于存储镜像后的图像mirrored_image = Image.new("RGB", (width, height))# 镜像处理for x in range(width):for y in range(height):# 获取原始图像中的像素值pixel = image.getpixel((x, y))# 将像素值复制到镜像图像中,但是在水平方向上镜像mirrored_image.putpixel((width - x - 1, y), pixel)return mirrored_imagedef bilinear_interpolation(image, x, y):# 将坐标转换为整数x1, y1 = int(x), int(y)x2, y2 = x1 + 1, y1 + 1# 处理边界情况if x2 >= image.width:x2 = x1if y2 >= image.height:y2 = y1# 获取四个相邻像素的RGB值q11 = image.getpixel((x1, y1))q21 = image.getpixel((x2, y1))q12 = image.getpixel((x1, y2))q22 = image.getpixel((x2, y2))r = []#空列表的创建# 处理 RGB 值的每个通道for i in range(3):  # 0: 红色通道, 1: 绿色通道, 2: 蓝色通道r.append(q11[i] * (x2 - x) * (y2 - y) + q21[i] * (x - x1) * (y2 - y) + q12[i] * (x2 - x) * (y - y1) + q22[i] * (x - x1) * (y - y1))return tuple(map(int, r))  # 返回处理后的 RGB 值def rotate_image(image, angle):# 旋转图像函数angle = angle % 360if angle == 0:return imagerotated_image = Image.new("RGB", image.size)  # 创建旋转后的图像对象for x in range(rotated_image.width):for y in range(rotated_image.height):# 计算旋转后的坐标,即逆变换找到原坐标位置x_original = ((x - rotated_image.width / 2) * math.cos(math.radians(angle)) -(y - rotated_image.height / 2) * math.sin(math.radians(angle)) + image.width / 2)y_original = ((x - rotated_image.width / 2) * math.sin(math.radians(angle)) +(y - rotated_image.height / 2) * math.cos(math.radians(angle)) + image.height / 2)if 0 <= x_original < image.width - 1 and 0 <= y_original < image.height - 1:# 应用双线性插值rotated_image.putpixel((x, y), bilinear_interpolation(image, x_original, y_original))#注意写法,这个函数第二个参数是元组表示的一组rgb的值return rotated_image# 打开图像文件
image = Image.open("rainbow.jpg")
image.show()# 逆时针旋转-20°
rotated_image = rotate_image(image, -20)
rotated_image.show()mirror=mirror_image(rotated_image)
mirror.show()share=shear_image(mirror,2)
share.show()resize=resize_image(share,0.2,0.2)
resize.show()

P3. 打开两幅图像,利用几何变换、图像代数运算,生成一幅精美的合成图像

from PIL import Imagedef resize_image(image, width_scale, height_scale):# 获取图像的宽度和高度width, height = image.size# 计算放大或缩小后的宽度和高度new_width = int(width * width_scale)new_height = int(height * height_scale)# 创建一个新图像对象,用于存储放大或缩小后的图像resized_image = image.resize((new_width, new_height))return resized_imagedef add_images(sun_image, sky_image, output_path):# 获取太阳图像和天空图像的宽度和高度sun_width, sun_height = sun_image.sizesky_width, sky_height = sky_image.size# 确保太阳图像完全在天空图像内if sun_width <= sky_width and sun_height <= sky_height:# 创建一个新的图像对象,用于存储混合后的图像result_image = Image.new("RGB", (sky_width, sky_height))# 将天空图像复制到结果图像中result_image.paste(sky_image, (0, 0))# 将太阳图像叠加到左上角result_image.paste(sun_image, (0, 0), sun_image)# 保存混合后的图像result_image.show()else:print("Sun image is too large to fit entirely on the sky image.")# 图像文件路径sun_path = "sun.png"
sun_image = Image.open(sun_path)
sun_image.show()
sun=resize_image(sun_image,0.2,0.2)
sky_path = "sky.jpg"
output_path = "result_image.jpg"
sky_image = Image.open(sky_path)
sky_image.show()
# 执行图像混合操作
add_images(sun, sky_image, output_path)

 说明,paste函数的使用:语法为image.paste(image_to_paste, box, mask)image_to_paste: 要粘贴的图像对象。box: 表示将图像粘贴到另一个图像的位置,通常是一个元组 (x, y),表示左上角的坐标。mask: 用于指定一个掩码图像,一般而言为数值,从0不透明到255透明,也可以是一个二值图像,如果提供了掩码图像,它将根据掩码的像素值来控制被粘贴图像的透明度,使得被粘贴图像可以部分透明地展现在目标图像上。

题外话:不要吐槽图像的精美程度。

相关文章:

Python 语言学习——应用1.2 数字图像处理(第二节,变换)

目录 1.基础知识 1.图像几何变换概念 2.图像几何变换方式 3.插值运算 4.几何变换步骤 2.各类变换 1.位置变换 2.形状变换 3.代数运算 3.实战演练 1.基础知识 1.图像几何变换概念 在图像处理过程中&#xff0c;为了观测需要&#xff0c;常常需要对 图像进行几何变换&am…...

【QT Quick】页面布局:手动定位与坐标系转换

在这篇教程中&#xff0c;我们将详细介绍在 QT Quick 中如何手动定位元素以及坐标系转换的概念和应用。手动定位不仅仅是指定 x、y 坐标&#xff0c;更涉及坐标系的管理。我们会从最基本的手动定位开始&#xff0c;逐步扩展到更复杂的坐标系转换操作。 坐标系 默认坐标系&…...

uniapp自定义导航,全端兼容

我们在用uniapp 开发应用的时候&#xff0c;有的页面需要自定义导航&#xff0c; 1.如果普通的直接使用uni 扩展柜组件的 uni-nav-bar 也基本够用&#xff0c; 2.如果稍微带点自定义的这个值无法支持的&#xff0c;特别在小程序端&#xff0c;胶囊是会压住右边的按钮的 自定…...

[论文阅读] DVQA: Understanding Data Visualizations via Question Answering

原文链接&#xff1a;http://arxiv.org/abs/1801.08163 启发&#xff1a;没太读懂这篇论文&#xff0c;暂时能理解的就是本文提出了一个专门针对条形图问答的数据集DVQA以及一个端到端模型SANDY&#xff0c;模型有两个版本&#xff0c;Oracle和OCR。主要解决的问题是固定词表无…...

【PostgreSQL】实战篇——数据备份和恢复的最佳实践和工具

数据备份和恢复是确保数据安全性和可用性的关键环节。无论是由于硬件故障、软件错误、数据损坏还是人为错误&#xff0c;能够快速恢复数据都是保护业务连续性的重要措施。 PostgreSQL 提供了多种备份和恢复工具和方法&#xff0c;其中最常用的包括 pg_dump、pg_restore 和点时…...

代码随想录算法训练营第二十九天|93.复原IP地址 78.子集 90.子集II

93.复原IP地址 给定一个只包含数字的字符串&#xff0c;复原它并返回所有可能的 IP 地址格式。 有效的 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"…...

【mysql】使用AbstractRoutingDataSource实现多数据源 与 获取mapper上注解

使用AbstractRoutingDataSource实现多数据源 与 获取mapper上注解 背景 随着业务发展速度越来越快&#xff0c;数据的增长也呈现倍数级别增长&#xff0c;数据库的压力&#xff0c;对于查询和写入等所有操作&#xff0c;都依赖于主库&#xff0c;其实有一些对于时效性要求不高…...

希沃冰点还原

要取消希沃冰点还原&#xff0c;可以按照以下步骤进行&#xff1a; 打开希沃冰点还原的应用或程序。 在应用或程序的界面上&#xff0c;寻找设置选项或菜单。 点击或选择设置选项或菜单&#xff0c;进入设置界面。 在设置界面上&#xff0c;查找“取消”或“停止”等相关选项…...

Hadoop服务端口号、Spark端口号、Hive端口号以及启动命令

文章目录 1. 服务端口号1.1 Hadoop相关的服务端口号1.2 Spark相关的服务端口号1.3 Hive的连接端口 2. 服务启动指令 1. 服务端口号 1.1 Hadoop相关的服务端口号 HDFS的web页面访问端口 9870HDFS 的程序访问端口 8020Yarn的访问端口 8088历史日志访问端口 19888 1.2 Spark相关…...

【C++】--类和对象(3)

&#x1f911;个人主页: 起名字真南 &#x1f911;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 深入构造函数2 类型转换3 static成员4 友元函数5 内部类6 匿名对象 1 深入构造函数 之前我们实现构造函数的时候&#xff0c;初始化成员变量都是在函数体内赋值&#xff0c…...

国外电商系统开发-运维系统文件上传-高级上传

如果您要上传文件到10台服务器中&#xff0c;有3台服务器的路径不是一样的&#xff0c;那么在这种情况下您就可以使用本功能&#xff0c;单独执行不一样的路径 点击【高级】上传...

【MongoDB】mongodb | 部署 | 常用命令

一、概述 基于mongodb的tcp连接无数据上报&#xff0c;服务器强踢监测。 物联网项目&#xff0c;tcp协议&#xff0c;基于4G卡&#xff0c;设备由于某些原因会断开重连&#xff0c;但是tcp没有断开&#xff0c;导致tcp持续累加&#xff0c;浪费资源。 建立机制&#xff1a; 当t…...

【Chrome浏览器插件--资源嗅探猫抓】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、资源嗅探插件---猫抓二、使用步骤总结 一、资源嗅探插件—猫抓 猫抓是一个浏览器插件&#xff0c;可以检测当前网页中的一些资源文件&#xff0c;可设置嗅探的…...

2.4Mybatis——缓存机制

2.4Mybatis——缓存机制 缓存配置一二级缓存一级缓存二级缓存 合集总览&#xff1a;Mybatis框架梳理 讲真&#xff0c;Mybatis缓存这块的记忆已经模糊了。刚好此时写测试用例出现一个BUG&#xff0c;就以这个问题作为切入点来梳理一下。 Testpublic void test(){Address ad…...

移动技术开发:文件的读取

1 实验名称 文件的读写 2 实验目的 掌握Android中读写文件的实现方法。 3 实验源代码 布局文件代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android&quo…...

Linux 中的 Makefile 伪目标详解

在 Linux 环境中&#xff0c;Makefile 是构建项目的重要工具&#xff0c;它通过定义规则&#xff0c;指导 make 工具如何编译和链接程序。通常我们会在 Makefile 中定义目标&#xff08;target&#xff09;&#xff0c;这些目标通常对应文件名。然而&#xff0c;有一种特殊类型…...

Java基础(中)

变量 成员变量与局部变量的区别 语法形式&#xff1a;从语法形式上看&#xff0c;成员变量是属于类的&#xff0c;而局部变量是在代码块或方法中定义的变量或是方法的参数&#xff1b;成员变量可以被 public,private,static 等修饰符所修饰&#xff0c;而局部变量不能被访问控…...

Leetcode热题100-200 岛屿数量

Leetcode热题100-200 岛屿数量 1. 题目描述2. 代码实现1. dfs算法2. bfs算法 1. 题目描述 200 岛屿数量 2. 代码实现 1. dfs算法 class Solution { public:int numIslands(vector<vector<char>>& grid) {int m grid.size(), n grid[0].size();int res 0…...

大数据新视界 --大数据大厂之 GraphQL 在大数据查询中的创新应用:优化数据获取效率

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

swift使用代码结构解析

多模态模型的训练llamafactory也可以训练&#xff0c;但是总的来说&#xff0c;llamafactory对多模态模型的支持还是不太多&#xff0c;ms-swift支持的多模态模型更多&#xff0c;因此有时候去找框架是否够支持相应的模型时会有所困难&#xff0c;所以对这些框架的代码也要稍微…...

五、Python基础语法(程序的输入和输出)

一、输入 输入&#xff1a;输入就是获取键盘输入的数据&#xff0c;使用input()函数。代码会从上往下执行&#xff0c;当遇到input()函数&#xff0c;就会暂停执行&#xff0c;输入内容后&#xff0c;敲回车键&#xff0c;表示本次的输入结束。input函数得到的数据类型都是字符…...

【C语言】常见概念

文章目录 库函数关键字字符和ASCll编码字符串与\0转义字符语句和语句分类注释 库函数 为了不再重复实现常见的代码&#xff0c;让程序员提升开发效率&#xff0c;C语言标准规定了一组函数&#xff0c;这些函数再由不同的编译器厂商根据标准进行实现&#xff0c;提供给程序员使…...

Electron应用创建和打包

一、创建项目目录 创建NodeJs项目目录&#xff0c;项目有关的文件、依赖包都将在本目录创建和安装。 mkdir hello_electron & cd hello_electronCMD执行以上命令将在用户目录下创建hello_electron并进入该目录。当然也可以手动在任何地方创建目录&#xff0c;cmd中cd 路径…...

代码随想录算法训练营第五六天| 99. 岛屿数量 100. 岛屿的最大面积

今日任务 99. 岛屿数量 深度搜搜 99. 岛屿数量 广度搜索 100. 岛屿的最大面积 99. 岛屿数量 题目链接&#xff1a; 99. 岛屿数量 import java.util.Scanner;public class Main {public static int[][] dir {{0, 1},{1, 0},{-1, 0},{0, -1}};public static void dfs(boolean…...

图解 微信开发者工具 小程序源码 调试、断点标记方法 , 微信小程序调试器,真机调试断点调试方法,小程序网络API请求调试方法 总结

在我们使用微信开发者工具进行微信小程序开发的时候&#xff0c;在这个微信开发者工具的代码编辑框里面我们是无法像使用vscode, idea等IDE工具时那样直接对代码打断点进行调试&#xff0c; 原因是小程序实际上他就是一个web浏览器应用的包装, 在其内部使用的还是类似chrome的…...

注释,换行,控制台输入输出,命名空间,省略return语句

注释 1.单行注释 // 2.多行注释 /*注释内容*/ 解释代码的作用&#xff1b;注释多余内容&#xff1b;注释不会影响代码执行 换行 \nstd::endl 控制台输入输出 输出123456 可一次性输出多个 std::cout<<"123456"//示例获取控制台输入内容&#xff0c;存储在…...

宠物空气净化器该怎么选?希喂,小米、安德迈这三款好用吗?

不得不说&#xff0c;虽然现在购物网站的活动不少&#xff0c;可力度都好弱啊&#xff01;我想买宠物空气净化器很久了&#xff0c;觉得有点贵&#xff0c;一直没舍得入手。价格一直没变化&#xff0c;平台小活动根本没什么优惠&#xff0c;只能寄希望于双十一了&#xff0c;准…...

【Mybatis篇】Mybatis的注解开发

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】&#xff0c;【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 文章目录 &#x1f3af; Select注解 …...

NEC协议

NEC协议是一种红外线通信协议&#xff0c;广泛应用于家电遥控器和其他红外线设备之间的通信。以下是对NEC协议的详细解释和介绍&#xff1a; 一、开发背景与应用 NEC协议由日本电子公司NEC&#xff08;日本电气公司&#xff09;开发&#xff0c;因其简单、易于实现和广泛兼容…...

Meta 发布 Quest 3S 头显及 AR 眼镜原型:开启未来交互新视界

简介 在科技的浪潮中&#xff0c;Meta 始终站在创新的前沿&#xff0c;不断为我们带来令人惊叹的虚拟现实和增强现实体验。2024 年 10 月 6 日&#xff0c;让我们一同聚焦 Meta 最新发布的 Quest 3S 头显及 AR 眼镜原型&#xff08;Orion&#xff09;&#xff0c;探索这两款产品…...