不使用 conv2 的 Matlab 图像滤波

Matlab image filtering without using conv2

我接到一个任务,要为 3x3 矩阵创建图像过滤函数,其结果必须等于 conv2 的结果。我写了这个函数,但是它过滤图像不正确:

function [ image ] = Func134( img,matrix )
  image=img;
  len=length(img)
  for i=2:1:len-1
    for j=2:1:len-1
      value=0;
      for g=-1:1:1
        for l=-1:1:1
          value=value+img(i+g,j+l)*matrix(g+2,l+2);
        end
      end
     image(i,j)=value;
    end
  end
i=1:1:length
image(i,1)=image(i,2)
image(i,len)=image(i,len-1)
image(1,i)=image(2,i)
image(len,i)=image(len-1,i)
end

过滤矩阵为[3,10,3;0,0,0;-3,-10,-3]

请帮助找出我的代码有什么问题。

我在 conv2 和我的代码之间得到的一些示例结果如下所示。

首先,这一行没有意义:

i=1:1:length;

我认为您打算使用 len 而不是 length 作为结束索引:

i=1:1:len;

现在参考你的代码,它是正确的,但是你做的是correlation而不是卷积。在 2D 卷积中,您必须对内核/掩码执行 180 度旋转,然后进行加权求和。因此,如果您想使用 conv2 获得相同的结果,您 必须 在调用之前预先旋转遮罩。

mask = [3,10,3;0,0,0;-3,-10,-3]
mask_flip = mask(end:-1:1,end:-1:1);
out = conv2(img, mask, 'same');

mask_flip 包含 180 度旋转的内核。我们使用 'same' 标志来确保结果的输出大小与输入大小相同。然而,当使用 conv2 时,我们假设图像的边界是零填充的。您的代码只是将原始图像的边界像素复制到生成的图像中。这被称为复制行为,但这不是 conv2 的本机行为。 conv2 假设边界像素像我之前提到的那样被零填充,所以我建议你做的是创建两个额外的图像,一个是输出图像,它有 2 行和 2 列,另一个是输入图像与输出图像大小相同,但您将输入图像放在该矩阵内。接下来,对这个新图像执行过滤,将得到的过滤像素放在输出图像中,然后裁剪这个结果。我决定创建一个新的填充输入图像,以保持您的大部分代码完好无损。

我还建议您在这里取消使用 length。请改用 size 来确定图像尺寸。这样的事情会起作用:

function [ image ] = Func134( img,matrix )
  [rows,cols] = size(img); %// Change

  %// New - Create a padded matrix that is the same class as the input
  new_img = zeros(rows+2,cols+2);
  new_img = cast(new_img, class(img));

  %// New -  Place original image in padded result
  new_img(2:end-1,2:end-1) = img;

  %// Also create new output image the same size as the padded result
  image = zeros(size(new_img));
  image = cast(image, class(img));

  for i=2:1:rows+1 %// Change
    for j=2:1:cols+1 %// Change
      value=0;
      for g=-1:1:1
        for l=-1:1:1
          value=value+new_img(i+g,j+l)*matrix(g+2,l+2); %// Change
        end
      end
     image(i,j)=value;
    end
  end

%// Change
%// Crop the image and remove the extra border pixels
image = image(2:end-1,2:end-1);
end

为了比较,我生成了这个随机矩阵:

>> rng(123);
>> A = rand(10,10)

A =

    0.6965    0.3432    0.6344    0.0921    0.6240    0.1206    0.6693    0.0957    0.3188    0.7050
    0.2861    0.7290    0.8494    0.4337    0.1156    0.8263    0.5859    0.8853    0.6920    0.9954
    0.2269    0.4386    0.7245    0.4309    0.3173    0.6031    0.6249    0.6272    0.5544    0.3559
    0.5513    0.0597    0.6110    0.4937    0.4148    0.5451    0.6747    0.7234    0.3890    0.7625
    0.7195    0.3980    0.7224    0.4258    0.8663    0.3428    0.8423    0.0161    0.9251    0.5932
    0.4231    0.7380    0.3230    0.3123    0.2505    0.3041    0.0832    0.5944    0.8417    0.6917
    0.9808    0.1825    0.3618    0.4264    0.4830    0.4170    0.7637    0.5568    0.3574    0.1511
    0.6848    0.1755    0.2283    0.8934    0.9856    0.6813    0.2437    0.1590    0.0436    0.3989
    0.4809    0.5316    0.2937    0.9442    0.5195    0.8755    0.1942    0.1531    0.3048    0.2409
    0.3921    0.5318    0.6310    0.5018    0.6129    0.5104    0.5725    0.6955    0.3982    0.3435

现在运行我们上面谈到的:

mask = [3,10,3;0,0,0;-3,-10,-3];
mask_flip = mask(end:-1:1,end:-1:1);
B = Func134(A,mask);
C = conv2(A, mask_flip,'same');

我们得到以下函数和 conv2 的输出:

>> B

B =

   -5.0485  -10.6972  -11.9826   -7.2322   -4.9363  -10.3681  -10.9944  -12.6870  -12.5618  -12.0295
    4.4100    0.1847   -2.2030   -2.7377    0.6031   -3.7711   -2.5978   -5.8890   -2.9036    2.7836
   -0.6436    6.6134    4.2122   -0.7822   -2.3282    1.6488    0.4420    2.2619    4.2144    3.2372
   -4.8046   -1.0665    0.1568   -1.5907   -4.6943    0.3036    0.4399    4.3466   -2.5859   -3.4849
   -0.7529   -5.5344    1.3900    3.1715    2.9108    4.6771    7.0247    1.7062   -3.9277   -0.6497
   -1.9663    2.4536    4.2516    2.2266    3.6084    0.6432   -1.0581   -3.4674    5.3815    6.1237
   -0.9296    5.1244    0.8912   -7.7325  -10.2260   -6.4585   -1.4298    6.2675   10.1657    5.3225
    3.9511   -1.7869   -1.9199   -5.0832   -3.2932   -2.9853    5.5304    5.9034    1.4683   -0.7394
    1.8580   -3.8938   -3.9216    3.8254    5.4139    1.8404   -4.3850   -7.4159   -4.9894   -0.5096
    6.4040    7.6395    7.3643   11.8812   10.6537   10.8957    5.0278    3.0277    4.2295    3.3229

>> C

C =

   -5.0485  -10.6972  -11.9826   -7.2322   -4.9363  -10.3681  -10.9944  -12.6870  -12.5618  -12.0295
    4.4100    0.1847   -2.2030   -2.7377    0.6031   -3.7711   -2.5978   -5.8890   -2.9036    2.7836
   -0.6436    6.6134    4.2122   -0.7822   -2.3282    1.6488    0.4420    2.2619    4.2144    3.2372
   -4.8046   -1.0665    0.1568   -1.5907   -4.6943    0.3036    0.4399    4.3466   -2.5859   -3.4849
   -0.7529   -5.5344    1.3900    3.1715    2.9108    4.6771    7.0247    1.7062   -3.9277   -0.6497
   -1.9663    2.4536    4.2516    2.2266    3.6084    0.6432   -1.0581   -3.4674    5.3815    6.1237
   -0.9296    5.1244    0.8912   -7.7325  -10.2260   -6.4585   -1.4298    6.2675   10.1657    5.3225
    3.9511   -1.7869   -1.9199   -5.0832   -3.2932   -2.9853    5.5304    5.9034    1.4683   -0.7394
    1.8580   -3.8938   -3.9216    3.8254    5.4139    1.8404   -4.3850   -7.4159   -4.9894   -0.5096
    6.4040    7.6395    7.3643   11.8812   10.6537   10.8957    5.0278    3.0277    4.2295    3.3229