Gere a matriz de convolução do kernel 2D para o formato de convolução do `same`

10

Eu quero encontrar uma matriz de convolução para um determinado 2D do kernel H .
Por exemplo, para imagem Imgde tamanho m×n , desejo (em MATALB):

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

Onde Testá a matriz de convolução e samesignifica que a Forma da convolução (tamanho da saída) corresponde ao tamanho da entrada.

Teoricamente, H deve ser convertido em uma matriz toeplitz, estou usando a função MATLAB convmtx2():

T = convmtx2(H, m, n);

No entanto, Té de tamanho (m+2)(n+2)×(mn) pois o MATLAB convmtx2gera uma matriz de convolução que corresponde à Forma de Convolução de full.

Existe uma maneira de gerar a matriz de convolução que corresponda ao uso conv2()com o sameparâmetro de forma de convolução?

matlabit
fonte
Você está procurando simplesmente obter o mesmo T * Img resultante ou gostaria de usar o T para uma finalidade diferente?
Charna 28/03/12
Eu editei seu código e matemática para que pareça mais atraente. Você pode fazer isso sozinho em perguntas futuras. Para edição de látex, use $$.
Jav_Rock
Pergunta relacionada - dsp.stackexchange.com/questions/17418 .
Royi 17/01/19

Respostas:

5

Não posso testar isso no meu computador porque não tenho a função convtmx2. Aqui está o que a ajuda do MATLAB diz:

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

T = convmtx2(H,m,n)retorna a matriz de convolução Tpara a matriz H. Se Xé uma matriz m por n, reshape(T*X(:),size(H)+[m n]-1)é o mesmo que conv2(X,H).

Isso obteria a mesma convolução resultante de, conv2(X,H)mas você ainda teria que retirar a parte correta da convolução.

Charna
fonte
Bem-vindo ao DSP.SE, e esta é uma ótima resposta!
Phonon
Eu acho que às vezes é preciso a matriz real para analisá-la (o operador adjacente, o inverso, etc ...). Portanto, esse método não funcionará (a menos que você comece a remover linhas da matriz, a qual será lenta como esparsa).
Royi 17/01/19
1

Eu escrevi uma função que resolve isso no meu repositório StackOverflow Q2080835 GitHub (Dê uma olhada CreateImageConvMtx()).
Na verdade, a função pode suportar qualquer formato de convolução que você queira - full, samee valid.

O código é o seguinte:

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

Aproveitar...

Royi
fonte