在一个流行的图像编辑软件中,有一个特性,即补丁(用于图像处理的术语是修复,如@mınxomaτ所指出的那样)。图像的选定区域,基于该修补程序之外的信息。而且它做得很好,考虑到这只是一个程序。作为一个人,你有时会看到一些不对劲的地方,但是如果你挤一下眼睛,或者只是看一眼,这个补丁似乎就能很好地填补这个空白。

给定指定图像矩形区域的图像和掩码应该进行修补(也可以作为图像或任何其他首选格式),您的程序应该尝试在指定的区域填充一个修补程序,试图将其与图像的其余部分混合。程序不能使用位于指定区域内的原始图像的信息。
你可以假设这个贴片至少它的宽度远离侧面,它的高度远离图像的顶部和底部。这意味着补丁的最大面积是整个图像的1/9。
请简单介绍一下你的算法是如何工作的。
投票人被要求判断算法执行得有多好,并据此投票。
关于如何判断的一些建议:(再次感谢@mınxomaτ提供更多的标准。)
为了使提交有效,输出映像必须与指定区域外的输入映像完全匹配。
在左侧的源图像上,在右侧对应的掩码:












发布于 2016-01-30 00:11:31
这是一种简单的插值方法。这个想法首先反映补丁两边的内容。然后,通过这些镜像像素离对应边缘的距离来插值:

最棘手的部分是找到一个很好的内插权重。在玩了几次之后,我想出了一个有理函数,除了我们镜像的那个外,所有边都是零。然后,用三次多项式来进行平滑:

这种简单的方法在“自然”图像上表现出奇的好,但一旦你面对锋利的边缘,游戏就结束了。在美国哥特式的例子中,干草叉的尖峰与像素网格很好地排列在一起,这使得它看起来相当漂亮,但如果不是这样的话,情况会更糟。
因此,这里的结果:






最后,守则:
imgfile= 'filename.png';
maskfile = [imgfile(1:end-4),'_mask.png'];
img = double(imread(imgfile));
mask = rgb2gray(imread(maskfile));
%% read mask
xmin = find(sum(mask,1),1,'first');
xmax = find(sum(mask,1),1,'last');
ymin = find(sum(mask,2),1,'first');
ymax = find(sum(mask,2),1,'last');
%% weight transformation functiosn
third = @(x)-2* x.^3 + 3* x.^2;
f=@(x)third(x);
w=@(x,y)y.*(x-1).*(y-1)./( (x+y).*(x+1-y));
for x=xmin:xmax
for y=ymin:ymax
%Left Right Up Down;
P = [img(y,xmin-(x-xmin)-1,:);img(y,xmax+(xmax-x)+1,:);img(ymin-(y-ymin)-1,x,:);img(ymax+(ymax-y)+1,x,:)];
% normalize coordinates
rx = (x-xmin)/(xmax-xmin);
ry = (y-ymin)/(ymax-ymin);
% calculate the weights
W = [w(rx,ry),w(1-rx,ry),w(ry,rx),w(1-ry,rx)]';
W = f(W);
W(isnan(W))=1;
img(y,x,:) = sum(bsxfun(@times,P,W),1)/sum(W);
end
end
imshow(img/255);
imwrite(img/255,[imgfile(1:end-4),'_out.png']);发布于 2016-01-30 21:54:53
它使用Mathematica的Inpaint函数。因为Mathematica自己做所有的工作,这是一个社区wiki。
inPaint (以下)是Inpaint的简单改编。对于彩色绘画/照片,它使用默认的"TextureSynthesis“设置。如果它检测到图片是黑白的(因为图片的图像数据与图像的二进制格式的图像数据相同),那么它就对图像进行二值化,并应用"TotalVariation“补丁。If子句将Binarize或Identity应用于图片。( Identity函数不改变地返回其参数。)
inPaint[picture_, mask_] :=
If[bw = ImageData@Rasterize[Binarize[picture]] == ImageData[picture], Binarize, Identity]@
Inpaint[picture, mask, Method -> If[bw, "TotalVariation", "TextureSynthesis"]]图像和掩码作为inPaint的参数输入。Partition和Grid只是用来格式化的。

产出已得到修补。inPaint后未进行图像修整。

发布于 2016-01-30 09:14:11
该程序混合了北、南、东和西区域的副本,以创建使用颜色、纹理和地方图像区域阴影的替换像素。
该示例输出:






代码首先找到修补程序的边界框。然后,对于要生成的每个像素,根据周围4个区域的加权和计算每个通道(RGB)的颜色。
import sys
from PIL import Image
infile, maskfile, outfile = sys.argv[1:4]
imageobj = Image.open(infile)
maskobj = Image.open(maskfile)
image = imageobj.load()
mask = maskobj.load()
assert imageobj.size == maskobj.size
W, H = imageobj.size
pixels = [(x,y) for x in range(W) for y in range(H)]
whitepart = [xy for xy in pixels if sum(mask[xy]) > 230*3]
xmin = min(x for x,y in whitepart)
xmax = max(x for x,y in whitepart)
ymin = min(y for x,y in whitepart)
ymax = max(y for x,y in whitepart)
xspan = xmax - xmin + 1
yspan = ymax - ymin + 1
def mkcolor(channel):
value = image[(xmin-dx, y)][channel] * 0.5*(xspan - dx)/xspan
value += image[(xmax+1 + xspan - dx, y)][channel] * 0.5*dx/xspan
value += image[(x, ymin-dy)][channel] * 0.5*(yspan - dy)/yspan
value += image[(x, ymax+1 + yspan - dy)][channel] * 0.5*dy/yspan
return int(value)
for dx in range(xspan):
for dy in range(yspan):
x = xmin + dx
y = ymin + dy
image[(x, y)] = (mkcolor(0), mkcolor(1), mkcolor(2))
imageobj.save(outfile)https://codegolf.stackexchange.com/questions/70483
复制相似问题