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