游戏引擎中的颜色科学

news2024/11/24 10:56:08

游戏引擎中的渲染组件的作用是生成一个二维图片,在特定的时间从给定的视点观察的方向看到的一个三维空间的状态。他们的生成每一张图片都会被称为帧,他们生成的速度称为帧率。

像素

在每一帧中,游戏引擎的视觉输出基本上是一大堆彩色像素,像素(Pixel)是图像基本的单元,图像尺寸通常是像素的长宽。

常见的显示器由数百万个像素,每个像素都会以一个比例发出红蓝绿三种颜色的光,一种通用制作颜色的系统称为RGB系统,他是游戏引擎通过计算颜色信息并发送给GPU最终显示给用户的方式。

图像的RGB颜色数据存储在一个称之为 FrameBuffer 帧缓冲区的内存块中。根据像素的格式不同,每个像素可以占据多达 128 位的空间。通常用于显示的图像 32位 或者 64位。每个像素的存储被分为4个通道 RGBA,在每像素 32 位的情况下,通常是 8位无符号整数,在每个像素64位的情况下,通常是16位浮点值。RGBA的前三个分量表示为红, 绿, 蓝 3种分量的强度,第4个分量为 alpha 分量,它表示是RGB分量额外的信息。(应该是计算机使用4的倍数比3的倍数更快)

颜色科学

在渲染3D图像之前,我先介绍下人类是如何感知色彩的以及RGB原理,正如我之前(彩色成像基础和应用[还未翻译完成])的篇章,在这篇我也将在下面的内容中继续阐述。

RGB系统作为色彩制作的一种系统之所以盛行的原因是与人类视觉的解剖结构有关。在光线明亮的情况下,眼球中心附近的光感受由视网膜上三种锥体细胞主导,他们对光谱中不同范围(400-750nm)的电磁辐射敏感。这三种锥体细胞被称为光视觉(photopic vision)。它与暗视觉(scotopic vision)不同,在黑暗的情况下,杆状细胞占主导(锥体细胞不活跃),杆状细胞不具备辨别颜色的能力。所以我们晚上很难分辨颜色。在光的辐射强度保持不变的情况下,下图显示了三种锥状细胞对光的相对敏感度与波长的函数关系。L 锥状细胞对感知光亮度的贡献最大,因为视网膜上大约 63% 的锥状细胞( L 锥状细胞),M 锥状细胞约占 31%,S 锥状细胞占其余的 6%。

CIE RGB颜色空间

三个刺激值的线性能力意味着我们可以构建一个三维向量空间。然而,这个叠加的量有点特殊,因为人类视觉物理上可能存在值不一致的情况(视觉心理量)。所以,20世纪的配色实验采用了红色,绿色和蓝色作为LMS刺激的基色。配色实验是以绿光 546.1 nm 蓝光 435.8 nm 红光 700 nm 。如下图(汞蒸汽灯的发射线)

图中具有负值,请注意,单一波长的光如果不等于某个基色(Primary Colors【在混合某种颜色所作为的基础颜色 例如在RGB中R G B颜色的通道所占比例】)那么想要某种的颜色将无法混合出来。在颜色匹配函数中而且还存在负值。对于红色,这一点很明显。所以,这些负值所代表的颜色无法被RGB空间所表示出来,这就限制定义了颜色空间的色域,即可以通过以任何比例混合基色生成的所有颜色的集合。

CIE XYZ 颜色空间

CIE RGB 如果它被用作所有颜色测量的国际标准,颜色空间在其标准化中具有一些被视为不太理想的特性,(例如上图存在负值RGB无法表示),还有光的亮度(不考虑颜色感知的亮度)混合在RGB的三个值中。一般更好的做法是用三刺激值表达,并将亮度直接用三刺激之一给出:这就是下面所讲的内容CIE XYZ颜色空间。

 当将上面公式应用于r(λ)  g(λ) b(λ)中时,它生成了CIE XYZ颜色空间,它们在整个可见光谱上都有正值。此外,XYZ矩阵的第二行条目Y经过精心选择,以使函数 y(λ) 尽可能接近V(λ)显示的亮度函数 ,这两个函数通常被接受为完全相等。因此,颜色的 Y 组件直接对应于其在 XYZ 颜色空间中的亮度。

X 和 Z 组件是一些抽象量,对应于色度,这是一个在不考虑亮度的情况下的感知颜色的度量。然而,随着颜色变得更亮或更暗,这些组件会随着亮度 Y 进行缩放。通过缩放颜色 (X, Y, Z) 使其位于平面 X + Y + Z = 1 上,可以计算出规范化的色度坐标 x、y 和 z,其公式为

由于这些缩放值的总和为一,因此只需要其中两个就可以完全描述颜色的色度,第三个值是冗余的。我们可以选择任意两个,但标准做法是取 x 和 y 色度坐标,并将它们与原始的 Y 亮度值结合形成所谓的 xyY 颜色空间。这是一个通用标准,通过它可以为任何可被普通人观察者感知的颜色(无论是单色还是多波长混合)提供精确的数值规格,并作为定义其他颜色空间的基础。给定某一特定颜色的 x、y 和 Y 值,我们可以使用逆公式计算 X 和 Z 值。这些值对于在由其主色的色度定义的颜色空间之间转换是有用的。

上图显示了与 xy 色度坐标相对应的颜色的二维图。这个图称为 CIE xy 色度图,尽管无法在印刷中准确再现所有颜色,但每种普通人眼可以感知的颜色都被包括在内。形成大多数外边界的曲线是光谱轨迹,由单色颜色组成。光谱轨迹上某一点的色度坐标是通过使用 x(λ)、y(λ) 和 z(λ) 颜色匹配函数来确定单一波长的 X、Y 和 Z 组件,然后应用方程 x = X  /  X+Y+Z, y = X  /  X+Y+Z 来获得 x 和 y。任何不位于光谱轨迹上的颜色都是多波长的混合。特别是,光谱轨迹上的最短和最长波长通过图的底部附近的紫色线连接。该线包含所有无法通过任何单一波长的光产生的完全饱和紫色。位于图的彩色区域之外的任何一对 xy 坐标被认为是“虚构”颜色的色度,因为它们没有实际的光源或物理对应物,仅在理论上存在。

x、y 和 z 颜色匹配函数经过归一化,以便在每个可见波长上具有相同的值。 这意味着,对于这样的理想光源,有 XYZ = 1,因此完美白光的 xy 色度坐标为 (1/3, 1/3)。当然,平坦的光谱功率分布在日常环境中并不实际发生,因此 CIE 定义了具有特定相对功率的标准光源,这些功率在可见波长的表中列出。与计算机图形学相关的标准光源称为 D65,其光谱功率分布如下图所示。标准光源 D65 的设计旨在近似不同地理位置在一年中的平均日光。数字 65 表示该光源与根据普朗克黑体辐射定律预测的6500K温度的理想光谱功率分布相关联,如图中的虚线所示。

当我们将 CIE 标准观察者的颜色匹配函数 x(λ)、y(λ) 和 z(λ) 与 D65 光源的光谱功率分布 SD65(λ)相乘并对所有波长积分时,可以得到白点的色度坐标 (xw, yw)。具体步骤如下:

首先,计算三刺激值 Xw​、Yw​、和 Zw:

然后,通过归一化得到色度坐标 xw​ 和 yw​:

得出的结论:

这些坐标定义了光源的白点,这个位置在CIE xy 色度图中显示。加色空间中基色的亮度通常通过要求基色的混合成等比例产生在亮度 Yw = 1 时的白点的给定色度来定义。

sRGB 颜色空间

在1990年代末,选择了红、绿、蓝基色的色度,以与当时的显示设备紧密匹配,这定义了所谓的标准 RGB 颜色空间,或通常称为 sRGB 颜色(这与 CIE RGB 颜色空间不同,但由于 sRGB 基色是用 CIE XYZ 颜色空间中的色度定义的,因此两者之间存在具体关系)。sRGB 颜色空间是大多数计算机图形应用程序默认使用的颜色空间,当没有指定其他颜色空间时,可以认为它是正确的颜色空间。

sRGB 基色的确切色度坐标 (xr, yr)、(xg, yg) 和 (xb, yb) 被定义为:(最大亮度下的  亮度=1)

这些基色在CIE xy 色度图中作为点 R、G 和 B 显示,并且连接它们的三角形表示 sRGB 颜色空间的色域。该三角形外的颜色无法在仅使用每个基色的正值的设备上产生。图的左上部分有大量颜色被排除在色域之外,但光谱轨迹在该区域被拉伸。因此,尽管某些颜色无法在标准 sRGB 设备上完全还原,但它们仍然通过色域外的光谱轨迹被拉伸,以呈现其与其他颜色相比的可感知差异。这意味着即使超出了 sRGB 色域的颜色,它们在视觉上的表现仍然是相对良好的,这并不是一个严重的问题。

sRGB 颜色空间定义了颜色白的色度坐标,如方程xw =0.3127 yw =0.3290  所示。这使我们可以通过要求颜色 (xr, yr, Yr)、(xg, yg, Yg) 和 (xb, yb, Yb) 的总和为白点 (xw, yw, 1) 来计算红、绿和蓝基色的亮度 Yr、Yg 和 Yb。我们不能直接用其 (x, y, Y) 坐标相加颜色,但可以通过应用下列方程  来相加其 (X, Y, Z) 坐标。(绿色基色的亮度通常被设为1)

这将产生以下等式:

从中,我们可以通过反转 3x3 矩阵求解亮度:

这些值告诉我们需要混合多少基色,以产生在 sRGB 颜色空间中被认为是白光的颜色。(例如要使Yr的亮度=Yb的亮度需要 0.212639 ⋅ R = 0.072192 ⋅ B)

为了找到将任何颜色从 XYZ 空间转换到 sRGB 空间的 3x3 矩阵,我们可以强制要求每个基色的色度如色度方程 公式#0 所示,并且亮度如上述亮度方程 公式#2 所示,映射到一个颜色 (R, G, B),其中对应于基色的分量为1,其他两个分量为0。这可以写成矩阵方程:

其中,右边的单位矩阵列表示sRGB空间中最大亮度下的红、绿、蓝主函数,左边的矩阵列为XYZ空间中对应的坐标。我们通过简单地对主矩阵XYZ坐标的反转来求解转换矩阵MsRGB

其中每个条目都被四舍五入到小数点后六位。正如预期的那样,矩阵MsRGB将D65的白点映射到sRGB的颜色(1,1,1),用方程表示为:

MsRGB 的逆是方程 MsRGB(公式#4) 中显示的 XYZ 基色矩阵,它提供了从 sRGB 颜色空间回到 XYZ 颜色空间的转换。其条目为:

同样,每个条目都已四舍五入到小数点后六位。MsRGB^-1 的第二行条目是方程 公式#3 中给出的亮度 Yr、Yg 和 Yb,它们是通过这些分量计算颜色 (R, G, B) 的亮度 Y 的系数,如下所示:

这是将彩色图像转换为仅包含亮度信息的灰度图像的公式。这三个不同的系数代表了基色的相对明显亮度,基于亮度函数,并且它们的总和为1,因为全强度的 RGB 颜色 (1, 1, 1)(即白色)必须具有亮度为1。

渲染图像的着色器程序通常通过将每种颜色视为一个三维向量,其中 x、y 和 z 组件表示标准红、绿、蓝基色的强度来执行颜色相关的计算。两个颜色可以像向量一样逐分量相加,这是一种完全有效的操作,因为它符合Grassmann定律。将颜色乘以标量以增加或减少其亮度也是有效的,方式与向量相同。这两种操作可以应用于作为基向量的全强度红、绿和蓝颜色,其值分别为 (1, 0, 0)、(0, 1, 0) 和 (0, 0, 1),以生成图 RGB颜色立方体 所示的 RGB 颜色立方体。在图中,我们可以看到三个面,其中一个分量的值为1,其他两个分量的值从0变化到1。该立方体展示了红色和绿色如何组合形成黄色,绿色和蓝色组合形成青色,蓝色和红色组合形成洋红色,所有三种基色组合形成白色。在立方体的背面,每个面的颜色都有一个分量的值为0,并且它们在 (0, 0, 0) 相交形成黑色。连接 (0, 0, 0) 和 (1, 1, 1) 的对角线包含了黑色和白色之间的所有灰度级。

在许多情况下,需要将两种颜色相乘。例如,光的颜色可能表示为一种 RGB 颜色,而表面反射的颜色可能表示为另一种 RGB 颜色。为了确定达到观察者的光颜色,因此表面呈现的颜色,可以简单地将光颜色和反射颜色相乘。这种颜色之间的乘积通过逐分量乘法计算,通常会产生对物理现实的可接受近似。以这种方式乘法并不总是正确的,但在没有额外信息的情况下,我们无法做得更好。正确的方式是计算它们的光谱在足够离散波长下的乘积,以获得准确的结果。继续以反射光为例,发射光的光谱功率分布需要与表面的反射光谱相乘。然后,该乘积需要与 sRGB 颜色空间的红、绿和蓝颜色匹配曲线相乘并积分,以确定应该显示的每个分量的强度。由于计算开销和存储要求等原因,游戏引擎通常不会为生成物理正确的结果而如此复杂,而是仅在乘法上下文中使用 RGB 颜色。

用于RGB运算的代码如下

struct ColorRGBA
{
	float red, green, blue, alpha;
	ColorRGBA() = default;
	ColorRGBA(float r, float g, float b, float a = 1.0F)
	{
		red = r; green = g; blue = b; alpha = a;
	}
	ColorRGBA& operator *=(float s)
	{
		red *= s; green *= s; blue *= s; alpha *= s;
		return (*this);
	}
	ColorRGBA& operator /=(float s)
	{
		s = 1.0F / s;
		red *= s; green *= s; blue *= s; alpha *= s;
		return (*this);
	}
	ColorRGBA& operator +=(const ColorRGBA& c)
	{
		red += c.red; green += c.green; blue += c.blue; alpha += c.alpha;
	}
	ColorRGBA& operator −= (const ColorRGBA& c)
	{
		red − = c.red; green −= c.green; blue − = c.blue; alpha −= c.alpha;
	}
	ColorRGBA& operator *=(const ColorRGBA& c)
	{
		red *= c.red; green *= c.green; blue *= c.blue; alpha *= c.alpha;
	}
};

inline ColorRGBA operator *(const ColorRGBA& c, float s)
{
	return (ColorRGBA(c.red * s, c.green * s, c.blue * s, c.alpha * s));
}

inline ColorRGBA operator /(const ColorRGBA& c, float s)
{
	s = 1.0F / s;
	return (ColorRGBA(c.red * s, c.green * s, c.blue * s, c.alpha * s));
}
inline ColorRGBA operator +(const ColorRGBA & a, const ColorRGBA & b)
{
	return (ColorRGBA(a.red + b.red, a.green + b.green,
		a.blue + b.blue, a.alpha + b.alpha));
}
inline ColorRGBA operator −(const ColorRGBA & a, const ColorRGBA & b)
{
	return (ColorRGBA(a.red − b.red, a.green − b.green,
		a.blue − b.blue, a.alpha − b.alpha));
}
inline ColorRGBA operator *(const ColorRGBA & a, const ColorRGBA & b)
{
	return (ColorRGBA(a.red * b.red, a.green * b.green,
		a.blue * b.blue, a.alpha * b.alpha));
}

Gamma Correction 伽马矫正

在阴极射线管(CRT)显示器的时代,每个像素的每个颜色通道的亮度是由输入信号的非线性函数决定的,这与电路的工作方式有关。某一输入值 Vsignal 的显示亮度 Vdisplay 由以下关系给出:

其中,指数 γ 通常在 2.0 到 2.5 的范围内。这个函数被称为伽马曲线(gamma curve),得名于用于指数的希腊字母。虽然从工程角度来看并不必要,但新型显示技术故意保持这一关系以确保一致性。

伽马曲线的存在意味着在渲染世界时计算出的最终颜色不应直接显示,因为大多数强度将显得过暗。图 gamma 展示了线性灰度强度梯度在 gamma 值约为 2.2 的普通显示器上的显示效果。根据公式#6 ,强度值 0.5 的实际亮度在显示时约为 22%,远低于预期的 50% 亮度。为了补偿这一效果,必须在将颜色值存储到帧缓冲区之前进行伽马校正。强度值通过将其提升到 $1/\gamma$ 次方来进行伽马校正,从而执行 公式#6 的逆操作。图 gamma 中的第二个灰度梯度展示了在所有强度值下显示的正确亮度。

当描述颜色为编码为 sRGB 时,通常意味着每个分量的强度已进行伽马校正并以非线性值存储,我们将使用 sRGB 术语表示这一确切含义。未进行伽马校正的颜色被简单地称为线性颜色。(这两种颜色都使用相同的 sRGB 原色集。)sRGB 标准定义了线性分量与 sRGB 分量之间的转换函数,这些函数与 公式#6 中的关系稍有不同,以避免在零附近出现无限导数。线性颜色的每个分量 c 通过函数 fsRGB 进行伽马校正以转换为 sRGB 颜色的分量。被定义为

在相反方向上,sRGB 颜色的每个分量 c 通过函数 flinear 转换为线性颜色的分量。

这两个函数在图 gamma转换函数 中绘出,且它们是精确的逆函数。尽管这些转换函数使用 2.4 的指数,但 flinear 的整体形状与大多数显示器使用的 2.2 伽马值的 公式#6 非常接近,曲线 f(c) = c^{2.2} 也在图中用于对比。这意味着 fsRGB 函数非常接近显示器应用的伽马曲线的逆函数,因此 fsRGB 应用的伽马校正使得显示的强度看起来是线性的。

当图像存储在低精度格式(例如每通道 8 位)时,伽马校正还有额外的好处。人眼在低强度下能够检测到较小的亮度差异,而在高强度下则难以区分。因此,如果以线性方式存储强度,则过多的离散值会分配给相互无法区分的高强度,而较少的离散值则分配给低强度,而这些低强度的相邻值相对容易区分。应用伽马校正可以重新分配 256 个可用值,使得更少的值对应于高强度,而更多的值对应于低强度。这在眼睛更加敏感的强度水平上提供了更高的精度。此方法适用于直接在伽马校正空间中创作的图像,或在更高位深度中存储的图像,这些图像在转换到每通道 8 位的低精度之前进行了伽马校正。因此,伽马校正有时被称为伽马压缩,因为通过重新分配强度值保留了部分高精度。

大多数数字图像格式(如 JPEG 和 PNG)默认将颜色以伽马校正的强度存储在 sRGB 色彩空间中。然而,涉及光照、反射和大气效应的渲染计算都需要在一个线性空间中进行。最终的颜色在显示前需要进行伽马校正。为了简化这一过程,图形硬件能够在适当的时刻自动执行 公式#7 和 公式#8 所定义的转换。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css中pointer-events:none属性对div里面元素的鼠标事件的影响

文章目录 前倾提要当没有设置属性pointer-events时候结果 当子元素设置了pointer-events: none修改后的代码结果如下所示 当父元素设置了pointer-events: none若两个div同级也就是兄弟级 前倾提要 在gis三维开发的地图组件上放一个背景图片,左右两侧的颜色渐变等&a…

中科蓝汛GPIO操作说明

概述 本篇文章介绍如何使用中科蓝汛AB5681,GPIO管脚使用说明。 一、第一种写法 1)、GPIO配置输入模式 //内部上拉 GPIOBDE | BIT(4); //数字IO使能: 0为模拟IO, 1 为数字IO GPIOBDIR | BIT(4); //控制IO的方向: 0为输出, 1为输入. GPIOBFEN &…

Kotlin 协程使用及其详解

Kotlin协程,好用,但是上限挺高的,我一直感觉自己就处于会用,知其然不知其所以然的地步。 做点小总结,比较浅显。后面自己再继续补充吧。 一、什么是协程? Kotlin 协程是一种轻量级的并发编程方式&#x…

LabVIEW 离心泵机组故障诊断系统

开发了一套基于LabVIEW图形化编程语言设计的离心泵机组故障诊断系统。系统利用先进的数据采集技术和故障诊断方法,通过远程在线监测与分析,有效提升了离心泵的预测性维护能力,保证了石油化工生产的连续性和安全性。 项目背景及意义 离心泵作…

线程函数和线程启动的几种不同形式

线程函数和线程启动的几种不同形式 在C中&#xff0c;线程函数和线程启动可以通过多种形式实现。以下是几种常见的形式&#xff0c;并附有相应的示例代码。 1. 使用函数指针启动线程 最基本的方式是使用函数指针来启动线程。 示例代码&#xff1a; #include <iostream&g…

辐射传输方程的分解

Decomposition of the Boundary Value Problem for Radiative Transfer Equation of MODIS and MISR instruments 0.Notions Let L L L be the straming-collision operator, and S S S is scattering operator: L I Ω ⋅ ∇ I ( r , Ω ) σ ( r , Ω ) I ( r , Ω ) S…

智会智展,活动必备

智会智展 APP 各大应用市场均可下载统一链接https://m.malink.cn/s/r6nQVf

Hive操作库、操作表及数据仓库的简单介绍

数据仓库和数据库 数据库和数仓区别 数据库与数据仓库的区别实际讲的是OLTP与OLAP的区别 操作型处理(数据库)&#xff0c;叫联机事务处理OLTP&#xff08;On-Line Transaction Processing&#xff09;&#xff0c;也可以称面向用户交易的处理系统&#xff0c;它是针对具体业务…

如何选择适合小团队的项目管理工具?免费与开源软件推荐

目录 一、小团队项目管理工具的重要性 二、热门项目管理工具介绍 &#xff08;一&#xff09;禅道 &#xff08;二&#xff09;Trello &#xff08;三&#xff09;Asana &#xff08;四&#xff09;JIRA 三、免费项目管理软件推荐 &#xff08;一&#xff09;ES 管理器 …

kafka如何获取 topic 主题的列表?

大家好&#xff0c;我是锋哥。今天分享关于【kafka如何获取 topic 主题的列表&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; kafka如何获取 topic 主题的列表&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Kafka中&#xff0c;可以…

Maven详解—(详解Maven,包括Maven依赖管理以及声明周期,Maven仓库、idea集成Maven)

文章目录 Maven详解一.初始Maven1.1 概述1.2 作用 二.Maven模型2.1 概述2.2 构建生命周期/阶段2.3 项目对象模型2.4 依赖管理模型 三.Maven仓库四.Maven安装4.1 下载4.2 安装步骤 五.Idea集成Maven Maven详解 一.初始Maven 1.1 概述 Maven是Apache旗下的一个开源项目&#x…

虚拟滚动 - 从基本实现到 Angular CDK

简介 在大数据列表的处理上&#xff0c;虚拟滚动是一种优化性能的有效方式。本篇文章将详细介绍两种常见的虚拟滚动实现方式&#xff1a;使用 transform 属性和 Intersection Observer。重点讲解如何通过 transform 属性实现高效的虚拟滚动&#xff0c;并对比Angular CDK中的实…

Spring Boot 配置文件启动加载顺序

前言 Spring Boot的启动加载顺序是一个涉及多个步骤和组件的过程。Spring Boot通过一系列默认设置简化了应用程序的配置&#xff0c;使得开发者能够快速地搭建和部署应用。为了实现这一目标&#xff0c;Spring Boot采用了一种分层和优先级机制来加载配置文件。 一、Spring Bo…

C# Modbus RTU通讯回顾

涉及技术&#xff1a; 1.使用NMdbus4 库 2.ushort[]转int 记得之前刚学习的时候&#xff0c;是ushort[] → Hex字符串→byte[] → 翻转byte[] →BitConverter.ToInt32()&#xff0c;饶了一大圈&#xff1b;实际上可以直接转&#xff1b;这里也有小细节&#xff1a;使用BitCo…

HFSS学习笔记(五)金属过孔、复制模型带激励等问题(持续更新...)

HFSS学习笔记&#xff08;五&#xff09;金属过孔、复制模型带激励等问题&#xff08;持续更新…&#xff09; 一、金属过孔设计 方法一&#xff1a;用介质减去金属圆柱体&#xff0c;然后再添加金属圆柱体 方法二&#xff1a;嵌入金属圆柱 圆柱过孔选择材料为“copper” HFS…

Late Chunking×Milvus:如何提高RAG准确率

01. 背景 在RAG应用开发中&#xff0c;第一步就是对于文档进行chunking&#xff08;分块&#xff09;&#xff0c;高效的文档分块&#xff0c;可以有效的提高后续的召回内容的准确性。而对于如何高效的分块是个讨论的热点&#xff0c;有诸如固定大小分块&#xff0c;随机大小分…

大屏可视化:舞动数据与美观的“设计秘籍”

大屏可视化鉴赏&#xff1a;踏入软件系统产品设计之旅&#xff0c;让我们一同鉴赏那些闪耀在智慧农业、智慧园区、智慧社区及智慧港口等领域的大屏可视化杰作。每一帧画面&#xff0c;都是科技与创新的完美融合&#xff0c;数据跃然屏上&#xff0c;智慧触手可及。 >> 数…

基于STM32的智能声音跟随小车设计

引言 本项目基于STM32微控制器设计了一个智能声音跟随小车&#xff0c;通过集成麦克风阵列实现声音源定位和跟随功能。该系统可以检测环境中的声音信号&#xff0c;如手掌拍击声或语音指令&#xff0c;驱动小车向声源方向移动。项目涉及硬件设计、声音信号处理算法以及电机控制…

Bruno解决SSL验证问题

在测试接口的时候&#xff0c;我使用的是Bruno这个软件&#xff0c;开源离线的API测试软件。 主页是这样子的 今天在测试一个HTTPS的接口时候&#xff0c;因为这个HTTPS接口是用的是自签证书&#xff0c;所以就报错误了。 Error invoking remote method send-http-request: …

【论文速读】| APOLLO:一种基于 GPT 的用于检测钓鱼邮件并生成警告用户的解释的工具

基本信息 原文标题&#xff1a;APOLLO: A GPT-based tool to detect phishing emails and generate explanations that warn users 原文作者&#xff1a;Giuseppe Desolda, Francesco Greco, Luca Vigan 作者单位&#xff1a;University of Bari “A. Moro”, Italy, King’…