相机成像之图像传感器与ISP【四】
文章目录
- 1、图像传感器基础
- 1.1 基础原理——光电效应
- 1.2 基础的图像传感器设计
- 1.3 衡量传感器效率的一个关键指标:光量子效率(QE)
- 1.4 感光单元的响应
- 1.5 像素的满阱容量
- 1.6 像素尺寸和填充比例
- 1.7 微透镜的作用
- 1.8 光学低通滤波器简介
- 1.9 传感器尺寸
- 1.10 模拟前端
- 1.11 Vignetting——渐晕
- 1.12 图像传感器的作用流程小结
- 2、颜色基础
- 2.1 颜色是人类感知的产物
- 2.2 光谱功率分布 (Spectral Power Distribution - SPD)
- 2.3 光谱灵敏度函数 (Spectral Sensitivity Function - SSF)
- 2.4 人眼的光谱灵敏度函数
- 2.5 颜色滤波阵列 - Color filter arrays (CFA)
- 2.6 每种相机有不同的光谱灵敏度函数
- 2.7 思考:你能想到其他捕捉颜色的方法吗?
- 2.8 图像传感器的作用流程小结
- 3、相机内的图像处理(ISP)
- 3.1 相机内图像处理的流程
- 3.2 白平衡基础
- 3.3 去马赛克
- 3.4 去噪
- 3.5 如何去除噪声
- 3.6 色调重建
- 4、相机内图像处理小结
- 4.1 我们真的需要RAW格式图像吗?
- 4.2 如何方便的获取RAW格式图像?
- 4.3 有很多开源系统在改变这一情况
- 4.4 总结
数码摄影的基础流程:
1、图像传感器基础
现代数字图像传感器已经非常复杂,涉及到半导体等知识,所以我们在本课中只能涉及基础,
什么是数字图像传感器?
下图中的“桶”就是像素阵列,
整个拍照过程如下,快门打开,曝光开始,由像素阵列(桶)持续接收这些光子直到曝光结束,曝光结束后,传感器将这些光子转换为数字信号,
1.1 基础原理——光电效应
1.2 基础的图像传感器设计
术语“感光器件(photosite)”可以用于指代整个像素,也可以仅指感光区域。
1.3 衡量传感器效率的一个关键指标:光量子效率(QE)
1.4 感光单元的响应
感光单元的响应几乎是线性的
- 当势阱饱和时会产生非线性的响应 (过曝)
- 当接近0时也产生非线性响应 (因为噪声的原因)
我们可以通过HDR成像来解决这种问题,
1.5 像素的满阱容量
- 满阱容量:在饱和前势阱容纳的电子的数量,是成像传感器的另外一个重要的性能指标,
- 满阱容量并不是越大越好,因为满阱容量越大则需要的像素尺寸也越大,
- 满阱容量越大,则能提高信噪比和动态范围(更广的亮度范围),动态范围是指一幅图像的传感器能同时捕获并显示最暗和最亮的能力,
1.6 像素尺寸和填充比例
1.7 微透镜的作用
- 将光线汇聚到感光像素区域来帮助感光器件收集更多的光线
- 提升有效填充因子
- 通过实现像素大小的2D Box滤波器对图像进行空间低通滤波,以防止混叠伪影
- 有时还会在传感器前面放置一个附加的光学低通滤波器(OLPF),以改进前置滤波效果
如下右图下面的图像传感器中的微透镜和感光器件有一个斜移,是为了使光线更好地被感光器件接收,
什么是混叠伪影,如下右图灰色衬衫上的波纹(又叫摩尔纹)就是混叠伪影,
混叠伪影的原因:
图像传感器不足以处理高频信息
有2种方法可以防止混叠伪影:
1、通过实现像素大小的2D Box滤波器对图像进行空间低通滤波,以防止混叠伪影
2、有时还会在传感器前面放置一个附加的光学低通滤波器(OLPF),以改进前置滤波效果
更多参考:了解什么叫混叠伪影:5. 数码相机内的图像处理-图像采样与金字塔
1.8 光学低通滤波器简介
- 在许多传感器前面,通常会有一块作为OLPF的玻璃片,也被称为光学抗混叠滤波器,
OLPF通常由两层双折射材料和红外滤波器组成。- 光线具有不同的振动方向,进入如下图左一的晶体后,就会分成不同的方向(振动方向不同)进行传播,所以会造成字的重影,
- 然而,OLPF意味着降低分辨率,因为高频信号被滤除了
- 随着现在像素数量变大,OLPF变得不再是必要的。所以摄影师经常破解他们的相机来移除OLPF,以避免分辨率的损失
- 也有相机制造商提供带和不带OLPF的相机版本
- 同时,OLPF在处理相干光(杂散条纹)时也可能存在问题
需要用到OLPF的场景,
不必要用OLPF的场景,
1.9 传感器尺寸
两种主要的图像传感器,现在主要使用CMOS,CCD逐渐退出历史舞台,
两类传感器的伪影现象,
传感器泛光是一个像素在图像传感器上接收过多的光子导致的,也会溢出到相邻的像素里面去,涂抹伪影发生在CCD中,因为CCD是逐行读取,速度相对较慢,对于移动的物体或快速变化的光线就会在图像中留下“痕迹”,
CCD和CMOS的更多区别,
CMOS传感器简图,
1.10 模拟前端
1.11 Vignetting——渐晕
远离中心的像素接收到的光较少,
四种渐晕产生的原因:
• 机械原因: 光线被遮光罩、过滤器和其他物体阻挡
• 镜头原因:类似,但光线被镜头元件阻挡
• 自然原因:由于辐射定律(“余弦四次衰减”)。
• 像素原因:感光元件的角度相关灵敏度。
1.12 图像传感器的作用流程小结
当相机快门打开时,传感器:
- 在每个像素,将入射光子转换为电子
- 在未饱和时将电子存储到光点的势阱中
直到相机快门关闭。 然后,模拟前端:
- 逐行读出感光点的电子,并将其转换为模拟信号
- 对这些模拟信号应用(可能不均匀)增益
- 将它们转换为数字信号
- 纠正非线性
- 最后返回图像。
2、颜色基础
2.1 颜色是人类感知的产物
“颜色”不是光(电磁辐射)的客观物理属性,波长才是,
2.2 光谱功率分布 (Spectral Power Distribution - SPD)
- 大多数类型的光由多种波长的光组成
- 我们可以根据不同波长上的功率分布来描述光
2.3 光谱灵敏度函数 (Spectral Sensitivity Function - SSF)
- 任何光传感器(数字或非数字)对不同波长都有不同的灵敏度。
- 这是通过传感器的光谱灵敏度函数来描述的𝑓(𝜆)
- 当测量某个 SPD为𝜙(𝜆)的光时,传感器会产生标量响应
2.4 人眼的光谱灵敏度函数
- 人眼包含所谓视锥细胞的光传感器的集合
- 有三类具有不同光谱灵敏度的细胞
- 人类的颜色感知是三维的(三原色)
2.5 颜色滤波阵列 - Color filter arrays (CFA)
- CFA使得数字图像传感器可以模仿人类视觉系统的视锥细胞来感知颜色
- 不同颜色的滤波器有不同的光谱灵敏度函数,模拟不同的视锥细胞
CFA的两种设计考虑:
- 对每种颜色滤波器采用什么样的光谱灵敏度函数f(λ)
- 如何在空间中排布不同的颜色滤波器(Mosaic – 马赛克)
不同的CFA马赛克排布:
2.6 每种相机有不同的光谱灵敏度函数
每台相机或多或少都有其独特的SSF,而且大多数时候被相机厂商保密,这使得正确再现传感器测量的颜色变得非常困难,
2.7 思考:你能想到其他捕捉颜色的方法吗?
2.8 图像传感器的作用流程小结
3、相机内的图像处理(ISP)
3.1 相机内图像处理的流程
相机图像信号处理器 (Image Signal Processor - ISP) 应用一系列图像处理操作,将 RAW 图像转换为“传统”图像。
3.2 白平衡基础
人类视觉系统具有色度适应性(chromatic adaptation):
- 在不同的光源下,我们可以正确地感知白色(和其他颜色)
- 但相机不行——相机是没有感知
如下图中的下图,虽然在这个光源下,我们看到的颜色和在上图看到的颜色是一致的,
白平衡:让我们感知到的白色在最终的图像中也渲染为白色的方法,
相机预置的白平衡设置:
如今的相机有大量的预设白平衡设置:你可以选择在哪种光线下拍摄图像,并应用相应白平衡,
摄影时的手动和自动白平衡:
手动白平衡:
- 根据照明情况选择相机上的白平衡设置,
- 手动选择照片中颜色中性的对象,并使用它进行对图像的颜色进行归一化,
自动白平衡:
- 灰色世界假设:强制场景的平均颜色为灰色
- 白色世界假设:强制场景中最亮的物体为白色
- 复杂的基于直方图的算法(大多数现代相机都是这样做的)
灰色世界假设:
- 计算每个通道的平均值
- 通过平均值对每个通道进行规格化
- 通过绿色通道平均值进行归一化
白世界假设:
- 计算每个通道的最大值
- 按每个通道的最大值规格化每个通道
- 按绿色通道最大值规格化
自动白平衡示例:
3.3 去马赛克
相机图像信号处理器 (Image Signal Processor - ISP) 应用一系列图像处理操作,将 RAW 图像转换为“传统”图像。
CFA(颜色滤波阵列)去马赛克:
从马赛克传感器输出中生成完整的RGB图像,需要借助邻域插值,
双线性插值去马赛克:
双线性插值:只需求4个邻域像素的平均值。
不同通道的邻域不一致,
3.4 去噪
相机图像信号处理器 (Image Signal Processor - ISP) 应用一系列图像处理操作,将 RAW 图像转换为“传统”图像
图像中的噪声:
在低光照下噪声特别明显,也就是势阱未装满光子,
几种传感器的噪声:
(1) 散粒噪声:光子到达率是一个随机过程(泊松分布),场景越亮,分布的方差就越大。
(2) 暗噪声:由于热活动而发射的电子(随着传感器越来越热而变得更糟)
(3) 读取噪声:由电子设备(例如增益、A/D转换器)引起。在明亮的场景和以及大像素传感器:散粒噪声是主要的噪声源,
参考资料:
https://zhuanlan.zhihu.com/p/397873289
3.5 如何去除噪声
邻域插值(与去马赛克类似),
3.6 色调重建
人眼感知亮度与测量亮度是有区别的,下图中“视网膜颜色”是眼睛感知到的颜色,“感知颜色”是大脑处理后的颜色,
- 我们已经看到传感器响应是线性的,人眼的响应也是线性的(测量亮度),
- 然而视觉感知,也就是大脑(感知亮度)是非线性的:我们对深色调更敏感,近似一个 γ \gamma γ 函数,
- 下图中,Eyes实际上是大脑感知的颜色,
Gamma编码:
色调重建也可以是Gamma编码的过程,我们的目标是使用少量的比特位来压缩编码图像的亮度信息,比如从12位压缩到8位应用非线性曲线可以更好地编码人类视觉更敏感的信息,
下图中,横坐标是实际亮度,纵坐标是感知到的亮度,
Gamma编码 vs 线性编码 —— 一个简化的例子
- 使用线性编码(5比特,32阶)会把人眼就能区分的亮度差异变成一个亮度,也会把人眼看不出明显差别的亮度变成有亮度差异,所以线性编码有较大的缺点,
- 而采用Gamma编码会在感知上更加平滑,
色调重建流程:
通过Gamma编码和Gamma校正得到的净效应还是线性曲线,
- 真实场景是线性的,经过人的大脑对线性场景的非线性响应,最终感知到的图就是下图左一,
- 经过相机Gamma编码,人眼看到的图片就是下图左二,
- 相机Gamma编码后,再经过Gamma校正,就得到显示器正常显示的图像,如下图右一,
如果没有Gamma编码会如何?
Gamma编码的历史缘故
- CRT显示器过去的响应曲线(几乎)完全等于人类灵敏度曲线的倒数。因此,CRT显示器可以跳过Gamma校正并直接显示Gamma编码的图像,
- 反过来说,以前在CRT显示器时代,我们执行Gamma编码的一个重要目的是抵消显示器的响应曲线。但在液晶显示器时代就不是了——我们现在依旧执行Gamma编码的原因就是确保最终图像的8个比特在感知上更加均匀,
Gamma编码曲线
确切的gamma编码曲线取决于相机制造厂商的设定,
可以近似的用Lγ描述,而不同设定的γ值不同,比较好的默认值是 γ = 1 / 2.2 \gamma=1/2.2 γ=1/2.2,
重要:Gamma编码后亮度值和场景的辐照度之间不再是线性关系,
4、相机内图像处理小结
相机图像信号处理器 (Image Signal Processor - ISP) 应用一系列图像处理操作,将 RAW 图像转换为“传统”图像,
4.1 我们真的需要RAW格式图像吗?
是的!
每次使用基于物理的计算机视觉算法时,都需要对辐射进行线性测量。
例如:光度立体、从阴影到形状、基于图像的重新照明、照明估计、与光传输和反向渲染有关的任何事情等。将算法应用于非线性(即非RAW)图像将产生完全无效的结果。
即便不研究计算机视觉算法,摄影师们也喜欢在RAW格式上进行图像编辑,
存储和处理RAW格式图像的负担,
- 图像巨大,对存储空间占用很大,不管是相机还是电脑都需要大量的存储空间
- 相机本身的处理负担加大,特别是在快速连拍模式
4.2 如何方便的获取RAW格式图像?
- 大多数专业相机、甚至卡片相机都提供存储RAW格式图像的选项
- 一些高端的手机,例如Iphone也提供了存储RAW格式图像的选项
如果拍摄前未设置存储为RAW格式,有办法通过RGB格式逆向得到RAW图像吗?
- 很不幸,你无法简单逆向得到RAW图像
- 图像处理管道是有损的:在所有步骤之后,关于原始图像的信息都会丢失。
- 除非如果我们确切地知道相机流程中各个组件的作用(例如,通过使用来自其他类似RAW图像的信息),我们才有可能反转相机的部分图像处理流程。
- 将PNG/JPG转换回RAW被称为“逆渲染(Derendering)”,这是一个活跃的研究领域。
逆渲染-Derendering
如下图,RAW是最大的几何体(颜色空间),而jpg是最大几何体里面的小的几何体,所以想从jpg还原RAW是较困难的,
我们讲述的相机内图像处理的流程是一个猜测的公有流程
相机图像信号处理器 (Image Signal Processor - ISP) 应用一系列图像处理操作,将 RAW 图像转换为“传统”图像。
实际的ISP流程可能非常复杂,
我们所讲的模拟前端也是一个通用而假设的流程,实际传感器复杂得多
Gamma编码曲线也因相机的不同而有很大变化
这些情况都使得严肃的研究非常困难,在管道的中间阶段很难获得真实数据,很难评估新算法对特定管道阶段的效果,
4.3 有很多开源系统在改变这一情况
- Frankencamera
- Android Camera2 API
- https://github.com/cruxopen/openISP
4.4 总结
照片中的像素值和相机传感器输出的值是两个非常不同的东西,两者之间的关系是复杂而未知的,
参考资料:
基础阅读资料:
- Szeliski, Computer Vision: Algorithms and Applications, Section 2.3. https://szeliski.org/Book/
- Michael Brown, “Understanding the In-Camera Image Processing Pipeline for Computer Vision,” CVPR 2016,
slides available at: http://www.comp.nus.edu.sg/~brown/CVPR2016_Brown.html
进一步阅读资料:
- Adams et al., “The Frankencamera: An Experimental Platform for Computational Photography,” SIGGRAPH 2010.
第一个图像处理管道的开放架构,也是Android Camera API的先驱.- Heide et al., “FlexISP: A Flexible Camera Image Processing Framework,” SIGGRAPH Asia 2014.
讨论如何实现单阶段图像处理管道.- Buckler et al., “Reconfiguring the Imaging Pipeline for Computer Vision,” ICCV 2017.
- Diamond et al., “Dirty Pixels: Optimizing Image Classification Architectures for Raw Sensor Data,” arXiv 2017.
这两篇论文都讨论了如何自适应地改变传统的图像处理流程,使其更好地适应各种计算机视觉问题.- Chakrabarti et al., “Rethinking Color Cameras,” ICCP 2014.
讨论不同的 CFA,包括具有白色滤镜的 CFA,以及如何对其进行去马赛克.
-Gunturk et al., “Demosaicking: Color Filter Array Interpolation,” IEEE Signal Processing Magazine 2005
对去马赛克算法的精彩回顾.- Kim et al., “A New In-Camera Imaging Model for Color Computer Vision and Its Application,” PAMI 2012.
- Chakrabarti et al., “Probabilistic Derendering of Camera Tone-mapped Images,” PAMI 2014.
两篇论文详细讨论了如何建模和校准图像处理管道、如何渲染已经通过管道的图像以及如何在不同相机的管道下重新渲染图像
相关文章:

相机成像之图像传感器与ISP【四】
文章目录 1、图像传感器基础1.1 基础原理——光电效应1.2 基础的图像传感器设计1.3 衡量传感器效率的一个关键指标:光量子效率(QE)1.4 感光单元的响应1.5 像素的满阱容量1.6 像素尺寸和填充比例1.7 微透镜的作用1.8 光学低通滤波器简介1.9 传…...

新手入门Java 方法带参,方法重载及面向对象和面向过程的区别介绍
第二章 方法带参 课前回顾 1.描述类和对象的关系 类是一组对象的共有特征和行为的描述。对象是类的其中一个具体的成员。 2.如何创建对象 类名 对象名 new 类名();3.如何定义和调用方法 public void 方法名(){}对象名.方法名();4.成员变量和局部变量的区别 成员变量有初…...
使用Sqoop将Hive数据导出到TiDB
关系型数据库与大数据平台之间的数据传输之前写过一些 使用Sqoop将数据在HDFS与MySQL互导 使用Sqoop将SQL Server视图中数据导入Hive 使用DataX将Hive与MySQL中的表互导 使用Sqoop将Hive数据导出到TiDB虽然没写过,但网上一堆写的,那为什么我要专门写一下…...

互联网上门洗衣洗鞋工厂系统搭建;
随着移动互联网的普及,人们越来越依赖手机应用程序来解决生活中的各种问题。通过手机预约服务、购买商品、获取信息已经成为一种生活习惯。因此,开发一款上门洗鞋小程序,可以满足消费者对于方便、快捷、专业的洗鞋服务的需求,同时…...
Redis面试题12
Redis 的主从复制是什么? Redis 的主从复制是一种数据备份和高可用性机制,通过将一个 Redis 服务器的数据复制到其他 Redis 从服务器上来实现数据的冗余备份和读写分离。 主从复制的工作原理如下: 配置主服务器并开启主从复制功能。从服务器…...

el-tree多个树进行节点同步联动(完整版)
2024.1.11今天我学习了如何对多个el-tree树进行相同节点的联动效果,如图: 这边有两棵树,我们发现第一个树和第二个树之间会有重复的指标,当我们选中第一个树的指标,我们希望第二个树如果也有重复的指标也能进行勾选上&…...
python两个字典合并,两个list合并
1.两个字典: a{‘a’:1,‘b’:2,‘c’:3} b {‘aa’:11,‘bb’:22,‘cc’:33} 合并1:dict(a, **b) 结果:{‘a’: 1,‘aa’: 11,‘c’: 3,‘b’: 2,‘bb’: 22,‘cc’: 33} 合并2:dict(a.items()b.items()) 结果:{‘…...

搜维尔科技:【简报】元宇宙数字人赛道,《全息影像技术应用》!
期待着看展的主角来到今天要参观的全息影像展,平时就喜欢看展的她对于所谓的全息影像非常好奇,于是她带着期待的心情进入展内。进入展内的主角看到的是与之前完全不同的画展,每幅画看起来就像真的一样,充满好奇的她在展览的各处游…...
SparkSQL和Hive语法差异
SparkSQL和Hive语法差异 1、仅支持Hive SparkSQL关联条件on不支持函数rand()创建零时表时,Spark不支持直接赋值nullSpark无法读取字段类型为void的表SparkSQL中如果表达式没有指定别名,SparkSQL会将整个表达式作为别名,如果表达式中包含特殊…...
XCODE IOS 静态链接库替换升级
XCODE 版本15.2. 一个很久需求没更新的IOS 应用,近来有新需求要开发。 拉下代码运行,出现了个BAD_ACCESS错误。出错的位置位于一个调用的第三方的.a静态库内部。因为调用代码并没有修改,很容易想到可能XCODE相关升级,导致的问题。…...

API设计:从基础到优秀实践
在这次深入探讨中,我们将深入了解API设计,从基础知识开始,逐步进阶到定义出色API的最佳实践。 作为开发者,你可能对许多这些概念很熟悉,但我将提供详细的解释,以加深你的理解。 API设计:电子商…...
路由的安装顺序
安装前端路由的顺序通常如下: 安装前端框架:选择并安装适合你的项目的前端框架,如React、Vue或Angular等。 创建路由配置文件:在项目根目录下创建一个路由配置文件,比如router.js或routes.js等,用于定义路…...
华为OD机试真题-围棋的气--Java-OD统一考试(C卷)
题目描述: 围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19x19=361个交点,对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。 “气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相邻的交叉点中,有几个交叉点没有棋子,由此可知: …...

CANFD数据记录仪在新能源汽车复杂路测下的应用
CANFD数据记录仪在新能源汽车复杂路测下的应用 汽车制造商在生产预批量阶段的耐久性测试中,为了检测潜在故障,必须让车辆在严酷的路况和环境下接受测试。为确保能回溯故障发生的现场情况,我们需要对测试数据精准记录与储存。这些数据是新车型优化迭代的关键,也是确保产品质量的…...

java: 5-6 break
文章目录 1. break1.1 介绍1.2 语法和流程图1.3 入门练习1.4 细节说明1.5 练习 【老韩视频p137-】 1. break 看个需求:随机生成 1-100 的一个数,直到生成了 97 这个数,看看你一共用了几次? 【思路分析:循环,但是循环的次数不知道…...

如何使用Imagewheel搭建一个简单的的私人图床无公网ip也能访问
文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…...
响应式编程Reactor API大全(上)
Reactor 是一个基于响应式编程的库,主要用于构建异步和事件驱动的应用程序。Reactor 提供了丰富的 API,包括创建、转换、过滤、组合等操作符,用于处理异步数据流。以下是一些 Reactor 的主要 API 示例: pom依赖 <dependencyMan…...
vue3自定义指令
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。 页面内创建自定义指令 下面是一个自定义指令的例子,当一个 input 元素被 Vue 插入到 DOM 中后,它会被自动聚焦: <script setu…...

ECharts 多季度连续显示到一个图中。
效果图 二.相关option 以下option可以复制到 echarts的编辑器 进行查看修改 const site test1; const site2 test2;const qtrlyOption function (data: any, titleText: string): any {//获取最大值 。最大最小值的目的是:使左右里边的所有bar使用同一个指标let …...
【Microsoft Copilot】手机端发布 ——GPT-4, DALL-E3 免费用
Microsoft Copilot 关于Microsoft CopilotMicrosoft Copilot 的特点1. 可以在手机端使用:2. 可以免费使用GPT-4。3. 可以无限制地使用GPT-4。4. 可以使用DALL-E3生成图片。5. 搜索功能6. 图像识别 Microsoft Copilot的缺点和注意事项1. 非常容易报错2. 不支持长篇聊…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...