Filter DSP-IIR滤波器的群延迟

Filter DSP-IIR滤波器的群延迟,filter,signal-processing,Filter,Signal Processing,我需要写一个程序来过滤0.8-3赫兹的信号。尽管我有一个工作的FIR滤波器,但这个滤波器太长了,我决定换成IIR滤波器。我自己用Matlab中的fdatool设计了一个,我得到了NUM和DEN。在时间上的改进将是相当好的(FIR是125抽头,这一个的顺序是12)。 下一步是转到C实现,我发现了这个不错的网站 问题是,在他们的代码中有一个参数我不理解,那就是NumSigPts void RunIIRPoly( double *Signal, double *FilteredSignal, int

我需要写一个程序来过滤0.8-3赫兹的信号。尽管我有一个工作的FIR滤波器,但这个滤波器太长了,我决定换成IIR滤波器。我自己用Matlab中的fdatool设计了一个,我得到了NUM和DEN。在时间上的改进将是相当好的(FIR是125抽头,这一个的顺序是12)。 下一步是转到C实现,我发现了这个不错的网站

问题是,在他们的代码中有一个参数我不理解,那就是NumSigPts

void RunIIRPoly( double *Signal, double *FilteredSignal, int NumSigPts)
{
 int j, k, N;
 double y, Reg[100];

 for(j=0; j<100; j++)Reg[j] = 0.0; // Init the delay registers.

 for(j=0; j<NumSigPts; j++)
 {
  // Shift the delay register values.
  for(k=N; k>0; k--)Reg[k] = Reg[k-1];

  // The denominator
  Reg[0] = Signal[j];
  for(k=1; k<=N; k++)Reg[0] -= DenomCoeff[k] * Reg[k];

  // The numerator
  y = 0;
  for(k=0; k<=N; k++)y += NumCoeff[k] * Reg[k];
  FilteredSignal[j] = y;
 }

}
void RunIIRPoly(双*信号,双*过滤信号,整数)
{
int j,k,N;
双y,Reg[100];

对于(j=0;j而言,关键在于以下评论:

请记住,这些过滤器有延迟,因此您需要运行代码 对于比要过滤的数据点数长的M个点 以便通过滤波器获得整个信号。一个合理的 M的值是群延迟值的两倍

正如示例代码所述,任何IIR滤波器都会有延迟。这是因为滤波器在信号通过后会继续响应。这意味着您的循环需要
信号长度
+
长度M
,才能完全处理信号。
NumSigPoints
是该值,基本上告诉f过滤处理多长时间

我认为他们所说的标称群延迟是指滤波器的最大群延迟值。群延迟基本上是指通过滤波器的频率将延迟多少,它是频率的函数(IIR滤波器具有非线性群延迟)。您可以计算滤波器的最大群延迟,也可以直接观察它,以便处理整个信号。如果您有Matlab,请尝试使用该函数


如果这是一个连续的过程,当信号进入时,你需要分块过滤。信号的最小大小是窗口大小(块大小)的函数,你可以自己选择。你可能需要寻找实时过滤的实现,因为窗口本身(窗口类型、重叠等)是一门本科DSP课程中至少几节课的主题。

嗨,Nate,谢谢你的回答。我已经尝试了你对grpdelay的建议,并更新了我的问题。我知道我必须将信号划分为块,但这正是我关心的问题,一个块的最小大小。我假设它必须至少与滤波器顺序。或者这仅仅是FIR滤波器的顺序?我也遵循了寄存器,根据我的理解,即使在信号的第一个值进入寄存器后,它也会在输出端产生一个值。对吗?我将+1这个值,因为似乎没有其他人有…它回答了实际问题,然后用另外一个应该是单独的问题…如果它真的问了什么。移动门柱的坏情况,等等,你是不是先在Matlab中尝试了你的过滤器?我不知道你在过滤图像。用IIR过滤器过滤图像可能会一团糟,请在你干扰im之前再次检查你的过滤器是否对图像有效用C打褶。
void ApplyIIR ( float **all_frames, float *num, float *den, int frame_number,  float *filter_Xs, int w, int h)
{   
        float Reg[FILTER_ORDER];

    for (int i=0; i< (width*height) ; i++) {  //go pixel by pixel

        for(int j=0; j<FILTER_ORDER; j++) //init regs
                Reg[j] = 0.0;
        float final_X=0;

            for(int l=0; l< FILTER_ORDER+ DELAY ; l++) {  // not sure how to set DELAY

                    for(int k=FILTER_ORDER-1; k>0;k--)
                        Reg[k] = Reg[k-1];

                    Reg[0] = all_frames[frame_number][i]; //get pixels one by one
                    for(int k=1; k<FILTER_ORDER;k++)
                        Reg[0] -= den[k]* Reg[k];


                    for(int k=0;k<FILTER_ORDER;k++)
                        final_X += num[k] * Reg[k];

                    if(frame_number == 0)             //go through all the frames
                        frame_number = FILTER_ORDER - 1;
                    else
                        frame_number--;

                }
                    filter_Xs[i] = final_X;         
    }

}