MATLAB中信号的核二维卷积
我想在MATLAB中实现信号的二维核卷积。这本质上是一个信号(不是图像)的非线性二次滤波器,如下式所述: 其中k2(t1,t2)是一个二维卷积核。x是1d[N,1]信号向量&y是输出[N,1]信号 到目前为止,我一直在用一种非常野蛮、不优雅的方式来做这件事。我想知道我是否可以使用MATLABMATLAB中信号的核二维卷积,matlab,image-processing,signal-processing,convolution,Matlab,Image Processing,Signal Processing,Convolution,我想在MATLAB中实现信号的二维核卷积。这本质上是一个信号(不是图像)的非线性二次滤波器,如下式所述: 其中k2(t1,t2)是一个二维卷积核。x是1d[N,1]信号向量&y是输出[N,1]信号 到目前为止,我一直在用一种非常野蛮、不优雅的方式来做这件事。我想知道我是否可以使用MATLABfilter2/conv2函数来更有效地执行此操作!我知道这些函数是用于图像处理的,我对图像处理知道的不多,所以我希望有人能帮我 可能如下 y=diag(conv2(k,x*x.')); 或 使用diag
filter2
/conv2
函数来更有效地执行此操作!我知道这些函数是用于图像处理的,我对图像处理知道的不多,所以我希望有人能帮我 可能如下
y=diag(conv2(k,x*x.'));
或
使用
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
我不知道您的信号或内核有多大,所以您可以试试。对于您提到的大小,使用FFT可能是值得的,尽管这相当于循环卷积,因此您必须确保N包含足够的零填充。我在下面假设这一点
由于可分性,您只需要对x进行1D fft
X=fft(x);
K=fft2(k,N,N);
XX=X*X.';
ytmp=ifft2(XX.*K);
y=diag(ytmp);
正如sebas指出的,除了ytmp的对角线之外,您正在丢弃所有的元素,因此存在一些浪费的计算。如果要对许多长度为N的信号x重复此操作,可以通过预计算IDFT矩阵来抑制这种浪费
Afft=ifft2(eye(N)).';
然后,您可以通过执行以下操作直接计算ifft的对角线,而不是计算ytmp
y=sum(Afft2.*ifft( XX.*(K.')) );
即使您没有对多个x重复计算,FFT加上避免循环的NlogN效率仍然可以弥补浪费 M
和N
是否相同?否,M是内核大小(系统内存)。N是信号长度。大概的数字,M=30个箱子,N=10000个箱子。要实现这一点,真正的优化需要了解x和k的相对大小。大概的数字,M=30个箱子,N=10000个箱子。@DankMasterDan不要用那个尺寸尝试conv2。“它可能永远不会在一台普通的计算机上结束。”DankMasterDan稍加修改,它就会更高效。只需将括号添加到矩阵向量与未在另一个向量之前转置的向量的乘积中<代码>x(imax:-1:imin)“*(k2(jmin:jmax,jmin:jmax)*x(imax:-1:imin))代码>没有括号总是更快。谢谢sebas!它不像我想象的解决方案那么简单,但它将我的计算时间减少了一半!不客气。下次你也可以用“算法”来标记你的问题,你可能会引起比我更好的程序员的注意。你需要在逆fft后得到实数(ytmp)吗?我不知道是否会得到实数结果。这取决于k的对称性,OP没有告诉我们。但是如果期望输出为实值,那么是的,您必须丢弃虚部中的任何浮点残差,就像您对ifft()等所做的那样。
y=sum(Afft2.*ifft( XX.*(K.')) );