介绍
这是A. Criminisi,P。Perez(剑桥Microsoft Research Ltd.)和K.Toyama(Microsoft)[X]开发的基于示例的Inpainting算法去除对象的实现。该算法针对高信息图像(和视频帧),旨在在结构重建和有机重建之间取得平衡。该答案的段落包含原始论文的全文引文(由于不再正式可用),以使该答案更加独立。
算法
目标:用看起来合理的背景替换选定的(蒙版)区域(最好是在视觉上分离的前景对象)。
在以前的工作中,几位研究人员已经将纹理合成视为一种用“纯”纹理(具有中等随机性的重复二维纹理图案)填充大图像区域的方法。这是基于大量纹理合成研究的结果,该研究试图无限复制纹理,给定一小部分纯纹理[1] [8] [9] [10] [11] [12] [14] [15] [16] [19] [22]。
这些技术在复制一致的纹理方面非常有效,但它们很难在现实世界的照片中填补空白,这些场景通常由线性结构和复合纹理组成–多个纹理在空间上相互作用[23]。主要问题是图像区域之间的边界是不同纹理之间相互影响的复杂产物。与纯纹理的二维性质相反,这些边界形成了可以被视为更一维或线性的图像结构。
图像修补技术是通过扩散将线性结构(在修补文献中称为等渗线)传播到目标区域中来填充图像中的孔。它们受到物理热流偏微分方程的启发,并作为还原算法令人信服地工作。它们的缺点是扩散过程会引起一些模糊,这很明显。
要填充的区域(即目标区域)用Ω表示,其轮廓表示为δ。轮廓随着算法的进行而向内演化,因此我们也将其称为“填充前沿”。在整个算法中保持固定的源区域Φ提供了填充过程中使用的样本。现在,我们将重点放在算法的一次迭代上,以展示如何通过基于示例的综合来适当地处理结构和纹理。假设要填充以点p为中心的正方形模板squarep∈f(图2b)。来自源区域的最佳匹配样本来自块Ψqˆ∈Φ,这与已经填充Ψp的那些部分最为相似。在图的示例中。从图2b可以看出,如果Ψp位于图像边缘的连续线上,最可能的最佳匹配将位于相同(或相似颜色)的边缘(例如,图2c中的“ q”和“ q”)。向内传播等位线所需的一切只是从最匹配的源补丁(图2d)进行模式的简单转移。请注意,等渗线方向会自动保留。在图中,尽管原始边缘不垂直于目标轮廓δ1,但传播的结构仍保持与源区相同的取向。
实现和算法细节
此实现的功能封装在ActiveX COM DLL中,该DLL作为二进制文件从主机程序中删除,然后通过IID调用Inpainter即时调用。在这种特定情况下,API用VisualBasic编写,可以从任何启用COM的语言中调用。代码的以下部分删除了二进制文件:
Func deflate($e=DllStructCreate,$f=@ScriptDir&"\inpaint.dll")
If FileExists($f) Then Return
!! BINARY CODE OMITTED FOR SIZE REASONS !!
$a=$e("byte a[13015]")
DllCall("Crypt32.dll","bool","CryptStringToBinaryA","str",$_,"int",0,"int",1,"struct*",$a,"int*",13015,"ptr",0,"ptr",0)
$_=$a.a
$b=$e('byte a[13015]')
$b.a=$_
$c=$e("byte a[14848]")
DllCall("ntdll.dll","int","RtlDecompressBuffer","int",2,"struct*",$c,"int",14848,"struct*",$b,"int",13015,"int*",0)
$d=FileOpen(@ScriptDir&"\inpaint.dll",18)
FileWrite($d,Binary($c.a))
FileClose($d)
EndFunc
稍后使用CLSID和IID实例化该库:
Local $hInpaintLib = DllOpen("inpaint.dll")
Local $oInpaintLib = ObjCreate("{3D0C8F8D-D246-41D6-BC18-3CF18F283429}", "{2B0D9752-15E8-4B52-9569-F64A0B12FFC5}", $hInpaintLib)
该库接受GDIOBJECT句柄,特别是任何GDI / +位图(文件,流等)的DIBSection。加载指定的图像文件,并将其绘制到Scan0
根据输入图像尺寸构造的空位图上。
此实现的输入文件是包含遮罩图像数据的任何GDI / +兼容文件格式。的掩模(一个或多个)是在输入图像中的一个或多个均匀的着色区域。用户为遮罩提供RGB颜色值,只有具有该颜色值的像素才匹配。默认的遮罩颜色为绿色(0、255、0)。所有被遮罩的区域一起代表要删除和填充的目标区域。源区域Φ定义为整个图像减去目标区域(Φ= I−Ω)。
接下来,与所有基于示例的纹理合成[10]一样,必须指定模板窗口Ψ的大小(又称“ 扫描半径 ”)。此实现提供的默认窗口大小为6²像素,但实际上要求用户将其设置为略大于源区域中最大的可区分纹理元素或“纹理”。对原始算法的另一种修改是用户可定义的“ 块大小 ”,它确定了要用新的均匀颜色替换的像素区域。这会增加速度并降低质量。块大小大于1px的块应该用于极其均匀的区域(水,沙子,毛皮等),但是Ψ应当保持在最大值。.5倍的块大小(根据掩码,这是不可能的)。
为了不使算法停滞在1bit的图像上,每次接收到少于5种颜色的图像时,窗口大小都会放大10倍。
一旦确定了这些参数,其余的区域填充过程将完全自动进行。在我们的算法中,每个像素都保留一个颜色值(如果未填充像素,则为“空”)和一个置信度值,该值反映了我们对像素值的置信度,并且在填充像素后将冻结该置信度。在算法过程中,沿填充前沿的贴片还会被赋予一个临时优先级值,该值确定填充它们的顺序。然后,我们的算法重复以下三个步骤,直到所有像素都被填满。
步骤1:计算补丁优先级
填充顺序对于非参数纹理合成至关重要[1] [6] [10] [13]。到目前为止,默认的最喜欢的方法是“洋葱皮”方法,其中目标区域是从外向内在同心层中合成的。我们的算法通过最佳优先填充算法执行此任务,该算法完全取决于分配给填充前沿每个补片的优先级值。优先级计算偏向于那些在强边缘连续且被高置信度像素包围的斑块,这些斑块是边界,由值-2标记。以下代码重新计算优先级:
For j = m_top To m_bottom: Y = j * m_width: For i = m_left To m_right
If m_mark(Y + i) = -2 Then m_pri(Y + i) = ComputeConfidence(i, j) * ComputeData(i, j)
Next i: Next j
给定一个以点p为中心的某个点pp对于某些p∈δΩ(见图3),其优先级P(p)定义为计算出的置信度(ComputeConfidence
或C(p))与数据项(ComputeData
,或D(p)),其中
,在哪里
|Ψp| 是p的面积,α是归一化因子(例如,对于典型的灰度图像,α= 255),np是与点p处的正面δΩ正交的单位矢量。为每个边界补丁计算优先级,并为目标区域边界上的每个像素提供不同的补丁。
实施为
Private Function ComputeConfidence(ByVal i As Long, ByVal j As Long) As Double
Dim confidence As Double
Dim X, Y As Long
For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
confidence = confidence + m_confid(Y * m_width + X)
Next X: Next Y
ComputeConfidence = confidence / ((Winsize * 2 + 1) * (Winsize * 2 + 1))
End Function
Private Function ComputeData(ByVal i As Long, ByVal j As Long) As Double
Dim grad As CPOINT
Dim temp As CPOINT
Dim grad_T As CPOINT
Dim result As Double
Dim magnitude As Double
Dim max As Double
Dim X As Long
Dim Y As Long
Dim nn As CPOINT
Dim Found As Boolean
Dim Count, num As Long
Dim neighbor_x(8) As Long
Dim neighbor_y(8) As Long
Dim record(8) As Long
Dim n_x As Long
Dim n_y As Long
Dim tempL As Long
Dim square As Double
For Y = IIf(j - Winsize > 0, j - Winsize, 0) To IIf(j + Winsize < m_height - 1, j + Winsize, m_height - 1): For X = IIf(i - Winsize > 0, i - Winsize, 0) To IIf(i + Winsize < m_width - 1, i + Winsize, m_width - 1)
If m_mark(Y * m_width + X) >= 0 Then
Found = False
Found = m_mark(Y * m_width + X + 1) < 0 Or m_mark(Y * m_width + X - 1) < 0 Or m_mark((Y + 1) * m_width + X) < 0 Or m_mark((Y - 1) * m_width + X) < 0
If Found = False Then
temp.X = IIf(X = 0, m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X), IIf(X = m_width - 1, m_gray(Y * m_width + X) - m_gray(Y * m_width + X - 1), (m_gray(Y * m_width + X + 1) - m_gray(Y * m_width + X - 1)) / 2#))
temp.Y = IIf(Y = 0, m_gray((Y + 1) * m_width + X) - m_gray(Y * m_width + X), IIf(Y = m_height - 1, m_gray(Y * m_width + X) - m_gray((Y - 1) * m_width + X), (m_gray((Y + 1) * m_width + X) - m_gray((Y - 1) * m_width + X)) / 2#))
magnitude = temp.X ^ 2 + temp.Y ^ 2
If magnitude > max Then
grad.X = temp.X
grad.Y = temp.Y
max = magnitude
End If
End If
End If
Next X: Next Y
grad_T.X = grad.Y
grad_T.Y = -grad.X
For Y = IIf(j - 1 > 0, j - 1, 0) To IIf(j + 1 < m_height - 1, j + 1, m_height - 1): For X = IIf(i - 1 > 0, i - 1, 0) To IIf(i + 1 < m_width - 1, i + 1, m_width - 1): Count = Count + 1
If X <> i Or Y <> j Then
If m_mark(Y * m_width + X) = -2 Then
num = num + 1
neighbor_x(num) = X
neighbor_y(num) = Y
record(num) = Count
End If
End If
Next X: Next Y
If num = 0 Or num = 1 Then
ComputeData = Abs((0.6 * grad_T.X + 0.8 * grad_T.Y) / 255)
Else
n_x = neighbor_y(2) - neighbor_y(1)
n_y = neighbor_x(2) - neighbor_x(1)
square = CDbl(n_x ^ 2 + n_y ^ 2) ^ 0.5
ComputeData = Abs((IIf(n_x = 0, 0, n_x / square) * grad_T.X + IIf(n_y = 0, 0, n_y / square) * grad_T.Y) / 255)
End If
End Function
置信项C(p)可以被认为是围绕像素p的可靠信息量的量度。目的是首先填充那些已经填充了更多像素的色块,并优先考虑较早填充(或不属于目标区域的像素)的像素。
这会自动沿填充前端合并对某些形状的偏好。例如,包含目标区域的角和细卷须的色块将被首先填充,因为它们被原始图像中的更多像素包围。这些补丁程序提供了更可靠的信息来进行匹配。相反,突出到目标区域的已填充像素“半岛”尖端的补丁将被搁置一旁,直到更多周围像素被填充为止。在粗糙级别上,(1)的项C(p)大约为强制执行所需的同心填充顺序。
随着填充的进行,目标区域外层的像素将趋向于具有更大的置信度值,因此需要更早地填充。目标区域中心的像素将具有较小的置信度值。数据项D(p)是每次迭代中等渗线撞击前部δΩ的强度的函数。该术语提高了等渗线“流入”的贴片的优先级。这个因素在我们的算法中至关重要,因为它鼓励首先合成线性结构,然后安全地传播到目标区域中。折线趋于连接,从而实现了视觉心理学的“连接原理” [7] [17]。
填充顺序取决于图像属性,从而导致有机合成过程,消除了“结构破裂”伪影的风险,并且还减少了块状伪影,而无需进行昂贵的补丁切割步骤[9]或引起模糊的融合步骤[19] ]。
步骤2:传播纹理和结构信息
一旦计算了填充前沿(边界)上的所有优先级,便找到具有最高优先级的补丁Ψpˆ。然后,我们用从源区域Φ提取的数据填充它。我们通过直接采样源区域来传播图像纹理。类似于[10],我们在源区域中搜索与Ψpˆ最相似的补丁。正式地,
,在哪里
两个通用色块Ψa和Ψb之间的距离d(Ψa,Ψb)简单定义为两个色块中已经填充的像素的平方差之和(SSD)。在此步骤中,无需进行进一步的分析或处理(尤其是不模糊)。此计算在主循环循环中运行,并实现如下:
获得最高优先级:
For j = m_top To m_bottom: Jidx = j * m_width: For i = m_left To m_right
If m_mark(Jidx + i) = -2 And m_pri(Jidx + i) > max_pri Then
pri_x = i
pri_y = j
max_pri = m_pri(Jidx + i)
End If
Next i: Next j
查找最相似的补丁:
min = 99999999
For j = PatchT To PatchB: Jidx = j * m_width: For i = PatchL To PatchR
If m_source(Jidx + i) Then
sum = 0
For iter_y = -Winsize To Winsize: target_y = pri_y + iter_y
If target_y > 0 And target_y < m_height Then
target_y = target_y * m_width: For iter_x = -Winsize To Winsize: target_x = pri_x + iter_x
If target_x > 0 And target_x < m_width Then
Tidx = target_y + target_x
If m_mark(Tidx) >= 0 Then
source_x = i + iter_x
source_y = j + iter_y
Sidx = source_y * m_width + source_x
temp_r = m_r(Tidx) - m_r(Sidx)
temp_g = m_g(Tidx) - m_g(Sidx)
temp_b = m_b(Tidx) - m_b(Sidx)
sum = sum + temp_r * temp_r + temp_g * temp_g + temp_b * temp_b
End If
End If
Next iter_x
End If
Next iter_y
If sum < min Then: min = sum: patch_x = i: patch_y = j
End If
Next i: Next j
步骤3:更新置信度值
在用新的像素值填充块ΨpΨ之后,以thepˆ界定的区域中的置信度C(p)如下更新:
这个简单的更新规则使我们能够在没有图像特定参数的情况下测量填充前沿上色块的相对置信度。随着填充的进行,置信度值衰减,这表明我们不太确定目标区域中心附近的像素的颜色值。在此处实现(以及所有其他必要的更新):
x0 = -Winsize
For iter_y = -Winsize To Winsize: For iter_x = -Winsize To Winsize
x0 = patch_x + iter_x
y0 = patch_y + iter_y
x1 = pri_x + iter_x
y1 = pri_y + iter_y
X1idx = y1 * m_width + x1
If m_mark(X1idx) < 0 Then
X0idx = y0 * m_width + x0
PicAr1(x1, y1) = m_color(X0idx)
m_color(X1idx) = m_color(X0idx)
m_r(X1idx) = m_r(X0idx)
m_g(X1idx) = m_g(X0idx)
m_b(X1idx) = m_b(X0idx)
m_gray(X1idx) = CDbl((m_r(X0idx) * 3735 + m_g(X0idx) * 19267 + m_b(X0idx) * 9765) / 32767)
m_confid(X1idx) = ComputeConfidence(pri_x, pri_y)
End If
Next iter_x: Next iter_y
For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
m_mark(Yidx + X) = IIf(PicAr1(X, Y).rgbRed = MaskRed And PicAr1(X, Y).rgbgreen = MaskGreen And PicAr1(X, Y).rgbBlue = MaskBlue, -1, Source)
Next X: Next Y
For Y = IIf(pri_y - Winsize - 2 > 0, pri_y - Winsize - 2, 0) To IIf(pri_y + Winsize + 2 < m_height - 1, pri_y + Winsize + 2, m_height - 1): Yidx = Y * m_width: For X = IIf(pri_x - Winsize - 2 > 0, pri_x - Winsize - 2, 0) To IIf(pri_x + Winsize + 2 < m_width - 1, pri_x + Winsize + 2, m_width - 1)
If m_mark(Yidx + X) = -1 Then
Found = (Y = m_height - 1 Or Y = 0 Or X = 0 Or X = m_width - 1) Or m_mark(Yidx + X - 1) = Source Or m_mark(Yidx + X + 1) = Source Or m_mark((Y - 1) * m_width + X) = Source Or m_mark((Y + 1) * m_width + X) = Source
If Found Then: Found = False: m_mark(Yidx + X) = -2
End If
Next X: Next Y
For i = IIf(pri_y - Winsize - 3 > 0, pri_y - Winsize - 3, 0) To IIf(pri_y + Winsize + 3 < m_height - 1, pri_y + Winsize + 3, m_height - 1): Yidx = i * m_width: For j = IIf(pri_x - Winsize - 3 > 0, pri_x - Winsize - 3, 0) To IIf(pri_x + Winsize + 3 < m_width - 1, pri_x + Winsize + 3, m_width - 1)
If m_mark(Yidx + j) = -2 Then m_pri(Yidx + j) = ComputeConfidence(j, i) * ComputeData(j, i)
Next j: Next i
完整的代码
这是可运行的代码,并带有库的源代码作为注释。
该代码被调用
inpaint(infile, outfile, blocksize, windowsize, r, g, b)
例子包括以下形式
;~ inpaint("gothic_in.png", "gothic_out.png")
;~ inpaint("starry_in.png", "starry_out.png")
;~ inpaint("scream_in.png", "scream_out.png")
;~ inpaint("mona_in.png", "mona_out.png")
;~ inpaint("maze_in.png", "maze_out.png")
;~ inpaint("checker_in.png", "checker_out.png")
只是取消注释要使用CTRL+ 运行的示例Q。
官方测试文件
该算法由被调整为每个图像。因此,默认值(以及默认掩码)完全次优。选择默认值,以便可以在合理的时间内处理每个样本。我强烈建议使用形状不规则的口罩和更好的窗口尺寸。点击图片放大!
棋盘
→
美国哥特式
→
迷宫
→
蒙娜丽莎
→
(可怕的面具)
惊叫
→
星空
→
实际例子
这些都使用自定义手绘蒙版。
如果您想看到其他有趣的图像,请发表评论。
EBII改进
EBII有多种变体,由各种研究人员创建。AnkurKumar Patel收集了有关各种EBII改进的论文[24],引起了我的注意。
具体来说,论文“ 针对基于示例的图像修复的改进的鲁棒算法 ” [25]提到了优先权值加权的两个改进。
改善
有效修改在算法的第1步(请参见上文)中,并使用以下方法对此像素的优先级进行C(p)和D(p)扩展:
在式为C ^和d以上给出,并且分别是归一化因子(例如,α= 255),等照度线矢量,单位矢量正交于前在点p。
进一步,
优先级函数定义为正则化置信度C(p)和新数据项D(p)的权重之和。其中α是调整系数,定义为满足0Rp(p):
其中α和β分别是置信度和数据项的分量权重。注意,α+β= 1。
客观评分
但是,真正有趣的是,本文包含一种用于评估EBII算法性能的提议方法(并且很简单!)。不过,将其与一粒盐一起使用,因为这是论文作者自己选择的一种方法,目的是验证所提出的方差方法的有效性以及对若干图像的改进。
通过比较恢复图像和原始图像之间的PSNR(峰值信噪比[26])来执行结果评估。通常,PSNR值越高,修复后的图像与原始图像的相似度就越大。计算PSNR的公式如下:
这些是他们使用的惊人的2(两张!)真实世界测试图像:
结论与纸张本身的质量一样令人失望。它显示几乎没有改善。这里最主要的是针对此类挑战(以及其他图像修复挑战)的可能的对象评分方法:
+-------+---------------+----------+
| Image | EBII Original | Improved |
+-------+---------------+----------+
| 1 | 52.9556 | 53.7890 |
| 2 | 53.9098 | 53.8989 |
+-------+---------------+----------+
嗯
有待研究
(特定于EBII)
a)预处理
一切都归结为“魔术擦除”原理,即该算法应“对一切正常”。我对此的幼稚解决方案是基于颜色的放大(请参见上文),但是有更好的方法。我正在考虑识别所有可追踪纹理像素的几何平均值,以自动调整窗口大小,并使图章大小(也是我的改进)取决于纹理像素和整个图像的分辨率。研究必须在这里进行。
b)后处理
原始作者已经非常出色地将所有想到的后期处理过滤器拆封了。今天,我尝试了一些其他方法,受到了永远不可思议的蒙娜丽莎的启发(感谢undergroundmonorail)。如果仅拍摄已修复的区域,并对所有奇怪的颜色块应用新的蒙版,并将其输入去斑点算法,则结果几乎完美。我可能会在将来的某个时间进行探索。
[X] -A. Criminisi,P。Perez,K。Toyama通过基于示例的绘画移除对象
[1]-M. Ashikhmin。合成自然纹理。在过程中。ACM症状。互动3D图形,第217-226页,北卡罗莱纳州研究三角园,2001年3月。
[5] — M. Bertalmio,L。Vese,G。Sapiro和S. Osher。同时修复结构和纹理图像。出现,2002
[6] — R. Bornard,E。Lecan,L。Laborelli和JH。切诺特。静止图像和图像序列中缺少数据校正。在法国ACM多媒体公司,2002年12月。
[7] — TF Chan和J. Shen。通过曲率驱动的扩散(CDD)进行非纹理修补。J.视觉通讯。图片代表。,4(12),2001。
[8]-JS de Bonet。用于纹理图像分析和合成的多分辨率采样程序。在过程中。ACM Conf。比较 图形(SIGGRAPH),第31卷,第361–368页,1997年。
[9] — A. Efros和WT Freeman。图像缝,用于纹理合成和转移。在过程中。ACM Conf。比较 Graphics(SIGGRAPH),第341–346页,Eugene Fiume,2001年8月。
[10] — A. Efros和T. Leung。通过非参数采样进行纹理合成。在过程中。ICCV,第1033至1038页,希腊克尔基拉,1999年9月。
[11] — WT Freeman,EC Pasztor和OT Carmichael。学习低视力。诠释 J. Computer Vision,40(1):25-47,2000。
[12] — D. Garber。纹理分析和纹理合成的计算模型。博士论文,大学。美国南加州,1981年。
[13] —哈里森(P. Harrison)。用于重新合成复杂纹理的非分层过程。在过程中。诠释 Conf。中欧公司 图形,Visua。和比较。Vision,比尔森,捷克共和国,2001年2月。
[14] — DJ Heeger和JR Bergen。基于金字塔的纹理分析/合成。在过程中。ACM Conf。比较 图形(SIGGRAPH),第29卷,第229-233页,加利福尼亚州洛杉矶,1995年。
[15] — A. Hertzmann,C。Jacobs,N。Oliver,B。Curless和D. Salesin。图像类比。在过程中。ACM Conf。比较 Graphics(SIGGRAPH),Eugene Fiume,2001年8月。
[16] — H. Igehy和L. Pereira。通过纹理合成进行图像替换。在过程中。诠释 Conf。图像处理,第Ⅲ:186-190页,1997年。
[17] — G. Kanizsa。愿景中的组织。1979年,纽约普拉格。
[19] — L. Liang,C。Liu,Y.-Q。徐,郭宝和H.-Y. 嘘 通过基于补丁的采样进行实时纹理合成。在ACM Transactions on Graphics,2001年。
[22] — L.-W.。Wey和M. Levoy。使用树结构矢量量化进行快速纹理合成。在过程中。ACM Conf。比较 Graphics(SIGGRAPH),2000年。
[23] — A. Zalesny,V。Ferrari,G。Caenen和L. van Gool。并行复合纹理合成。在Texture 2002研讨会上-(与ECCV02结合使用),哥本哈根,丹麦,2002年6月。
[24] -AkurKumar Patel,古吉拉特理工大学,计算机科学和工程学
[25]- 改进的基于示例图像修补的鲁棒算法
[26]- 维基百科,峰值信噪比
inpaint.exe left top width height img.jpg
)吗?