2017-10-20 62 views
3

J'essaie de trouver la meilleure façon d'effectuer une sorte de convolution. J'ai une matrice 3D I = [N x M x P] et une matrice 2D S = [1 x 1 x K x P]. Pour chaque pth frame (troisième dimension) de ma matrice 3D, je veux retourner la convolution valide entre I (:,:, p-K/2: p + K/2) et S (1, 1,:, p). Voyez-vous un moyen de le faire?Meilleure façon d'effectuer une convolution avec un nouveau vecteur pour chaque image?

En fait, en termes de calcul du nombre d'opérations en très proche d'une convolution standard, la différence est que je dois changer la deuxième matrice pour chaque trame ...

C'est la méthode que je actuellement utiliser:

% I = 3D matrix [N x M x P] 
% S = Filter [1 x 1 x K x P] (K is an odd number) 
% OUT = Result 

[N, M, P] = size(I); % Data size 
K = size(S, 3); % Filter length 
win = (K-1)/2 ; % Window 
OUT = zeros(size(I)); % Pre-allocation 

for p = win+1:P-win 
    OUT(:, :, p) = convn(I(:, :, p-win:p+win), S(1, 1, :, p), 'valid'); % Perform convolution 
end 

à la fin, nous avons le même nombre d'opérations que la convolution standard, la seule différence est que le filtre est différent pour chaque trame ...

Toute idée?

Merci;)

Répondre

0

Donc, vous voulez convoluer une sous-image NxMxK ​​avec un noyau 1x1xKx1, et ne prennent que la partie valide, ce qui est une image NxM.

Regardons cette opération pour un emplacement unique (x, y). Cette convolution 1D, dont vous ne gardez 1 valeur est équivalente au produit scalaire de la sous-image et votre noyau:

OUT(x,y,p) = squeeze(I(x,y,p-win:p+win))' * squeeze(S(1,1,:,p)) 

Vous pouvez vectoriser dans l'ensemble (x, y) en remodelant la sous- image de I à une matrice (N * M) xK (le K est horizontal, S est un vecteur de colonne).

La répétition de ceci sur tout p est plus facile à implémenter avec une boucle, comme vous le faites maintenant. L'alternative est de créer un S plus grand où chaque colonne est décalée de un, de sorte que vous pouvez faire un seul produit scalaire entre les deux matrices. Mais que S est également créé pour créer, il faut probablement une boucle aussi. Je ne pense pas que le fait d'éviter les boucles soit plus pressant dans MATLAB (il est devenu beaucoup plus rapide au fil des années) et le produit lui-même est probablement la partie la plus coûteuse de l'algorithme.