原文:PDF
代码:GIT
论文中给出的噪声模型为
x
∼
k
P
(
x
∗
k
)
+
N
(
0
,
σ
2
)
x \sim k\mathcal{P}(\frac{x^*}{k})+\mathcal{N}(0,\sigma^2)
x∼kP(kx∗)+N(0,σ2)
其中,
x
x
x 为噪声图像,
x
∗
x^*
x∗ 为无噪声图像,
k
k
k 是 photon noise 相关参数,
σ
\sigma
σ 是 add noise 相关参数
噪声相关可以参考 计算摄影:噪声模型与噪声估计
在这个基础上,可以用python实现模拟生成噪声图像
import numpy as np
k = 2 # example for 3200 ISO
sigma = 10 # example for 3200 ISO
noise = k * np.random.poisson(img / k) + np.random.normal( 0., sigma, img.shape)
K-Sigma
作者提出了 K-Sigma Transform 用于模型的预处理和后处理,以去掉数据的噪声强度对于ISO的依赖,某种程度上算是降低了训练数据的难度
the network can be trained using normalized data without considering the ISO setting
定义
f
(
x
)
=
x
k
+
σ
2
k
2
f(x) = \frac{x}{k} + \frac{\sigma^2}{k^2}
f(x)=kx+k2σ2
带入噪声模型,可以得到只依赖于
x
∗
x^*
x∗ 分布的数据
对于 特定的ISO ,可以通过求解以下线性回归问题得到 对应的
k
k
k 和
σ
\sigma
σ
{
E
(
x
)
=
x
∗
V
a
r
(
x
)
=
k
x
∗
+
σ
2
\left \{ \begin{array}{ll} \mathrm{E}(x) = x^* \ \mathrm{Var}(x) = k x^*+\sigma^2 \end{array} \right.
{E(x)=x∗Var(x)=kx∗+σ2
具体的,对于相同场景,相同ISO设置下,拍摄的多张图像,通过均值估计 x ∗ x^* x∗,再利用方差和最小二乘法,得到 k k k 和 σ \sigma σ
import numpy as np
k = 2 # example for 3200 ISO
sigma = 10 # example for 3200 ISO
if __name__ == "__main__":
# Generate the noise image
noise = []
for i in range(200):
noise.append(k * np.random.poisson(img / k) + np.random.normal( 0., sigma, img.shape))
noise = np.asarray(noise) # 200x16x16
mu = np.mean(noise, 0) # 1x16x16
mu = np.clip(np.round(mu), 0,255)
xp = np.unique(np.sort(mu))[:]
print(xp.shape)
# calculate the var for every xp
var = []
for i in xp:
var.append(np.mean((noise[:, mu == i] - i)**2))
var = np.asarray(var)
w = np.column_stack((xp, np.ones_like(xp)))
# y = wx; w->[mu, 1] x->[k, simma^2]^T, y->var
# x = inv(w^T*w)*w^T * y
winv = np.matmul(np.linalg.inv(np.matmul(np.transpose(w), w)),np.transpose(w))
x = np.matmul(winv, var)
对于不同的ISO设置,可以用以上代码得到对应的 K-Sigma 参数,利用numpy的polyfit
函数分别拟合1阶函数和2阶函数,即可得到作者所说的Noise参数
作者在实际代码中,使用了一个anchor,将 input 对齐到了 anchor 的,而不是如同论文中所说的简单的做 K-Sigma 变换和逆变换,作者的解答如下:
anchor is an extension to the original k-sigma transfor. For a random ISO
Gx
and an anchor ISOGa
, the process is
img_norm = inv_ksigma(ksigma(img, Gx), Ga)
In this way, the input images are “normalized” to noise characteristics at ISO-level atGa
. Compared with the orignal k-sigma transform, this extension can keep the value range to the network in a stable range.
另外,对于代码中的V
,作者的解释如下:
V
means value range. For a typical 10bit sensor with black_level 64,V = 1023-64 = 959
. Some sensors can be set in different bitwidth output, this param is useful in this case.
具体参见ISSUE 3,不吐槽是否还有其他骚 *** 作。
Re-Thinking其实作者的 *** 作可以看作特殊的正则化,从我个人的感觉上来看,其结果是依据噪声模型的参数,将图像“压缩”到特定的范围,至于作者为什么要做一个extension ,感觉是由于不同的ISO,会将图像压缩到不同的范围,比如,利用不同ISO参数拍摄的相同场景的图像,低ISO的 k k k值更小,高ISO的 k k k值更大,如果不改变曝光时间等其他参数,那么低ISO的图像更暗,高ISO的图像更亮,看似变换是合理的,但通常为了保证高ISO能够正常成像,都会调整曝光参数等防止过曝,这会将图像亮度拉低,那么再应用K-Sigma变换似乎就没太有道理。
如有错误请指正,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)