介绍
这篇论文(Poisson image editing)主要解决的是图像编辑的局部变化问题,比如说图像的无缝融合。之前的一些方法会导致图像的边缘出现接缝,即使用羽化的方法处理,也无法完全解决。
这篇文章提出的是一种通用机制,基于这种机制可以实现无缝图像克隆(Seamless Cloning)和选区编辑(Selection Editing)等功能。
原理
人眼对于二阶变化(如边缘)敏感,而对于一阶的梯度(比如光照、阴影的变化)不敏感。拉普拉斯算子进行了二阶导,光照、阴影这类缓慢的梯度可以近似看成线性函数,二阶导接近 0,这就会导致拉普拉斯算子处理后缓慢梯度被抑制,不过看着不明显。而对于高频变化,如边缘,经过拉普拉斯算子处理,会保留下来,依据拉普拉斯算子处理后的结果进行计算可以尽可能保留这些特征,以此达成“看起来差不多”的效果。

假设我们有一张源图像,一张目标图像,从源图像上切下来一块区域,移到目标图像上进行融合,那么可以这样看待下面几个符号:
- S:R2 上的闭集,可以代表目标区域
- Ω:Ω 是 S 上的子集,也就是要融合的区域
- ∂Ω:Ω 区域的边缘,即融合的区域的边缘
- f∗:定义在 S 去掉 Ω 的区域上的标量函数,可以看成源图像未融合部分的像素值。由于我们可以对图像的 RGB 三个分量分别处理,所以这里直接当作标量函数了
- f:f 是定义在 Ω 上的标量函数,也就是我们要求的图像部分
如果这是一个插值问题,最简单的插值方法是看作这样的最小化问题:
fmin∬Ω∣∇f∣2且f∣∂Ω=f∗∣∂Ω
这叫做膜插值,可以让边缘连贯,同时确保内部平滑。这或许能用来修复背景,但跟我们要做的图像融合没啥关系。我们需要对内部的插值做额外的约束,为此引入了一个引导场 v,将问题转化为:
fmin∬Ω∣∇f−v∣2且f∣∂Ω=f∗∣∂Ω
即让插值区域的梯度尽可能接近引导场 v,且边缘连续。引导场 v 可能就是源图像的梯度,也可能不是。
这个问题的解又满足:
Δf=divv over Ω 且 f∣∂Ω=f∗∣∂Ω
由第一段的分析,我们更加确信转化成这样的最小化问题是合理的。
对于图像编辑的问题,我们需要离散地进行求解。直接对上面这个方程离散,不好计算,所以还是选择原本的方程进行离散:
f∣Ωmin⟨p,q⟩∩Ω=∅∑((fp−fq)−vpq)2, with fp=fp∗, for all p∈∂Ω
其中 ⟨p,q⟩ 表示 q 是 p 的上下左右四个方向的像素之一,vpq 表示 p,q 中点处的引导向量场在 pq 方向的投影,即 vpq=v(2p+q)⋅pq。
这个式子把梯度近似成相邻像素的差,在引导向量场上离散取点并做投影来实现离散化。
求解离散的最小化能量,令偏导等于 0(这个平方和是凸函数,偏导为 0 的点就是最值点):
∂fp∂⟨p,q⟩∑(fp−fq−vpq)2=0
注意如果靠近 S 的边缘时,相邻像素不一定是 4 个。而对于 ∂Ω 上的点,满足 fq∗=fq,所以有:
q∈Np∑2(fp−fq−vpq)=0⇒∣Np∣fp−q∈Np∩Ω∑fq=q∈Np∩∂Ω∑fq∗+q∈Np∑vpq
这个方程就可以计算了。
应用
无缝图像克隆
无缝图像克隆(Seamless Cloning)就是指原理一节中的情况,将源图像融合到目标图像中。可以完成的任务有,往图片里增加内容,消除内容,以及改变纹理特征等。



问题的关键是选取合适的引导向量场 v,最简单的做法是直接取源图像的梯度,即 v=∇g,
但对于某些情况,比如源图像有洞、透明,或是要插入的位置太过于靠近其他物体,就会导致模糊的情况,这个时候可以用混合梯度的方式来解决。
for all x∈Ω,v(x)={∇f∗(x)∇g(x)if ∣∇f∗(x)∣>∣∇g(x)∣,otherwise.
选取源图像和目标图像中梯度更大的来计算,可以避免一些模糊的情况。离散形式:
vpq={fp∗−fq∗gp−gqif ∣fp∗−fq∗∣>∣gp−gq∣,otherwise,



选区编辑
还可以借助这个框架完成一些局部的图像编辑功能,比如纹理扁平化,改变光照、颜色,以及纹理的无缝拼合等。
调整一下思路,把引导场换成处理后的图像梯度场,就能做到原地修改了。

比如可以用一个二值掩码来对梯度进行处理:
for all x∈Ω,v(x)=M(x)∇f∗(x),
这里的 M 可以取边缘检测器之类的函数,达成的效果就是纹理细节被弱化了,图像变得平滑。


对局部颜色、亮度进行修改,按该方法,可以做到与其他物体的无缝接合。用户无需精确指定边界,就可以获得很好的过渡效果。

对于不能无缝拼接的纹理,可以把边缘作为 f∗,用这个方法来无缝拼接纹理。
实现
这里主要完成的是第一类的应用——无缝图像克隆。
对于一般的点 q 来说,4fq−f上−f下−f左−f右=右式,对于每个 q∈Ω 都可以列出一个方程,问题就转化成求解方程组了。
可以将解方程的问题转化成解 Ax=b 的方程组的问题,其中 A 是一个稀疏矩阵,包含方程组中每项的系数,而 x 是一个向量,包含每个点 q 的值。右侧的 b 对应方程右侧的值,与每个 q 对应。
求解有多种方法,比如共轭梯度法,多重网格法等。也可以简单地求 A−1,注意到 A 是一个对称正定矩阵,可以用 LDLT 分解来解决。