如果您尝试将图像中某个值的像素替换为其 4 个相邻像素的平均值,则不必使用interp2。看起来您将图像的大小加倍,然后在完成后从该图像中采样。
如果您想按照您的要求进行操作,您需要使用列主索引来促进像素的矢量化访问。具体来说,您需要使用sub2ind 来帮助确定您需要在矩阵中访问的位置。
但是,您需要考虑超出范围的像素。有很多方法可以适应这种情况,但我将实现的称为 zero-padding,其中边框像素简单地设置为 0。我将创建一个零填充图像,其中顶部和底部行以及左右值都是一些标记值(如-1),在此图像上使用find找到坐标然后进行修复。确保在执行此操作之前将边框像素设置回 0,以免在修复过程中使用 -1。完成后,您将裁剪此新图像的边框像素以获得最终输出图像。
因此,如果您想执行“修复”,请尝试以下操作:
% Read in image
I = imread('test_image.JPG');
% Create padded image with border pixels set to -1
Ipad = -ones(size(I) + 2);
% Place image in the middle
Ipad(2:end-1,2:end-1) = I;
% Find zero pixels
[r,c] = find(I == 0);
% Now set border pixels to 0
Ipad(Ipad == -1) = 0;
% Find column major indices for those elements that are 0
% as well as their 4 neighbours
ind = sub2ind(size(I), r, c);
ind_up = sub2ind(size(I), r-1, c);
ind_down = sub2ind(size(I), r+1, c);
ind_left = sub2ind(size(I), r, c-1);
ind_right = sub2ind(size(I), r, c+1);
% Perform the inpainting by averaging
Ipad(ind) = (Ipad(ind_up) + Ipad(ind_down) + Ipad(ind_left) + Ipad(ind_right))/4;
% Store the output in I1 after removing border pixels
I1 = Ipad(2:end-1,2:end-1);
但是,即使您要对整个图像进行操作,执行此操作的一种可能更短的方法是使用 3 x 3 内核执行 2D 卷积,其元素在基数方向上为 1,并确保除以 4 以找到每个位置的平均值。之后,您只需复制输出中原始图像中为 0 的值。您可以使用conv2 来执行此操作,并确保指定'same' 标志以确保输出大小与输入大小相同。 conv2 在您接近边框元素时的行为是零填充,这是我在第一个实现中所做的:
% Read in image
I = imread('test_image.JPG');
% Specify kernel
kernel = [0 1 0; 1 0 1; 0 1 0] / 4;
% Perform convolution - make sure you cast image to double
% as convolution in 2D only works for floating-point types
out = conv2(double(I), kernel, 'same');
% Copy over those values from the output that match the value
% to be inpainted for the input. Also cast back to original
% data type.
I1 = I;
I1(I == 0) = cast(out(I == 0), class(I));