Image 用matlab修复图像

Image 用matlab修复图像,image,matlab,image-processing,interpolation,pixel,Image,Matlab,Image Processing,Interpolation,Pixel,我试图用邻域的平均值替换图像中具有特定值的所有像素。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); I

我试图用邻域的平均值替换图像中具有特定值的所有像素。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索引。是否有一种通用的方法将其合并到代码中


请帮忙

如果试图将图像中的像素替换为其4个相邻像素的平均值,则不必使用
interp2
。看起来您正在将图像的大小加倍,然后在完成后从该图像进行采样

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

但是,您需要考虑超出边界的像素。有很多方法可以适应这种情况,但我将实现的是零填充,其中边界像素仅设置为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的值。您可以使用来执行此操作,并确保指定
'same'
标志,以确保输出大小与输入大小相同。当您接近边界元素时,
conv2
的行为是零pad,这是我在第一个实现中已经做过的:

% 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));

我的+1表示卷积。卷积永远是答案。@Suever当然是@非常感谢。我做了interp2只是为了更接近数值。我尝试了卷积法——现在如果我试图在I1中找到零,它必须返回null,对吗?情况似乎并非如此。find(I1==0)返回索引列表。@它应该返回。我在几个测试图像上试过了。例如,尝试
I=重塑(1:25,5,5);I([2 6 10 19 24])=0然后使用上述代码进行修复。您将看到最终输出没有零。您可能没有设置所有零的原因是由于浮点精度。因此,与其精确地与0进行比较,不如找出某个公差范围内的值。。。也许是0.5左右。我无法判断它是否有效,因为您尚未提供要对其执行此操作的示例图像。@rayryeng-我已上载了一个测试图像,该方法在该图像上失败。足够高的阈值也不起作用。我真的很感谢你的帮助!在应用卷积之前,我将其转换为灰度。顺便说一下,fileexchange上有一个函数,