简体   繁体   English

不使用conv2的Matlab图像过滤

[英]Matlab image filtering without using conv2

I've been given a task to create image filtering function for 3x3 matrices, and its outcome must be equal to conv2's. 我被赋予了为3x3矩阵创建图像过滤功能的任务,其结果必须等于conv2。 I have written this function, but it filters image incorrectly: 我写了这个函数,但是它错误地过滤了图像:

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

Filtration matrix is [3,10,3;0,0,0;-3,-10,-3] 过滤矩阵为[3,10,3; 0,0,0; ​​-3,-10,-3]

Please help to figure out what is wrong with my code. 请帮助弄清楚我的代码有什么问题。

Some sample results I get between conv2 and my code are seen below. 我在conv2和我的代码之间得到的一些示例结果如下所示。

图像处理结果

First off, this line doesn't make sense: 首先,这条线没有意义:

i=1:1:length;

I think you meant to use len instead of length as the ending index: 我认为你的意思是使用len而不是length作为结束索引:

i=1:1:len;

Now referring to your code, it is correct, but what you are doing is correlation not convolution. 现在提到你的代码,它是正确的,但你正在做的是相关而不是卷积。 In 2D convolution, you have to perform a 180 degree rotation of the kernel / mask and then do the weighted sum. 在2D卷积中,您必须执行内核/掩码的180度旋转,然后执行加权求和。 As such, if you want to achieve the same results using conv2 , you must pre-rotate the mask before calling it. 因此,如果要使用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 contains the 180 degree rotated kernel. mask_flip包含180度旋转的内核。 We use the 'same' flag to ensure that the output size of the result is the same size as the input. 我们使用'same'标志来确保结果的输出大小与输入的大小相同。 However, when using conv2 , we are assuming that the borders of the image are zero-padded. 但是,当使用conv2 ,我们假设图像的边框是零填充的。 Your code simply copies the border pixels of the original image into the resulting image. 您的代码只是将原始图像的边框像素复制到生成的图像中。 This is known as replicating behaviour but that is not what conv2 does natively. 这被称为复制行为,但这不是conv2行为。 conv2 assumes that the border pixels are zero-padded as I mentioned before, so what I would suggest you do is create two additional images, one being the output image that has 2 more rows and 2 more columns and another being the input image that is the same size as the output image but you place the input image inside this matrix. conv2假设边框像素是我前面提到的零填充,所以我建议你做的是创建两个额外的图像,一个是输出图像,其中有2行多2列,另一个是输入图像,与输出图像大小相同,但您将输入图像放在此矩阵中。 Next, perform the filtering on this new image, place the resulting filtered pixels in the output image then crop this result. 接下来,对此新图像执行过滤,将生成的过滤像素放在输出图像中,然后裁剪此结果。 I've decided to create a new padded input image in order to keep most of your code intact. 我决定创建一个新的填充输入图像,以保持大部分代码完好无损。

I would also recommend that you abolish the use of length here. 我还建议你在这里取消length的使用。 Use size instead to determine the image dimensions. 使用size来确定图像尺寸。 Something like this will work: 这样的东西会起作用:

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

To compare, I've generated this random matrix: 为了比较,我已经生成了这个随机矩阵:

>> 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

Now running with what we talked about above: 现在运行我们上面谈到的内容:

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

We get the following for your function and the output of conv2 : 我们为您的函数和conv2的输出得到以下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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM