12
$\begingroup$

I want to find a convolution matrix for a certain 2D kernel $ H $.
For example, for image Img of size $ m \times n $ , I want (in MATALB):

T * Img = reshape(conv2(Img, H, 'same'), [], 1);

Where T is the convolution matrix and same means the Convolution Shape (Output Size) matched the input size.

Theoretically, H should be converted to a toeplitz matrix, I'm using the MATLAB function convmtx2():

T = convmtx2(H, m, n);

Yet T is of size $ (m+2) (n+2) \times (mn) $ as MATLAB's convmtx2 generates a convolution matrix which matches Convolution Shape of full.

Is there a way to generate the Convolution Matrix which matches using conv2() with the same convolution shape parameter?

$\endgroup$
3
  • $\begingroup$ Are you looking simply to get the same resultant T*Img or you would like to use T for a different purpose? $\endgroup$
    – Charna
    Commented Mar 28, 2012 at 19:01
  • $\begingroup$ I edited your code and maths so it looks more atractive. You can do this yourself on future questions. For Latex editing use $$. $\endgroup$
    – Jav_Rock
    Commented Jun 29, 2012 at 13:18
  • $\begingroup$ Related question - dsp.stackexchange.com/questions/17418. $\endgroup$
    – Royi
    Commented Jan 17, 2019 at 8:58

2 Answers 2

5
$\begingroup$

I cannot test this on my computer because I do not have the convtmx2 function, here is what the MATLAB help says:

http://www.mathworks.com/help/toolbox/images/ref/convmtx2.html

T = convmtx2(H,m,n) returns the convolution matrix T for the matrix H. If X is an m-by-n matrix, then reshape(T*X(:),size(H)+[m n]-1) is the same as conv2(X,H).

This would get the same resulting convolution of conv2(X,H) but then you would still have to pull out the correct piece of the convolution.

$\endgroup$
2
  • $\begingroup$ Welcome to DSP.SE, and this is a great answer! $\endgroup$
    – Phonon
    Commented Mar 29, 2012 at 2:37
  • $\begingroup$ I think that sometimes one needs the actual matrix to analyze it (The adjoint operator, the inverse, etc...). Hence this method won't work (Unless you start removing rows form the matrix which will be slow as it is Sparse). $\endgroup$
    – Royi
    Commented Jan 17, 2019 at 15:05
0
$\begingroup$

I wrote a function which solves this in my StackExchange Codes StackOverflow Q2080835 GitHub Repository (Have a look at StackOverflow\Q2080835 folder for a file named CreateImageConvMtx()).
Actually the function can support any convolution shape you'd like - full, same and valid.

The code is as following:

function [ mK ] = CreateImageConvMtx( mH, numRows, numCols, convShape )

CONVOLUTION_SHAPE_FULL  = 1;
CONVOLUTION_SHAPE_SAME  = 2;
CONVOLUTION_SHAPE_VALID = 3;

switch(convShape)
    case(CONVOLUTION_SHAPE_FULL)
        % Code for the 'full' case
        convShapeString = 'full';
    case(CONVOLUTION_SHAPE_SAME)
        % Code for the 'same' case
        convShapeString = 'same';
    case(CONVOLUTION_SHAPE_VALID)
        % Code for the 'valid' case
        convShapeString = 'valid';
end

mImpulse = zeros(numRows, numCols);

for ii = numel(mImpulse):-1:1
    mImpulse(ii)    = 1; %<! Create impulse image corresponding to i-th output matrix column
    mTmp            = sparse(conv2(mImpulse, mH, convShapeString)); %<! The impulse response
    cColumn{ii}     = mTmp(:);
    mImpulse(ii)    = 0;
end

mK = cell2mat(cColumn);


end

Enjoy...

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.