不使用conv2的Matlab图像过滤

时间:2016-02-16 17:42:58

标签: image matlab image-processing filtering convolution

我已经完成了为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和我的代码之间得到的一些示例结果如下所示。

Image processing results

1 个答案:

答案 0 :(得分:5)

首先,这条线没有意义:

i=1:1:length;

我认为您打算使用len代替length作为结束索引:

i=1:1:len;

现在提到你的代码,它是正确的,但你正在做的是相关而不是卷积。在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