我想在MATLAB中实现信号的2d内核卷积。这基本上是信号(非图像)的非线性二次滤波器,如下面的公式所述:
其中k2(t1,t2)是二维卷积核。 x是1d [N,1]信号矢量& y是输出[N,1]信号。
到目前为止,我一直以非常蛮力,非优雅的方式做到这一点。我想知道我是否可以使用MATLAB filter2
/ conv2
函数来更有效地执行此操作!我知道这些功能是用于图像处理的,我不太了解,所以我希望有人可以提供帮助!
答案 0 :(得分:1)
可能如下
y=diag(conv2(k,x*x.'));
或
y=diag(conv2(x,x,k));
答案 1 :(得分:1)
使用diag(conv2(x,x,k));
时的问题是你正在计算更大的东西(整个2d矩阵),然后你只保留对角线。根据信号的大小,它可能很昂贵。您可以尝试使用
n = 500; m = 50;
x = rand(n,1);
k2 = rand(m,m);
tic; res1 = diag(conv2(x,x,k2)); toc;
tic;
res2 = zeros(n+m-1,1);
for k = 1:n+m-1
imin = k+1-min(k,m); imax = min(k,n);
jmin = max(1,k-n+1); jmax = min(k,m);
res2(k) = x(imax:-1:imin)'*k2(jmin:jmax,jmin:jmax)*x(imax:-1:imin);
end
toc;
norm(res1-res2)
在我尝试过的很多情况下,它的工作速度比其他选项快。例如,一个输出就是
>> script
Elapsed time is 0.012753 seconds.
Elapsed time is 0.006541 seconds.
ans =
1.5059e-12
我不知道你的信号或内核有多大,所以你可以试试。
答案 2 :(得分:0)
对于你提到的尺寸,使用FFT可能是值得的,虽然这相当于循环卷积,所以你必须确保N包含足够的零填充。我假设如下。
由于可分离性,您只需要x上的1D fft
X=fft(x);
K=fft2(k,N,N);
XX=X*X.';
ytmp=ifft2(XX.*K);
y=diag(ytmp);
正如塞巴斯指出的那样,除了ytmp的对角线以外,你都丢弃了所有,所以有一些浪费的计算。如果您要为长度为N的许多信号x重复此操作,您可以通过预先计算IDFT矩阵来抑制浪费,
Afft=ifft2(eye(N)).';
然后,您可以直接通过
来计算ifft的对角线,而不是计算ytmp
。
y=sum(Afft2.*ifft( XX.*(K.')) );
即使你没有重复计算多个x,FFT的NlogN效率加上避免循环仍然可以弥补浪费。