2D convolution of 3D matrix slices

I'm trying to do a bunch of rolling sums over matrices in MATLAB. To avoid loops, I used repmat

to fold my 2D matrices into a 3D structure. However, now the fast fold feature conv2

can no longer be used for the accumulator. However, the N-dimensional convolution ( convn

) function is not what I'm looking for, as it literally folds all 3 dimensions. I want something that will do a 2D convolution on each slice and return a 3D matrix.

Overlaying matrices in 2D instead of splitting them in 3D won't work because it will mess up the convolution cases. I could have padded zeros between them, but then it starts to get messy.

In other words, without the for loop, how can I accomplish the following:

A = ones(5,5,5);
B = zeros(size(A));
for i = 1 : size(A, 3)
    B(:,:,i) = conv2(A(:,:,i), ones(2), 'same');
end

      

Thanks in advance for your help!

+3


source to share


2 answers


convn will work with n-dimensional matrix and 2-dimensional filter. Just:



A = ones(5,5,5);
B = convn(A, ones(2), 'same');

      

+6


source


You can use some padding with zeros

and the reshaping

same -

%// Store size parameters
[m,n,r] = size(A)  
[m1,n1] = size(kernel) 

%// Create a zeros padded version of the input array. We need to pad zeros at the end
%// rows and columns to replicate the convolutionoperation around those boundaries
Ap = zeros(m+m1-1,n+n1-1,r);
Ap(1:m,1:n,:) = A;

%// Reshape the padded version into a 3D array and apply conv2 on it and
%// reshape back to the original 3D array size
B_vect = reshape(conv2(reshape(Ap,size(Ap,1),[]),kernel,'same'),size(Ap))

%// Get rid of the padded rows and columns for the final output
B_vect = B_vect(1:m,1:n,:);

      



The basic idea is to convert the input 3D array to 2D array and then apply 2D convolution to it. An extra step is needed with padding to have the same behavior as you saw with conv2

around borders.

+3


source







All Articles