Générer la matrice de convolution du noyau 2D pour la forme de convolution de «même»

10

Je veux trouver une matrice de convolution pour un certain noyau 2D . Par exemple, pour une image de taille , je veux (en MATALB):H
Imgm×n

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

Test la matrice de convolution et samesignifie que la forme de convolution (taille de sortie) correspond à la taille d'entrée.

Théoriquement, H devrait être converti en matrice toeplitz, j'utilise la fonction MATLAB convmtx2():

T = convmtx2(H, m, n);

Pourtant, il Test de taille car MATLAB génère une matrice de convolution qui correspond à la forme de convolution de .(m+2)(n+2)×(mn)convmtx2full

Existe-t-il un moyen de générer la matrice de convolution qui correspond à l'utilisation conv2()avec le sameparamètre de forme de convolution?

matlabit
la source
Cherchez-vous simplement à obtenir le même T * Img résultant ou souhaitez-vous utiliser T à des fins différentes?
Charna
J'ai modifié votre code et vos maths pour qu'il soit plus attrayant. Vous pouvez le faire vous-même sur les questions futures. Pour l'édition au latex, utilisez $$.
Jav_Rock
Question connexe - dsp.stackexchange.com/questions/17418 .
Royi

Réponses:

5

Je ne peux pas tester cela sur mon ordinateur car je n'ai pas la fonction convtmx2, voici ce que dit l'aide MATLAB:

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

T = convmtx2(H,m,n)renvoie la matrice de convolution Tpour la matrice H. Si Xest une matrice m par n, alors reshape(T*X(:),size(H)+[m n]-1)c'est la même chose que conv2(X,H).

Cela obtiendrait la même convolution résultante de conv2(X,H)mais il vous faudrait alors retirer la bonne pièce de la convolution.

Charna
la source
Bienvenue sur DSP.SE, et c'est une excellente réponse!
Phonon
Je pense que parfois on a besoin de la matrice réelle pour l'analyser (l'opérateur adjoint, l'inverse, etc ...). Par conséquent, cette méthode ne fonctionnera pas (sauf si vous commencez à supprimer des lignes de la matrice qui sera lente car elle est clairsemée).
Royi
1

J'ai écrit une fonction qui résout ce problème dans mon référentiel GitHub StackOverflow Q2080835 (jetez un œil à CreateImageConvMtx()).
En fait, la fonction peut prendre en charge n'importe quelle forme de convolution que vous souhaitez - full, sameet valid.

Le code est le suivant:

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

Prendre plaisir...

Royi
la source