2017-10-20 102 views
3

我试图找出执行一种卷积的最佳方式。我有一个3D矩阵I = [N×M×P]和一个2D矩阵S = [1×1×K×P]。对于我3D矩阵的每个第p帧(第三维),我想返回I(:,:,p-K/2:p + K/2)和S(1,1,:,p)之间的有效卷积。你有没有办法做到这一点?为每个图像执行新矢量卷积的最佳方法?

事实上,在计算操作的非常接近一个标准卷积数量来看,所不同的是,我需要改变每一帧的第二矩阵...

这是我的方法目前使用方法:

% 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 

在我们有相同数量比标准卷积运算结束,唯一的区别是,过滤器是针对每帧不同...

任何想法?

感谢;)

回答

0

所以,你想一个卷积NxMxK子图像与1x1xKx1内核,然后只需要有效的部分,这是一个N×M的图像。

让我们来看看单个(x,y)位置的这个操作。通过重塑子

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

这个你可以在所有(X,Y)矢量化:这1D卷积,而你只保留1个值,相当于子图像的点积和内核I的图像映射到(N * M)xK矩阵(K是水平的,S是列向量)。

在所有p中重复此操作最容易实现一个循环,就像现在一样。另一种方法是创建一个更大的S,其中每列移动一个,因此您可以在两个矩阵之间做单点积。但是,S的创建成本也很高,大概需要一个循环。我不认为避免循环是在MATLAB中再次强调(多年来它的速度要快得多),而且产品本身可能是算法中最昂贵的部分。