L0 gradient minimization算法
论文及源代码link
[侵删]
数学基础
L0 gradient minimization算法的的目标函数:
min
S
{
∑
p
(
S
p
−
I
p
)
2
+
λ
⋅
C
(
S
)
}
\min\limits_S\left\{\sum_p(S_p-I_p)^2+\lambda\cdot C(S)\right\}
Smin{p∑(Sp−Ip)2+λ⋅C(S)}
C
(
S
)
=
#
{
p
∣
∣
∂
x
S
p
∣
+
∣
∂
y
S
p
∣
≠
0
}
C(S)=\#\left\{\begin{matrix}p&|&|\partial_xS_p|+|\partial_yS_p|\ne0\end{matrix}\right\}
C(S)=#{p∣∣∂xSp∣+∣∂ySp∣=0}
由于原始函数一项为像素差异,另一项为全局不连续的函数,所以无论是梯度法还是离散优化方法都很难计算。所以采用了半二次分裂的方法,所包含的的子问题都是具有封闭形式的解。作者通过引入辅助变量
h
p
,
v
p
h_p,v_p
hp,vp,对原始目标函数进行重塑,得到:
min
S
.
h
,
v
{
∑
p
(
S
p
−
I
p
)
2
+
λ
C
(
h
,
v
)
+
β
(
(
∂
x
S
p
−
h
p
)
2
+
(
∂
y
S
p
−
v
p
)
2
)
}
(
1
)
\min\limits_{S.h,v}\bigg\{\sum_p(S_p-I_p)^2+\lambda C(h,v)+\beta((\partial_xS_p-h_p)^2+(\partial_yS_p-v_p)^2)\bigg\}\quad(1)
S.h,vmin{p∑(Sp−Ip)2+λC(h,v)+β((∂xSp−hp)2+(∂ySp−vp)2)}(1)
其中的
C
(
h
,
v
)
=
#
{
p
∣
∣
h
p
∣
+
∣
v
p
∣
≠
0
}
C(h,v)=\#\bigl\{p\bigm|\lvert h_p\rvert+\lvert v_p\rvert\ne0\bigr\}
C(h,v)=#{p
∣hp∣+∣vp∣=0}用来约束梯度。
转为两个子问题:
子问题一:
解决子问题1为:
{
∑
p
(
S
p
−
I
p
)
2
+
β
(
(
∂
x
S
p
−
h
p
)
2
+
(
∂
y
S
p
−
v
p
)
2
)
}
(
2
)
\left\{\sum\limits_p(S_p-I_p)^2+\beta((\partial_xS_p-h_p)^2+(\partial_yS_p-v_p)^2)\right\}\quad(2)
{p∑(Sp−Ip)2+β((∂xSp−hp)2+(∂ySp−vp)2)}(2)
公式2为二次函数,可以找到全局最优点。使用FFT进行加速,则转为计算:
S
=
F
−
1
(
F
(
I
)
+
β
(
F
(
∂
x
)
∗
F
(
h
)
+
F
(
∂
y
)
∗
F
(
v
)
)
F
(
1
)
+
β
(
F
(
∂
x
)
∗
F
(
∂
x
)
+
F
(
∂
y
)
∗
F
(
∂
y
)
)
)
(
3
)
S=\mathcal{F}^{-1}\left(\begin{matrix}\mathcal{F}(I)+\beta(\mathcal{F}(\partial_x)^*\mathcal{F}(h)+\mathcal{F}(\partial_y)^*\mathcal{F}(v))\\ \hline\mathcal{F}(1)+\beta(\mathcal{F}(\partial_x)^*\mathcal{F}(\partial_x)+\mathcal{F}(\partial_y)^*\mathcal{F}(\partial_y))\end{matrix}\right)\quad(3)
S=F−1(F(I)+β(F(∂x)∗F(h)+F(∂y)∗F(v))F(1)+β(F(∂x)∗F(∂x)+F(∂y)∗F(∂y)))(3)
子问题二:
目标函数为:
min
h
,
v
{
∑
p
(
∂
x
S
p
−
h
p
)
2
+
(
∂
y
S
p
−
v
p
)
2
)
+
λ
β
C
(
h
,
v
)
}
(
4
)
\min\limits_{h,v}\left\{\sum_p(\partial_x S_p-h_p)^2+(\partial_y S_p-v_p)^2)+\frac{\lambda}{\beta}C(h,v)\right\}\quad(4)
h,vmin{p∑(∂xSp−hp)2+(∂ySp−vp)2)+βλC(h,v)}(4)
其中的
C
(
h
,
v
)
C(h,v)
C(h,v)返回的是
∣
h
∣
+
∣
v
∣
\lvert h\rvert+\lvert v\rvert
∣h∣+∣v∣的非零元素。
这个明显复杂的子问题实际上快速解决,因为能(4)可以进行空间分解,其中每个元素
h
p
h_p
hp和
v
p
v_p
vp是单独估计的。拆分后变为:
∑
p
min
h
p
,
v
p
{
(
h
p
−
∂
x
S
p
)
2
+
(
v
p
−
∂
y
S
p
)
2
+
λ
β
H
(
∣
h
p
∣
+
∣
v
p
∣
)
}
(
5
)
\sum\limits_p\min\limits_{h_p,v_p}\left\{\left(h_p-\partial_xS_p\right)^2+\left(v_p-\partial_yS_p\right)^2+\frac{\lambda}{\beta}H(\left|h_p\right|+\left|v_p\right|)\right\}\quad(5)
p∑hp,vpmin{(hp−∂xSp)2+(vp−∂ySp)2+βλH(∣hp∣+∣vp∣)}(5)
其中的
H
(
∣
h
∣
+
∣
v
∣
)
H(\lvert h\rvert+\lvert v\rvert)
H(∣h∣+∣v∣)是一个二值化函数,如果
∣
h
p
∣
+
∣
v
p
∣
≠
0
|h_p|+|v_p|\ne0
∣hp∣+∣vp∣=0则返回1,否则为0。对于公式5,构建
E
p
=
{
(
h
p
−
∂
x
S
p
)
2
+
(
v
p
−
∂
y
S
p
)
2
+
λ
β
H
(
∣
h
p
∣
+
∣
v
p
∣
)
}
(
6
)
E_p=\left\{(h_p-\partial_xS_p)^2+(v_p-\partial_yS_p)^2+\frac{\lambda}{\beta}H(|h_p|+|v_p|)\right\}\quad(6)
Ep={(hp−∂xSp)2+(vp−∂ySp)2+βλH(∣hp∣+∣vp∣)}(6)
那么取得最小值的
E
p
∗
E_p^*
Ep∗需要满足条件:
(
h
p
,
v
p
)
=
{
(
0
,
0
)
(
∂
x
S
p
)
2
+
(
∂
y
S
p
)
2
≤
λ
/
β
(
∂
x
S
p
,
∂
y
S
p
)
otherwise
(
7
)
(h_p,v_p)=\begin{cases}(0,0)&(\partial_x S_p)^2+(\partial_y S_p)^2\le\lambda/\beta\\ (\partial_x S_p,\partial_y S_p)&\text{otherwise}\end{cases}\quad(7)
(hp,vp)={(0,0)(∂xSp,∂ySp)(∂xSp)2+(∂ySp)2≤λ/βotherwise(7)
算法流程图
![](./L0GradientMin.png)
通过求解h,v的值,不断更新S以及 β \beta β,最终求得原始公式的最优解。
代码解析
官方matlab代码
function S = L0Smoothing(Im, lambda, kappa)
%L0Smooth - Image Smoothing via L0 Gradient Minimization
% S = L0Smooth(Im, lambda, kappa) performs L0 graidient smoothing of input
% image Im, with smoothness weight lambda and rate kappa.
%
% Paras:
% @Im : Input UINT8 image, both grayscale and color images are acceptable.
% @lambda: Smoothing parameter controlling the degree of smooth. (See [1])
% Typically it is within the range [1e-3, 1e-1], 2e-2 by default.
% @kappa : Parameter that controls the rate. (See [1])
% Small kappa results in more iteratioins and with sharper edges.
% We select kappa in (1, 2].
% kappa = 2 is suggested for natural images.
%
% Example
% ==========
% Im = imread('pflower.jpg');
% S = L0Smooth(Im); % Default Parameters (lambda = 2e-2, kappa = 2)
% figure, imshow(Im), figure, imshow(S);
if ~exist('kappa','var')
kappa = 2.0;
end
if ~exist('lambda','var')
lambda = 2e-2;
end
S = im2double(Im);
betamax = 1e5;
fx = [1, -1];
fy = [1; -1];
[N,M,D] = size(Im);
sizeI2D = [N,M];
% psf2otf:点扩散函数转调制传递函数,这里认为是微分的FFT
otfFx = psf2otf(fx,sizeI2D);
otfFy = psf2otf(fy,sizeI2D);
Normin1 = fft2(S);
% 公式3中分母部分:微分的FFT的平方
Denormin2 = abs(otfFx).^2 + abs(otfFy ).^2;
if D>1
Denormin2 = repmat(Denormin2,[1,1,D]);
end
beta = 2*lambda;
while beta < betamax
% 公式3分母
Denormin = 1 + beta*Denormin2;
% h-v subproblem
h = [diff(S,1,2), S(:,1,:) - S(:,end,:)];
v = [diff(S,1,1); S(1,:,:) - S(end,:,:)];
% 公式7,求h-v问题的最小化
if D==1
t = (h.^2+v.^2)<lambda/beta;
else
t = sum((h.^2+v.^2),3)<lambda/beta;
t = repmat(t,[1,1,D]);
end
h(t)=0; v(t)=0;
% S subproblem
% 计算公式3的分子:分别对h和v进行dx和dy计算
% 等价于FFT域中dx,dy乘h,v
Normin2 = [h(:,end,:) - h(:, 1,:), -diff(h,1,2)];
Normin2 = Normin2 + [v(end,:,:) - v(1, :,:); -diff(v,1,1)];
FS = (Normin1 + beta*fft2(Normin2))./Denormin;
%计算得到当前的解
S = real(ifft2(FS));
% 不断增大beta,使得整体公式逼近原始公式。
beta = beta*kappa;
fprintf('.');
end
fprintf('\n');
end