简体   繁体   English

使用fft进行反卷积的实现与MATLAB中的deconv函数有什么区别?

[英]What is different between the implementation of deconvolution with fft and the deconv function in MATLAB?

I've got stuck in this code: 我陷入了这段代码:

function [ y ] = mydeconv( c,x )
    lx=length(x);
    lc=length(c);
    %lt=lx+lc;
    c=[c zeros(1,lx)];
    x=[x zeros(1,lc)];
    y = ifft(real((fft(c)) ./(fft(x))));
end

and the result is: 结果是:

mydeconv([1 2 3 3 2 1],[1 1 1])
ans =
Column 1
            NaN + 0.000000000000000i
Column 2
            NaN +               NaNi
Column 3
            NaN +               NaNi
Column 4
            NaN + 0.000000000000000i
Column 5
            NaN +               NaNi
Column 6
            NaN +               NaNi
Column 7
            NaN + 0.000000000000000i
Column 8
            NaN +               NaNi
Column 9
            NaN +               NaNi

and the result of deconv function simply is: deconv函数的结果就是:

deconv([1 2 3 3 2 1],[1 1 1])
ans =
 1     1     1     1

In principle it should work, I can't understand what is wrong with it. 原则上,它应该工作,我不明白它有什么问题。

Since the padded vector x has a length that is a multiple of the original, you end up with zeros in the frequency domain of fft(x) . 由于填充后的向量x的长度是原始向量的倍数,因此在fft(x)的频域中最终为零。 You can avoid this by choosing a different (longer) length when such zeros are observed: 您可以通过在观察到这样的零时选择不同的(更长)长度来避免这种情况:

function [ y ] = mydeconv( c,x )
  lx=length(x);
  lc=length(c);
  if (lc >= lx)
    lt = lc;
    while (1)
      xpadded = [x zeros(1,lt-length(x))];
      Xf = fft(xpadded);
      if (min(abs(Xf)) > 0)
        break;
      end
      lt = lt + 1;
    end
    cpadded = [c zeros(1,lt-length(c))];
    Cf = fft(cpadded);
    y = real(ifft(Cf ./ Xf));
    y = y(1:lc-lx+1);
  else
    y = [];
  end
end

There are two problems in your code: 您的代码中有两个问题:

Firstly, you should take real part of the IFFT output, not of individual FFTs. 首先,您应该使用IFFT输出的real部分,而不是单个FFT。

Secondly, you should protect against zero-divide-by-zero cases, which are resulting in NaN in your example. 其次,您应该防止零除以零的情况,这种情况在您的示例中会导致NaN

You can implement both of the above, by modifying the line computing y as follows: 您可以通过如下修改线计算y来实现以上两种:

y = real(ifft((eps+fft(c)) ./ (eps+fft(x))));

Note that eps is a small positive number to protect against zero-divide-by-zero cases. 请注意, eps是一个小的正数,可以防止被零除的情况。 With this, the output is: 这样,输出为:

disp(y)
% 1.0000    1.0000    1.0000    1.0000    0.0000   -0.0000    0.0000    0.0000    0.0000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM