
bilateral grid(双边网格)
双边网格(bilateral grid)的原理全解析,非常通俗易懂
bilateral grid
最近掌握了一种叫做 bilateral grid的数据结构,关于它的资料在网上比较少而且都写得不够深入,我尝试来写一下^-^
要理解bilateral grid,必须要读的文章是:Real-time Edge-Aware Image Processing with the Bilateral Grid, ACM TOG, 2007
bilateral grid的提出本身是为了加速诸如双边滤波(bilateral filter)、边缘感知绘画(edge-aware inpainting)和局部直方图均衡(local histogram equalization)等算法,让这些算法能够在GPU上进行并行计算。
在开始介绍bilateral grid之前,需要一点点对双边滤波的了解作为前置知识。
双边滤波
双边滤波的主要应用场景是图像平滑化,对比普通的高斯平滑核(gaussian filter),双边滤波能更好地保持图像的结构边缘信息。
对于一张大小为(h, w)的灰度图,用 I ( p ) I(p) I(p)表示取出其中点 p p p的强度值。
局部滤波器的工作原理是:对于每一中心点 p p p,对其邻域窗口 N p \mathcal{N}_p Np内的点集 { q ∣ q ∈ N p } \{q| q\in \mathcal{N}_p\} {q∣q∈Np}做加权平均,得到点 p p p对应的滤波器输出。
高斯平滑核:对于权值的设计,仅考虑点
p
p
p和点
q
q
q之间的位置关系,即定下
σ
\sigma
σ和窗口大小后,对于每一个邻域窗口
N
p
\mathcal{N}_p
Np,卷积核都是固定的。
G
(
p
)
=
1
W
p
Σ
q
g
σ
(
∥
q
−
p
∥
)
I
(
q
)
,其中
g
σ
(
x
)
=
1
σ
2
π
e
−
x
2
2
2
σ
2
G(p)=\frac{1}{W_p}\Sigma_q g_\sigma(\Vert q-p\Vert )I(q),其中g_\sigma(x) = \frac{1}{\sigma \sqrt{2\pi}}e^{- \frac{ x_2^2}{2\sigma^2}}
G(p)=Wp1Σqgσ(∥q−p∥)I(q),其中gσ(x)=σ2π1e−2σ2x22
具体来说,
g
σ
(
∥
q
−
p
∥
)
=
g
σ
(
x
q
−
x
p
)
⋅
g
σ
(
y
q
−
y
p
)
=
1
σ
2
2
π
e
−
(
x
q
−
x
p
)
2
+
(
y
q
−
y
p
)
2
2
σ
2
具体来说,g_\sigma(\Vert q-p\Vert ) = g_\sigma(x_q - x_p)\cdot g_\sigma(y_q - y_p) = \frac{1}{\sigma^2 2\pi}e^{- \frac{(x_q-x_p)^2 +(y_q-y_p)^2 }{2\sigma^2}}
具体来说,gσ(∥q−p∥)=gσ(xq−xp)⋅gσ(yq−yp)=σ22π1e−2σ2(xq−xp)2+(yq−yp)2
双边滤波:在权值的设计上,除了考虑点
p
p
p和点
q
q
q之间的位置关系外,还考虑点
p
p
p和点
q
q
q之间的值的大小关系。这一点也很通俗易懂:如果两点之间的值差异较大,也意味着两点的相关性比较小,那么在平滑操作上,点
q
q
q的信息对于平滑点
p
p
p的作用不大,对应权值就应该要小一些。
B
(
p
)
=
1
k
p
Σ
q
g
σ
p
(
∥
q
−
p
∥
)
⋅
g
σ
i
(
∥
I
(
q
)
−
I
(
p
)
∥
)
⋅
I
(
q
)
B(p) = \frac{1}{k_p}\Sigma_q g_{\sigma_p}(\Vert q-p\Vert )\cdot g_{\sigma_i}(\Vert I(q)- I(p)\Vert )\cdot I(q)
B(p)=kp1Σqgσp(∥q−p∥)⋅gσi(∥I(q)−I(p)∥)⋅I(q)
双边滤波的设计是edge-aware的,但是有一个非常致命的缺点:它的卷积核是spatial varying的,也就是说,对于每一个邻域窗口
N
p
\mathcal{N}_p
Np,都要重新计算卷积核。这样一来,计算复杂度和耗时都大大增加!
那么,该如何既利用得到双边滤波的优秀性能,又能兼顾效率呢?bilateral grid就能实现这一点。
双边网格(bilateral grid)
对于一张大小为(h, w)的灰度图[每个像素点取值范围为0-255],每一个点其实包含3个维度的信息:x坐标,y坐标和像素值。双边网络的思想就是做维度的扩充,使用一个三维(下采样)的tensor来包含全图的信息。
先贴一张论文中的图,下图即为利用双边网格加速双边滤波实现的流程:
论文中举了个1D image的例子,并不是我们生活中常见的灰度图/彩图,我将以更常见的灰度图来主要例子来讲解。
bilateral grid的大小
先给出一些定义:
s
s
s_s
ss:在空间维度下采样的倍数,用于控制smoothing的程度。
s
r
s_r
sr:在值强度维度下采样的倍数,用于控制对边缘信息的保留程度。
那么,这两个超参数就决定了bilateral grid的大小为: ( h / s s , w / s s , 256 / s r ) (h/s_s, w/s_s, 256/s_r) (h/ss,w/ss,256/sr)
bilateral grid的创建
- 初始化:首先,初始化每个grid node ( i , j , k ) (i,j,k) (i,j,k)值为 Γ ( i , j , k ) = ( 0 , 0 ) \Gamma(i,j,k)=(0, 0) Γ(i,j,k)=(0,0)。grid node中存储的是二元组,第一个元素存储被映射到这个grid node上的点的值强度之和,第二个元素存储被映射到这个grid node上的点的数量。
- 值填充:遍历图上每个点
p
p
p,执行操作
Γ
(
[
x
/
s
s
]
,
[
y
/
s
s
]
,
[
I
(
p
)
/
s
r
]
)
+
=
(
I
(
p
)
,
1
)
,其中
[
⋅
]
为round operator(四舍五入取整)
\Gamma([x/s_s],[y/s_s],[I(p) / s_r]) += (I(p), 1),其中[\cdot]为\text{round operator}(四舍五入取整)
Γ([x/ss],[y/ss],[I(p)/sr])+=(I(p),1),其中[⋅]为round operator(四舍五入取整)
这个操作的含义是:将灰度图上的每一个点都映射到bilateral grid对应的位置上去。
创建好的bilateral grid包含了整张灰度图的全部信息。
Processing
用一个3D gaussian filter
f
f
f对bilateral grid本身做卷积操作,即等价于在灰度图上应用bilateral filter
Γ
~
=
f
(
Γ
)
,
\tilde{\Gamma} = f(\Gamma),
Γ~=f(Γ),
其中
f
中两点
m
和
n
,值为
g
σ
s
(
x
n
−
x
m
)
⋅
g
σ
s
(
y
n
−
y
m
)
⋅
g
σ
i
(
z
n
−
z
m
)
其中f中两点m和n,值为g_{\sigma_s}(x_n - x_m)\cdot g_{\sigma_s}(y_n - y_m)\cdot g_{\sigma_i}(z_n -z_m)
其中f中两点m和n,值为gσs(xn−xm)⋅gσs(yn−ym)⋅gσi(zn−zm)
这样子,就能巧妙地运用并行计算操作来实现bilateral filter了,但是得到还不够
Γ
~
\tilde{\Gamma}
Γ~,我们希望得到的是一个和灰度图输入等大的输出,也就是说,要做和创建bialteral grid中的值填充的逆操作类似的操作。
恢复成图像(slicing)
在文中,运用三线性插值来还原出输出图像
M
M
M中每个点的值强度
除了处理过后的bilateral grid
Γ
~
\tilde{\Gamma}
Γ~外,还需要一张reference image
E
E
E。在实际应用中,
E
E
E可能是输入图像本身,也可能是用输入图像生成的guidance map。
M
=
s
E
(
Γ
~
)
M = s_E(\tilde{\Gamma})
M=sE(Γ~)
对于三线性插值,这里就不赘述了,原理很简单:对于
E
E
E中每一点
p
p
p,求出其在
Γ
~
\tilde{\Gamma}
Γ~上的位置映射,包含其的最小的cude有8个角点,根据位置对它们做加权求和,即能获得
p
p
p在
Γ
~
\tilde{\Gamma}
Γ~上的二元组值
(
I
t
o
t
a
l
(
p
)
,
n
p
)
(I_{total}(p), n_p)
(Itotal(p),np)。
最后,输出图像 M M M中同一位置点 p p p的值为 I t o t a l ( p ) n p \frac{I_{total}(p)}{n_p} npItotal(p)。
扩展到彩图
随着时代的发展,我们生活中更常见的其实还是彩图。对于有着(R, G, B)三个通道的彩图,大家觉得其对应的bilateral grid是几维呢?
答案是5维。 维数 = 坐标维数 ( 2 ) + 值强度维数 ( 3 ) 维数=坐标维数(2) + 值强度维数(3) 维数=坐标维数(2)+值强度维数(3)
那么显然,与处理灰度图不同的是,应用5D Gaussian filter来对bilateral grid做卷积操作。
双边网格的变体
这里就得介绍同一作者的另外一篇文章:bilateral guided upsampling, ACM TOG, 2016
施工中,未完待续……
更多推荐
所有评论(0)