How to convolve two matrices with different sizes?

I would like to filter a 2D image with a Gaussian by convolving them. The convolution must be done without using conv, conv2 ... functions.
The matrix image is not squared.
How could I implement this convolution?
Thanks in advanced
Help ASAP

5 Comments

habe you already done a convolution in 1d? it's the same but you shift the signals in two directions, overlap them, multiply and add the entries. normally you can assume 0 outside the normal image bounds, but that's a question of definition
Unfortunatly, I don't know how perform the 1D convolution. I am new to Matlab. Could you give a hint? My first Matrix is 420x500 and the kernel is 21x21. Thank you very much.
Jonas
Jonas on 3 May 2021
Edited: Jan on 3 May 2021
if you are interested just in the solution, you can have a look into https://de.mathworks.com/matlabcentral/answers/22358-how-to-do-convolution-without-commands
if you want to understand how convolution works, then i sughest you start with having a look into manual 1d convolution. you can search in this forum, there are multiple questions about that topic
Thank you very much. Now I understand how the convolution works for 2D using the following code:
Nevertheless, could you be able to explain me what Rep is used for? It is not very clear for me :(
Tremendous thanks. You will save my life
The code is copied below:
function B = convolve(A, k);
[r c] = size(A);
[m n] = size(k);
h = rot90(k, 2);
center = floor((size(h)+1)/2);
left = center(2) - 1;
right = n - center(2);
top = center(1) - 1;
bottom = m - center(1);
Rep = zeros(r + top + bottom, c + left + right);
for x = 1 + top : r + top
for y = 1 + left : c + left
Rep(x,y) = A(x - top, y - left);
end
end
B = zeros(r , c);
for x = 1 : r
for y = 1 : c
for i = 1 : m
for j = 1 : n
q = x - 1;
w = y -1;
B(x, y) = B(x, y) + (Rep(i + q, j + w) * h(i, j));
end
end
end
end
Jonas
Jonas on 3 May 2021
Edited: Jonas on 3 May 2021
Rep is you original image which is padded with 0 on all four sides of the image. it is padded about half height of k at bottom and top and about half width of k at the left and right. this is necessary because when you convolve, your signals become bigger compared to the original. it just like in 1d convolution if you convolve e.g. [1 2 3 4] with [3 8 5] the resulting signal will have length 6 which is longer than both input signals.

Sign in to comment.

Answers (1)

There's no reason to be looping over the kernel like that. Let's say you wanted to replicate the behavior of conv2:
inpict = im2double(rgb2gray(imread('peppers.png')));
fk=fkgen('gaussian',20); % filter kernel
example=conv2(inpict,fk); % example to test against
% get sizes
s0 = [size(inpict,1) size(inpict,2)];
sfk = [size(fk,1) size(fk,2)];
s = s0 + 2*(sfk-1);
% pad the array with zeros
padded = zeros(s);
padded(sfk(1):(end-sfk(1)+1),sfk(2):(end-sfk(2)+1)) = inpict;
% flip the kernel (this is convolution, not correlation)
fk = rot90(fk,2);
fk = fk(:);
% preallocate full-size output
% by default, conv2 does the same
outpict = zeros(sfk(1)+s0(1)-1,s0(2)+sfk(2)-1);
for m = 1:s(1)-sfk(1)+1
for n = 1:s(2)-sfk(2)+1
sample = padded(m:m+sfk(1)-1,n:n+sfk(2)-1);
outpict(m,n) = sample(:)'*fk;
end
end
% measure error between our method and conv2
immse(example,outpict)
If instead you wanted to work a bit more like imfilter(), there are some considerations
  • By default, imfilter() zero-pads, but this causes vingetting. It's often desirable to use edge replication instead. You could use padarray() to do either.
  • By default, imfilter() uses correlation, so the filter isn't rotated. For symmetric filters, there isn't a difference, but it's something to keep in mind if compatibility matters.
  • By default, imfilter() returns the central area equal to the original image geometry. You'd just have to change the range of indices your filter slides over to change the output array. Otherwise you can just convolve the whole thing and crop off the excess.

Answered:

DGM
on 3 May 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!