[英]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.