修复图片matlab

时间:2016-06-02 18:09:19

标签: image matlab image-processing interpolation pixel

test image

我正在尝试使用邻居的平均值替换图像中具有特定值的所有像素。 interp2可以在这里有用吗?我试过了 -

I = imread('test_image.JPG');
[r c] = size(I);
class_of_image = class(I);
[xi,yi] = meshgrid(1:0.5:c,1:0.5:r);
I1 = cast(interp2(double(image),xi,yi,'linear'),class_of_image);

[x_z,y_z] = find(I1==0);
I1(x_z,y_z) = I1(x_z-1,y_z)+I1(x_z+1,y_z)+I1(x_z,y_z-1)+I1(x_z,y_z+1);

这会出现错误消息 - 索引超出矩阵维度。

我意识到错误在于尝试访问超出r和c的I1索引。是否有通用的方法将其合并到代码中?

请帮忙!

1 个答案:

答案 0 :(得分:2)

如果您尝试将图像中具有特定值的像素替换为其4个邻居的平均值,则不必使用interp2。看起来你正在将图像的大小加倍,然后在完成后从该图像中取样。

如果你想做你想要的,你需要使用列主要索引来促进像素的矢量化访问。具体而言,您需要使用sub2ind来帮助确定您需要在矩阵中访问的位置。

但是,您需要考虑超出范围的像素。有很多方法可以适应这种情况,但我将实现的是零填充,其中边框像素只是设置为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));