0%

3A算法

3A技术即自动对焦(AF)、自动曝光(AE)和自动白平衡(AWB),3A数字成像技术利用了AF、AE、AWB算法实现图像对比度最大、改善目标拍摄物过曝光或曝光不足情况,使画面在不同光线照射下的色差得到补偿,从而呈现较高画质的图像信息。

自动对焦AF

计算当前图像的对比度,然后调整焦距,最终使得图像的对比度最大。这里对合适的焦距可以采用 爬山法 搜索。因为一开始你并不知道当前焦距下成像是最清晰的,那么爬山法的原理和梯度下降有点类似。搜索当前点领域空间的点,选其中反馈最大的位置作为下一步迭代的点。即不断往上“怕山”,直到遇到局部最优值,即领域的值都比它差。

那么自动对焦算法中有两个关键步骤

  • 图像清晰度评价指标:图像熵,灰度方差,拉普拉斯梯度和,变分损失等
  • 搜索算法: 上述的爬山法的 优点是 避免了全局搜索,效率高。 但是会陷入局部最优,一个替代的方法是 模拟退火法。他的思路是当找到局部最优值后,以一定的概率接受往周围稍差的值前进,即以一定概率接受走下坡路,但是这个概率是越来越低的,直至收敛。因此这样就可能跳出局部最优值,而搜索到更好的结果。

自动曝光AE

一般的自动曝光算法通过获取图像的亮度调节相应的曝光参数,得到合适的曝光量。曝光参数包括光圈大小, 快门速度和摄像头传感器的亮度增益。

获取图像亮度,可采用的方法有:

  1. 平均亮度
  2. 分区域加权平均,可以将关注区域集中在屏幕某个具体位置 或者具体对象
  3. 直方图信息等
  4. 设置不同的亮度文献,对背光、正光和强光进行区分

调整参数的主要方法:

  1. 查表法:系统内部可能预先存储了一张曝光参数的调整步长与图像亮度之间的关系查找表,根据当前的亮度去获取调整值,使得图像亮度接近期望值。
  2. 迭代法:
  3. 数值计算法

自动白平衡AWB

白平衡,这是和光源的色温息息相关的概念。例如 早期的灯泡,都是光色的暖光源,在暖光源下成像的整体颜色就偏黄,白炽灯是冷色光源,成像效果就偏蓝。为了使得成像效果不受光源色温影响,尽可能还原出场景的本身颜色,就有了自动白平衡算法。

常用的白平衡算法有以下两种:

  1. 选白点算法:所谓白点就是图像中原本应该是白色的点。白点算法就是首先找到图像中 可能的 “白色的点”,然后将白色点矫正会去RGB={255,255,255},以此为标准,就能知道变换矩阵将其他颜色的像素点都还原回去。这里的 可能的白点 是选的图像中 RGB 值和最大的点,这个最大的也是一个阈值。
  2. 灰度世界假设:类似上面的白点算法。灰度世界原理是,对于一个丰富的场景的图,它全图 R G B 三通道的均值应该接近,基于此就可以算出各个通道的变换倍数。
  3. 色温估计:这个算法原理是,预先在不同的光源下,记录一个合适的校准值保存。在测试的时候,先根据图像估算色温,然后去查表找到当前色温的校准值。至于如何估计色温,可以将图像分块,然后针对每个块做一个白点的计算,得到色温估算。

ISP

安卓相机处理流程

参考链接

ISP 图像信号处理器,用于处理图像传感器的原始数据。它首先是一个处理器,然后由运行在其上的软件来控制整个ISP流程。软件结构按照层级可以划分为如下三层,分别为 顶层的 ISP控制逻辑, 3A算法库,传感器控制库 和 基础ISP算法。如下图所示。

image-20210608223056771

  • SENSOR 3A:我理解为控制相机硬件的库,例如控制相机的快门,光圈大小等,因此它服务于 3A库,3A算法需要根据当前图像的统计信息反馈来调整这些硬件参数。
  • SENSOR ISP:其他的一些算法库,例如 黑电平矫正,黑点矫正等算法
  • 3A LIB:就是上面介绍的3A算法
  • ISP CTRL:整个 ISP 的控制逻辑,从传感器读取数据,然后通过回调函数调用底层的ISP算法,完成整个ISP的流程,然后输出图像,同时还负责处理外部用户通过IIC / SPI 等输入的控制指令。

image-20210608215513588

常规的步骤可以 以 3A 算法作为依据划分为算个阶段。因为其实 白平衡 亮度 和 焦距 他们存在依赖关系。因此需要有序调整。从上图可以大致看出,先自动调整白平衡,然后自动调整曝光,最后自动对焦

黑电平矫正

由于传感器存在漏电流,当全黑时成的像由于漏电流的存在而不是全黑的,减去偏移值即可

镜头阴影矫正

或者叫非均匀矫正,镜头中央进光比较均匀,四周少,表现就是纯色场景 四周有暗角。这也是相机的固有缺陷,可以实现矫正

坏点矫正

相机传感器难免有一些成像单元损坏,会导致最后的图像有一些坏点。找坏点,做中值滤波即可

颜色插值

相机的成像元件是按照 拜尔排列,和屏幕的显示彩色图像一样,他是红绿蓝三个颜色滤镜分别采集RGB信号,因此输出的图像也就是 RawRGB格式,那么就需要对R G B 三通道都进行颜色插值,

image-20210608215036384image-20210608215107199

去噪

对图像传统的去噪方法 ….

颜色矫正

  • RGB: 是一种均匀性较差的颜色空间,人眼对于三个颜色分量的敏感程度是不一样的,如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。在RGB颜色系统中,三个颜色分量之间是高度相关的,即只要亮度改变,三个分量都会相应的改变,如果一个颜色的某一个分量发生了一定程度的改变,那么这颜色很可能也要发生改变。
  • HSI:用色调(Hue)、饱和度(Saturation或Chroma)和亮度(Intensity或Brightness)来描述颜色。 I 分量与颜色信息无关,H和S分量与人感受彩色的方式相似,彩色图像中的每一个均匀性彩色区域都对应一个相一致的色度和饱和度,色度和饱和度能够被用来进行独立于亮度的彩色区域分割。
  • YUV:Y就是常说的灰度

gamma矫正

人眼对亮度的敏感度不是线性变化的,在低照度下 人眼对亮度变化敏感,在高亮度下人眼对亮度变化没那么敏感,因此使用gamma矫正对输入图像的灰度做一个非线性操作,拉伸低亮度的值,压缩高亮度的像素值

色彩空间转换

了解一下常用的色彩空间和运用

彩色去噪

图像分割

简单了解一下传统图像分割中常用的两个算法

OSTU

大津法自适应图像二值化方法。自适应的计算二值化的分割阈值。他的原理是:将图像发为前景和背景区域,大于阈值的为前景,小于阈值的背景。设置某个阈值,计算前景区域的像素均值w1 背景区域的像素均值 w2 以及全图的像素均值 w ,期望 w 和 w1 w2 的方差最大,即类间方差最大化的分割阈值即为所求。

标记分水岭

相机响应模型

这是在阅读下面这个文献是遇到的概念

A New Low-Light Image Enhancement Algorithm using Camera Response Model ∗

相机响应曲线

首先,物体在反射光进入相机后,相机成像具有一个响应曲线,理论上响应曲线应该是对不同波段不同强度的光能线性还原。但是实际为一个S曲线,例如下图所示:

image-20210606215822976

横坐标为 实际的进入相机的亮度,而纵坐标代表感光元件量化后的像素值强度,例如纵坐标为50就代表成像后的像素值为0.5x255…同时上图中 ISO 的调节可以将相机响应曲线平移,但是并不能改变相机响应曲线的形状。在x轴上平移就使得相机对不同的输入光强更敏感。ISO(感光度)

因此相机响应函数就是指的上面这个曲线

ISO 控制传感器自身对亮度的感知范围,而 快门+光圈 = 曝光,快门控制进光时间,光圈代表进光的窗口大小

方法

LIME以及其他使用Retinex分解的方法中,都认为 I = V X R 这个 V 是图像的亮度(或者叫曝光,曝光本质就是进入摄像机的总的光量),但其实更准确的说,这个 V 应该是物体反射后的光的强度。但是经过成像后,是有个相机响应模型的后处理,因此 这篇文章中认为 I = f(V) x R => R = I / f(V) => 其中V使用和LIME中类似的估计。而 f 函数是相机的响应曲线,对于固定的相机,这个响应曲线应该是固定的,因此在 一个数据集上 去 标定相机响应曲线的参数即可。

那么增强的步骤就是:估计 亮度 V 带入抑制的相机响应模型对图像提亮

(具体公式还得详细推导)

拉普拉斯融合

参考链接

  1. 为什么在处理高斯金字塔的时候需要采用滤波呢,直接下采样不可以吗? 如果把图像看做频率信号的话,直接进行下采样则会出现采样不足的情况,消除这种情况的方法是采用低通滤波器(高斯滤波器)对图像进行滤波,将采样不足的高频信号过滤掉,这样在进行下采样的时候就保证了不出现采样不足的情况。
  2. 拉普拉斯金字塔的理解? 拉普拉斯金字塔可以看做一个带通滤波器,在每一级都保留了图像某个频率值附近的成分。(这一点与高斯金字塔不同,高斯金字塔是低通金字塔)两个低通滤波器的差值就构成了一个带通滤波器。高斯金字塔构建过程中的 低通 +下采样必然会丢失部分频率的信息,因此通过高斯金字塔可以记录丢失的信息,所以高斯金字塔可以用于图像的还原

image-20210606222607987

拉普拉斯算子

其实拉普拉斯算子就是一个二阶微分算子,可用于图像锐化,因为二阶微分可以检测出图像的突变边缘,用于图像锐化,而不是缓变边缘。拉普拉斯算子在泊松融合中也有应用。

拉普拉斯融合

融合的方法使用的拉普拉斯金字塔融合的方式。

  1. 首先对每张图像分别构建 高斯金字塔 和 拉普拉斯金字塔。

  2. 高斯金字塔 构建过程就是 模糊 + 下采样 => 高一层的图像。

  3. 拉普拉斯金字塔构建的方法是,将步骤2的高斯图再上采样 + 模糊 ,这样相对原始没 模糊下采样的图 肯定有信息损失。拉普拉金子塔就是保存这个残差。即 原图 - 模糊上采样后的结果 4. 按照上述方法可知,高斯金字 N 那么拉普拉斯金字塔就是 N-1。需要保留高斯金子塔最顶层的图像,后面用于恢复。

  4. 融合就是,将每张图的金子塔的同一层 拉普拉斯结果融合,加权系数为 他们对应的 高斯金子塔的值。整个过程就看作每张图相同层的拉普拉斯加权平均吧,权重是高斯金子塔的值。最顶层的就直接是 高斯图的平均。

  5. 按照5最后获得的结果就是,除了最顶层是 高斯图,其他层都是拉普拉斯,将高斯 上采样+模糊+拉普拉斯 即可恢复

    image-20201223210726030

其他融合方法

图像融合

传统去噪算法

image-20210606193900333

图像噪声

噪声种类

图像噪声

  • 高斯白噪声:分布符合高斯分布的噪声,功率谱密度服从均匀分布,类似于白光中包含了可见光中所有频率 并且在各个频率上的功率谱密度都是一样的。高斯白噪声与光强无关,无论何时噪声的平均水平都是0。
  • 泊松噪声(散粒噪声):符合泊松分布的噪声模型。泊松噪声随着光强增大,平均噪声也增大,但是信噪比其实随着光强增大而增大了的。
  • 椒盐噪声:椒盐噪声主要来自于传输介质和记录设备不完善等导致。
  • 乘性噪声:乘性噪声一般由信道不理想引起,它们与信号的关系是相乘,信号在它在,信号不在他也就不在。

泊松分布适合于描述单位时间内随机事件发生的次数的概率分布,如某一服务设施在一定时间内受到的服务请求的次数。因为光是由离散的光子构成(光的粒子性),到达光电检测器表面的量子数目存在统计涨落,因此,图像监测具有颗粒性,这种颗粒性造成了图像对比度的变小以及对图像细节信息的遮盖,我们对这种因为光量子而造成的测量不确定性成为图像的泊松噪声

image-20210701112412122

高斯白噪声

通常讨论的高斯白噪声是 加性 高斯白噪声(AWGN ),它有如下几个特点:

  1. 加性
  2. 高斯
  3. 白噪声:功率谱密度服从均匀分布,类似于白光中包含了可见光中所有频率 并且在各个频率上的功率谱密度都是一样的。

加性噪声有一个很重要的性质:

每个像素点的噪声 在 空域 和 时域都是独立无关的,即当前像素的噪声值,和它领域的像素的噪声值 是无关的变量。在时域是指,同一个像素位置,不同时间拍的照,噪声强度也是相互独立的。

image-20210630214759894
image-20210630215237457

其中 u 为干净的图像,n 为高斯白噪声。常用的均值滤波的方法,是多个像素点取平均,每个像素的噪声是独立无关的,加入这几个像素的 u(x) 都一样,即是相似像素。那么 多个像素值取平均 后 分布变为:

image-20210630215244594

如果 u(xi) 是常数,那么加权平均后的 u(x) 不变;对于第二项,噪声的方差明显成比例的缩小。 例如 一个噪声分布 nx(0, 1) ny(0,1) 对他俩加权平均 0.5 x nx 之后 分布变为 nx(0, 0.5^2) ny(0, 0.5^2) 两个乘系数后的分布再求和 n(0, 0.5^2 + 0.5^2) = n(0, 0.5) 所以均值后方差缩小了很多,就得到更干净的图像。

上述理论也是 目前各种 空域去噪方法 例如 均值滤波,高斯滤波, 非局部均值去噪 的理论基础。

像素取均值可以使高斯噪声方差成比例的缩小,但是上述推导中 是假设 加权的像素原始灰度值一致,最后均值滤波后才能保证 不改变原有信号,同时使得噪声的方差成比例缩小。但是 领域的均值像素他们原始的 u(x)不一定相似,所以均值滤波一定成度上也会使得原图的纹理和边缘模糊,便有了以下方法的改进来尽可能保留细节。

高斯滤波对领域像素加上了权重来避免过多的模糊原始的信息

非局部均值滤波,根据相似块的相似度来加权

双边滤波同时考虑空域和值域相似性,所以它的细节保留效果更好

多帧去噪方法则利用了噪声时域上的独立性,同时如果帧之间像素完全对齐,那么这种完全没有模糊原始细节的问题

变换域去噪

图像频谱图

将图像进行二维傅里叶变换,可以得到图像的频谱图

1
2
3
4
5
6
7
8
9
10
11
12
13
I=imread('C:\Users\10729\Desktop\1.PNG');
I=rgb2gray(I);
I=im2double(I);
% [w, h] = size(I);
% I = ones(w,h) * 0.5; %频谱图中心有个亮点,其他全0
% I = randn(w,h); %高斯噪声的频谱图,也是高斯,即每个频率带所占的比重也是个高斯分布
F=fft2(I);
F=fftshift(F); %% 将0频率点移到中间
F=abs(F);
T=log(F+1); %% 压缩一下,否则直流分量太多

figure;

首先,图像的频谱图实际是和空域图像的梯度大小和方向息息相关。频谱图中心代表 频率为0的直流分量,两个轴一个为 x 方向的频率,一个是 y 方向的频率。但是不存在负频率。我理解的频谱图应该是 中心对称的。距离中心 O 越远代表频率越高,即空域图中梯度越大(离x轴越远代表该方向的频率越大,离y轴越远表示另一方向的频率越大,可以简单理解为 dx dy)。

频谱图的:

  • x, y 轴:代表两个方向的频率(可以理解为两个方向的梯度)

  • 距离轴的距离:中心处为直流分量,距离轴越远表示频率越大

  • x, y 唯一确定了一个频率带

  • 频谱图的像素值大小:代表能量的大小 例如 全 0.1 的图像的频谱图中心直流分量 > 全05的图像的频谱中心直流分量

  • 空域图中 相同频率的像素越多,那么在频谱图中聚集起来能量也会越大。例如 将图像尺寸缩放前后,大图的直流分量幅值更大

image-20210630212324839

高斯白噪声正交变换

结论:高斯白噪声的正交变换(傅里叶变换)任然是高斯白噪声;或者说 高斯白噪声的正交变换系数同样是高斯白噪声

可以做如下试验,取一个含有高斯白噪声的图,把他看作空域图像。对他做傅里叶变换,得到一个频谱图,发现它个变换之前的分布类似。即 上述结论。

直观的理解:对于图像空域像素中每个点,该点的像素值是个符合高斯分布的随机值,它和它领域的点是独立互不相关的,因此它领域的点也是个高斯随机值。那么他俩做差即为图像的梯度,这个差值 = 高斯分布1 - 高斯分布2,所以差值的大小依然服从高斯分布 。而根据频谱图的直观理解,频带 近似于 梯度。高斯图像的梯度幅值是高斯分布,那么可以等同理解为 高斯图的频谱图也是 高斯分布的,即再每个频带上的像素比例是个不确定的比例,它服从同样的高斯分布,只不过变换前后 像素值大小的物理意义变了。详细证明:证明

常用的频域滤波方法

低/高/带通滤波

这个就是利用 频谱图 分离频率的特性,使用一个掩码对 频谱图指定的频带进行过滤。然后反变换,使用高斯高通滤波可以 起到瑞华边缘的作用,高斯低通滤波可以起到模糊的作用

阈值滤波

首先,常规的干净图像,它的频谱图在直流分量应该有较大的幅值。而高斯白噪声的正交变换后的频谱图依然是 同分布的高斯白噪声,例如下图:

image-20210701200050585

叠加有高斯白噪声的图像的频谱图相当于 在 相对原图 在每个频带 又叠加了一个高斯白噪声。但是这个高斯白噪声的幅值分布范围是是在 3 sigma 以内,当噪声sigma较小时,可以采用一个阈值法将频谱图 较低 幅值 的地方直接设置为0,认为这些是噪声对应的频带,但是这样无法去除隐藏在 直流分量中的噪声,所以不彻底。并且当噪声sigma较大时,也会使得 噪声和 部分图像的其他分量混合导致误杀,使图像模糊。

协同滤波

协同滤波其实是在 频域 中利用了 多帧去噪的原理。上述阈值滤波存在的问题是,当噪声幅值较大时,会和边缘细节混合在一起,导致阈值无法区分。协同滤波的关键步骤: 高斯白噪声无论变换几次,依然是同分布的,即幅值不会增大

以一个一维度的原始干净信号(干净图像的某一行为例子)

  1. 干净的原始一维信号正交变换后如左上角图所示,大部分平缓低频信号 (将直流分量置0了,免得影响观察(红线))
  2. 在干净信号上加较大方差的高斯噪声后,噪声在各个频带上的能量都有,且大小可以和干净信号的幅度相当,无法阈值滤除
  3. 取多个这种信号组成一个二维数据,现在原始维度上正交变换,再在新增的叠加维度上正交变换,然后取第一行,在新增维度上正交变换后 直流分量聚集向第一行(这里又是直流分量了,因为叠加的是相同的原始信号,他们在每个频带上的能量分布是一样的),所以在新增维度上正交变换会把每个原始信号的每个频带的能量聚集在第一行。取出此时的第一行显示。
  4. 从上述看出 新增维度得是相似的原始信号,这样他们在对应频带上能量分布才能一致,这样在新增维度变换时,可以将这个一致的能量当作直流信号聚集起来。否则会引入新的高频信息,但是这部分高频信息如果无法和噪声区分就会被滤掉,而噪声无论正交变换几次分布不变,能量不变。这样就拉开了噪声和信号能量之间的差距,再通过阈值即可得到较好的效果
  5. 为什么不直接像素位置取平均呢?如果仅仅是相似的图像块,直接取平均很明显会情况更糟,而且频域取平均和时域取平均没区别。
  6. 协同滤波中相似块的堆叠 其实和 非局部均值滤波思想类似,只不过一个是在时域对相似块的利用,一个在频域利用,后者计算复杂度低很多,但是对细节保留效果不好,因为该算法本身并没有把噪声的方差缩小,而无论我们怎样把低频分量的能量集中,总会有一些细节部分的的能量会被淹没在噪声当中,无法恢复。
image-20210701213302939

维也纳滤波

图像处理-逆滤波和维纳滤波

维纳滤波是在频域中处理图像的一种算法,是一种非常经典的图像增强算法,不仅可以进行图像降噪,还可以消除由于运动等原因带来的图像模糊。运动模糊可以在空域建模为卷积退化,将退化图像变换到频域,可以将 卷积 分解为点乘,然后寻求一个和干净图像的频谱均方差最小的解。将卷积信号设置为 1 即 不存在运动模糊时,就变为单纯的去噪方法,为下式:

image-20210701214422250

对于输入图像的功率普,干净图像的功率谱接近可以近似,噪声的功率谱使用固定方差去生成噪声图然后计算功率谱(所以这就得知道噪声的方差否则去噪效果不好)

从上式直观的看,其实和前面的阈值滤波有点相似,本质上也是对噪声频谱的幅值进行抑制,只不过这个通过优化推导出的是最优解。当某个频带 原始信号能量 远大于 噪声信号能量,那么幅值系数接近于1不抑制。当原始信号能量 远小于 噪声信号能量,系数接近于0,抑制噪声。维纳收缩

同态滤波

图像处理-同态滤波

其实这是一种 频域图像增强方法。低光照图 = 反射分量 x 纹理值 ,反射分量比较平滑对应低频分量,而纹理对应高频。首先取对数 将乘变为加 然后 变换到频域使用 高通滤波 最后 恢复。即可剔除反射分量,提亮。

空域去噪

高斯滤波

高斯滤波可以单独分为 x 方向和 y 方向分别卷积,从而降低计算的复杂度,时域卷积也可以在空域加速

双边滤波

基本原理是 空域距离和像素的值域相似度相结合, 相对高斯滤波是一种保边滤波,但是会有梯度反转的卡通效应。并且运算量大,但是有加速算法

引导滤波

基本原理有两点,首先输出假设为输入图像的局部窗口的线性表示,其次是设定一个指导图像。最终优化输出图像和指导图像的 L2 损失,是个凸优化问题。最终的效果就是 在局部高方差的区域 不平滑,在低方差的区域做均值。当指导图像为输入图像时他就是保边滤波。

非局部均值滤波

NL 考虑了和周围区域的相似度

TV变分去噪

有一系列的TV损失的变种,例如变分去噪法,非局部变分去噪,双噪声相似的非局部变分去噪 图像处理-双噪声相似性的去噪方法.

## 混合域去噪

BM3D

BM3D去噪方法讲解

image-20210701223354016

BM3D 方法其实是 协同滤波 和 维纳滤波的结合。分为两个步骤:

步骤一:

  1. 在图像领域内寻找相似块堆叠成一个 3D 块进行协同滤波,采用硬阈值的方法过滤。同时统计 非0的像素点的个数
  2. 逆变换,并将图像块还原到原来的位置。(由于一个图像块可能处在不同的 3D图像组中,因此前面统计的系数可用于加权融合 来自不同滤波组的同一个图像块)
  3. 上述步骤后得到一个初步的滤波结果

步骤二:

  1. 有了初步滤波结果,重新匹配相似块(由于初步滤波后,相似度量结果更可靠)
  2. 将相似块组成 3D 组进行变换,类似协同滤波,但是变换后不适用 硬阈值 过滤,因为硬阈值始终存在误杀的情况。由于前面已经有了一个初步硬阈值滤波后的结果,因此 结合 维纳滤波的 维纳萎缩法,已知原始干净图像的信号能量(即初步滤波后的结果)和 噪声的能量(用方差模拟),那么可以更精确地对 新的 3D组 的系数进行抑制。
  3. 抑制完毕 逆变换 ….

TV 类去噪

同态滤波

参考链接

基本原理

同态变换一般是指将非线性组合信号通过某种变换,使其变成线性组合信号,从而可以更方便的运用线性操作对信号进行处理。

所谓非线性组合信号,举例来说,比如 z(t) = x(t) y(t),两个信号相乘得到组合信号,由于时域相乘等价于频率域卷积,所以无法在频率域将其分开。但是我们应用一个log算子,对两边取对数,则有: log(z(t)) = log(x(t)) + log(y(t)),这样一来,就变成了线性组合的信号,log(x(t)) 和 log(y(t)) 时域相加,所以频域也是相加的关系,如果它们的频谱位置不同,就可以傅里叶变换后较好的分开,以便进行后续的分别的操作,比如应用高、低通滤波或者其他手工设计的滤波器等,然后再将结果傅里叶反变换,得到处理过的 ,在取幂,就可以得到最终的处理结果。

图像中的同态滤波

在图像处理中,常常遇到动态范围很大但是暗区的细节又不清楚的现象,我们希望增强暗区细节的同时不损失亮区细节,一般来说,我们可以将图像f(x,y)建模成 照射强度(illumination) i(x,y) 和 反射强度(reflection) r(x,y)的乘积,所以有:

image-20210606115221662

一般来说,自然图片的光照一般是均匀渐变的,所以i应该是低频分量,而不同物体对光的反射是具有突变的,所以r是高频分量。现在我们对两边取对数,并做Fourier变换,得到线性组合的频率域。

image-20210606115234960

我们希望对低频能量进行压制(抑制掉 光照分量),这样就降低了动态范围,而要对高频进行提高,这样就增强了图像的对比度,示意图如下:

image-20210606115250493

所以采用的滤波器为:

image-20210606115300446

操作完成后在按照之前介绍的步骤,反变换,求幂,即可得到处理后的图像,整个过程的流程图如下:

image-20210606115350488

An Experiment-Based Review of Low-Light Image Enhancement Methods

其他相关文章:Lighting the Darkness in the Deep Learning Era

低光照存在的挑战

背光,光照不均匀,弱光照,极低光照,彩色光,噪声等

image-20210605213359244

传统方法

  • 基于直方图的方法:原理就是将低光照图像的直方图 尽可能调整为 均匀分布,通过原始分布 到 理想均匀分布的约束,来推导像素的变换函数,完成增强。其中用到了累计直方图作为中间桥梁。但是直方图的先验假设也是很强的,在处理彩色图像的时很容易出现颜色失真,噪声等问题。

  • 基于灰度变换的方法

    • 线性变换
    • 非线性变换:常用的非线性函数有 LOG 和 GAMMA 函数。仅仅使用固定的参数来增强,没有考虑到图像的全局信息,因此常常借助以下辅助手段,例如使用图像的累积概率直方图分布来自适应估计获得矫正参数等。
  • 基于 Retinex 模型:这个模型是根据人眼颜色感知恒常特性建立,物体的颜色是由物体对不同波长的光的反射能力决定,而不是由反射光强度的绝对值决定,物体的颜色不受光照非均匀性的影响。

    • 单尺度 SSR 多尺度 MSR;MSRCR 外加了颜色矫正,因为前两者都是三通道分离操作,所以颜色失真很严重,而后者效果好很多。
    • 这种方法可以较好的提高对比度和亮度,且在彩色图像处理方面也有更好的优势。但早期的方法基本都是使用高斯核分别对RGB三通道做平滑以近似光照,对边缘保持能力较差,会由holo效应,或者会导致过曝(因为光照图一定是小于1的无论如何都会拉量图像)
  • 基于频率域的方法:需要计算量大,并且变换参数,频率选择都存在很强的假设,如果设置不好效果就差

  • 同态滤波:认为输入图像由 低频光照分量 和 高频的反射率分量,也即Retinex那一套。只不过 频域滤波也只能消除加性的 信号。因此首先在 log 域将 光照和反射率分离,然后在频率域通过高频滤波器滤波,最后还原

    • 小波变换
  • 基于融合的方法:泊松融合。在梯度域中将梯度融合

    • 单帧图像融合:可以使用 CRF 相机响应模型来生成多曝光图然后融合
    • 多帧图像融合:效果好但是需要同一场景的图像 不好获取
  • 基于去雾模型的方法

深度学习

基于监督学习的方法

基于监督学习的方法大概可以分为 单阶段的 和 多阶段的网络。早期(2018年及以前)的都是单阶段的网络,一个输入,一个输出,损失函数作用于一个位置。

  • 例如18年BMVC上的MBLLEN,通过精心设计的多分支特征提取融合的结构增强

这种方法完全依赖网络的拟合能力和训练数据。但是自从2019年及以后,几乎都会采用多阶段的网络,他们会利用一定的传统先验,来使网络更容易学习到低光照到参考图之间的函数映射,降低对网络参数量和规模的依赖。

  • 典型的是 RetinexNet,KinD等网络。 结合 Retinex 模型的方法,增加一个光照估计阶段,然后使用一个UNET对分解的反射率图进行重建,这样的方式会比直接用UNET对低光照图矫正效果好很多。
  • 基于频率分解的方法,可以使用边缘提取方法预先对图像做边缘提取,分为边缘和细节分别处理。也可以在网络结构上增加学习频率提取的结构(并列空洞卷积做差),这是20年CVPR上的文章DRBN
  • 多曝光融合:AAAI20上的方法,按照单帧HDR的思路,首先对低光图乘系数,然后每个分支分别处理一个输入,并融合
  • 金字塔:也有用拉普拉斯金字塔的,使用拉普拉斯金子塔来对不同频带的图像分别增强,然后恢复。

存在的问题:

成对的训练数据缺乏,使用合成数据训练又难以获得较好的泛化性

强化学习

无监督学习

使用 GAN 来消除网络对成对训练图像的依赖。由于缺乏强监督,使用单一的GAN增强,局部会有不一致的增强效果,EnlightenGAN的做法是通过一个全局和一个局部判别器结合以及感知损失结合的方式,来提高生成图像质量的稳定性。但是它在一些场景中依然存在问题。另一个增加强约束的方式是采用 cycleGAN 结构,cycleGAN的缺点是结构复杂,训练过程更不稳定。

虽然GAN的方法效果不稳定,但是不失为一种值得探索的方向

半监督

这种方法就是一部分使用 成对的图像监督 来提高网络对细节的恢复能力。另一方面使用对抗损失提高网络的泛化性

零样本学习

20年开始有文章尝试零样本的方法构建低光照增强网络,以彻底摆脱对训练数据的依赖。这种方法依赖人工设计的图像鲜艳损失指导网络训练,这就依赖于损失函数的好坏,增强效果不自然。

损失函数

  1. SSIM L1 L2 损失 L2平方损失有模糊效应,用L1损失细节恢复更好,SSIM 也能很好的保留结构和纹理特征
  2. 感知损失,即 VGG 提取特征后 衡量特征之间的相似性
  3. 平滑损失 : 变分损失,对梯度约束 达到一定的去噪效果
  4. 对抗损失
  5. 曝光损失:局部均值和期望曝光值之间的误差

数据集

  • 合成数据集:使用gamma矫正 合成低光照数据 或者使用Retinex先分离光照然后把光照调低再还原。现在几乎不用 合成数据的方法了
  • LOL
  • SCIE
  • MIT-Adobe FiveK:主要是用于 色调调整或者增强,但是也有被用于低光照增强的
  • SID:Raw格式的数据
  • SMOID

评价指标

  • PSNR
  • MAE
  • MSE
  • SSIM
  • LOE
  • NIQE

请问你了解哪些设计模式?

常见的设计模式如下:

单例模式:确保单例类全局只有一个实例,并提供该实例的全局访问点。单例模式的实现核心是将 类 的构造函数设置为私有,并预留一个获取全局唯一对象的静态函数,用于外界获得该实例。根据实例化的时间可以分为懒汉模式和饿汉模式,区别就在于是使用的时候实例化还是在系统启动的时候就初始化。

工厂模式:是一个创建对象的接口,但是由子类决定实例化哪个类。工厂方法把实例化操作延迟到子类。

生成器模式:是一个创建型设计模式,如果一个类包含大量的部件,可以通过一个额外的生成器来分步骤创建复杂的对象,然后将创建的对象返回。

模板模式:定义算法框架,并将一些步骤延迟到子类实现,例如 常见的目标检测,包含了图像读取,预处理,检测,可视化,这几个子过程。如果更改其中的预处理的方法,那么只用在子类中重写预处理函数即可,其他过程都可以复用。weak_ptr

观察者模式:原理类似于所有观察者都实现一个 updata 接口,然后将所有的观察者注册进被观察者中,当被观察者状态变化时循环通过 update 接口通知所有观察者。

装饰模式:是静态继承的一种替代,通过装饰模式可以动态的给原有的对象增加新的功能。装饰类和被装饰类之间不存在耦合不相互影响。这种模式对被装饰类进行包装,在装饰类中持有被装饰类的对象,实现在保持原有功能前提下实现新的功能。除了最底层的原始对象不需要依赖以外,其他装饰对象都要携带一个指针指向它装饰的对象,装饰的过程像一个链表层层叠加。

请你说一说OOP的设计模式的五项原则

单一职责原则:每个类只负责单一的责任,如果一个任务很复杂,应该将他分散的多个类种实现,减少类的耦合,提高类的复用性。 依赖倒置原则:核心是面向接口编程的思想。高层模块不能依赖于底层模块,他们应该共同依赖于抽象(接口),因为抽象更稳定。在高层模块和底层模块之间抽象出一个稳定的接口层,降低他们之间的耦合。 里氏替换原则:这个原则是说 子类对象要能够完全替换父类,即可以使用父类的地方也要能使用子类替换。并在客户端中使用父类指针或引用类型来引用子类,以实现动态绑定。 接口隔离原则:不应该强迫客户依赖于它们不用的方法。因此使用多个专门的接口比使用单一的总接口要好。 开放-封闭原则:在新增功能时,不需要修改原有的代码 最少知识原则

请问如何保证单例模式只有唯一实例?你知道的都有哪些方法?

构造函数设置为私有属性,只有通过该类提供的静态方法来得到该类的唯一实例。在静态方法中判断 指向实例的静态成员指针为空,就实例化类,否则直接返回。(必须是静态成员指针,因为静态成员函数无法访问非静态成员变量)

单例模式有懒汉模式,可能会线程不安全,如果多个线程同时通过了指针空判断,就会创建出多个实例,通过双重锁来实现线程安全。(判空,上锁,再判空,为啥要用双重锁?如果已经实例化了,通过第一个判空操作能避免读的时候加锁等待,提高性能。第二个锁就是为了防止创建对象的时候多线程竞争) 另一个是饿汉模式,在程序运行时就完成了对象初始化,因此不存在不安全问题。

请你说说工厂模式的优点?

为了解耦,将对象的使用过程和创建过程分离。如果对象创建过程包含了复杂的创建逻辑,可以统一放在工厂类中实现,实现代码复用。充分利用了面向对象的多态性质,工厂对象返回的是指向具体子类的基类指针,如果后续修改了子类的业务逻辑,也只用修改工厂中的初始化逻辑,方便维护。

请你说一下观察者模式

观察者模式中分为观察者和被观察者,当被观察者发生装填改变时,观察者会受到通知。主要为了解决对象状态改变给其他对象通知的问题,其实现类似于观察者在被观察者那注册了一个回调函数。

说一说装饰模式

是静态继承的一种替代,通过装饰模式可以动态的给原有的对象增加新的功能。装饰类和被装饰类之间不存在耦合不相互影响。这种模式对被装饰类进行包装,在装饰类中持有被装饰类的对象,实现在保持原有功能前提下实现新的功能。除了最底层的原始对象不需要依赖以外,其他装饰对象都要携带一个指针指向它装饰的对象,装饰的过程像一个链表层层叠加。

使用场景:1、扩展一个类的功能。 2、动态增加功能,动态撤销。

手撕单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using namespace std;

class Single{
private:
static Single* ptr;
std::mutex mtx_;
Single(){};
public:
static getSingeTon(){
if(ptr == nullptr){
mtx_.lock();
if(ptr == nullptr){
ptr = new Single();
}
mtx_.unlock();
}
return ptr;
}
};
Single* Single::ptr = nullptr;