项目地址:https://dilipkay.wordpress.com/blind-deconvolution/
- 图像先验: ℓ 1 / ℓ 2 \ell_1/\ell_2 ℓ1/ℓ2(normalized version of ℓ 1 \ell_1 ℓ1),模糊核先验: ℓ 1 \ell_1 ℓ1
- x更新:iterative shrinkage-thresholding algorithm(ISTA)
- k更新:iterative re-weighted least squares (IRLS)
- 扩展到非一致性模糊
- 在Levin(2009)库上做了测试
作者认为 利用
ℓ
1
/
ℓ
2
\ell_1/\ell_2
ℓ1/ℓ2正则化相比其他常见形式的图像先验更有利于清晰图像而不是模糊图像。
作者以高斯模糊为例(这里我存疑:对于运动模糊不一定适用)
横轴表示高斯模糊核大小,即模糊核越大越模糊。高斯核大小为负数表示图像锐化(即原图减去模糊后的图像,后附代码)。传送门:图像锐化算法-sharpen
先提取低频,原图减去低频得到高频。这种方法称为非锐化掩模(unsharpen mask),我们常使用低通滤波器(高斯、双边)对图像进行滤波,这种方法滤波器很好控制(包括大小和强弱),从而可以控制高频分量的强弱。
从上图中作者得出结论: ℓ 1 / ℓ 2 \ell_1/\ell_2 ℓ1/ℓ2对于清晰图像值很小,对于模糊图像值很大,根据能量最小化,算法更倾向于清晰图像,而其余先验反之。
- 这里先解释为什么图像越模糊,
ℓ
1
/
ℓ
2
\ell_1/\ell_2
ℓ1/ℓ2值越小。
作者说图像模糊会使图像梯度的 ℓ 1 \ell_1 ℓ1和 ℓ 2 \ell_2 ℓ2值都减小,但 ℓ 2 \ell_2 ℓ2值减小的幅度更大。
这里我认为这种情况只适用于高斯模糊,因为高斯模糊确实使边缘变弱,但对于运动模糊而言,模糊虽然使得边缘变弱,但会使边缘出现偏移(重影现象),边缘数量反而增加,整体能量并不一定下降!(个人理解, ℓ 1 \ell_1 ℓ1大家不都在用嘛=。=)
正如文章所说,
ℓ
1
/
ℓ
2
\ell_1/\ell_2
ℓ1/ℓ2是
ℓ
1
\ell_1
ℓ1归一化后的版本,具有尺度不变性。
个人理解:对强边缘和弱边缘的响应差距相对较小。比如某个像素的梯度为[-10,10],
ℓ
1
=
20
\ell_1=20
ℓ1=20,
ℓ
1
/
ℓ
2
=
2
\ell_1/\ell_2=\sqrt2
ℓ1/ℓ2=2,另一个像素的梯度为[-1,-1],
ℓ
1
=
2
\ell_1=2
ℓ1=2,
ℓ
1
/
ℓ
2
=
2
\ell_1/\ell_2=\sqrt2
ℓ1/ℓ2=2。显然
ℓ
1
\ell_1
ℓ1响应差距更大。
ℓ 1 \ell_1 ℓ1 is scale variant so the norm can be minimized by simply reducing the signal.
模型优化
x
x
x 和
y
y
y 分别为清晰图像
u
u
u 和模糊图像
g
g
g 的梯度图。
- 更新 x x x时,将正则项的分母固定(看成常数),用上一次迭代的值,使用iterative shrinkage-thresholding algorithm(ISTA)算法解决。
- 更新 k k k时,使用iterative re-weighted least squares (IRLS)算法解决。
- 恢复最终清晰图像时使用超拉普拉斯先验(
α
=
0.8
\alpha=0.8
α=0.8,
λ
=
3000
\lambda=3000
λ=3000)
附
matlab 实现非锐化掩模(unsharpen mask)代码:
clear;
imSrc = imread('coloredChips.png');
imSrcYcbcr = rgb2ycbcr(imSrc);
imSrcY = imSrcYcbcr(:,:,1);
[hei, wid] = size(imSrc(:,:,1));
size = 3;
sigma = 1; %gauss standard deviation sigma, default is 1
amount = 1.5;
threshold = 15;
gaussFilter = fspecial('gaussian', [size, size], sigma);
imSrcY_lf = imfilter(imSrcY, gaussFilter, 'symmetric');
imSrcY_hf = imSrcY - imSrcY_lf;
imLabel = (imSrcY_hf > threshold);
imLabel = uint8(imLabel);
imDstY = uint8(imSrcY + amount * imSrcY_hf .* imLabel);
figure, imshow([imSrcY, imSrcY_lf, imSrcY_hf, imDstY]);
imSrcYcbcr(:,:,1) = imDstY;
imDst = ycbcr2rgb(uint8(imSrcYcbcr));
figure, imshow([imSrc, imDst]);