我需要编写一个程序来过滤 0.8-3 Hz 的信号。尽管我有一个可用的 FIR 滤波器,但这需要太长时间,因此我决定更换为 IIR 滤波器。我自己使用 Matlab 中的 fdatool 设计了一个,并且我有 NUM 和 DEN。时间上的改进将是相当好的(FIR 是 125 个抽头,而这个的阶数是 12)。 下一步是转向 C 实现,我发现了这个不错的网站 http://iowahills.com/Example%20Code/IIRNthOrderImplementation.txt .
问题是在他们的代码中有一个我不明白的参数,那就是 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;
}
}
在描述中他们说
This particular filter has a nominal group delay of 4 so we set NumSigPts to at least 1000 + 2*4
如何找到滤波器的群延迟。它与过滤器的顺序有什么关系吗? 我过滤的信号是连续提供的,所以我的确切问题是开始过滤的信号的最小大小是多少?
稍后编辑:
所以今天我对这个 IIR 滤波器进行了一些尝试,但仍然没有取得一些好的结果。 我采纳了 Nate 的建议并尝试了 Matlab 的 grpdelay 函数。问题是我不太确定如何解释输出。
我想做的是逐像素过滤一些图像、帧。我这样做的方法是将图像存储在图像数组 all_frames 中。为了访问每个像素,我调用 all_frames[frame_number][pixel_number]。
我根据上面提到的网站想出的代码是:
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;
}
}
FILTER_ORDER 设置为 13,因为 num 和 den 有 0-12 个值。
我走的是完全错误的道路吗?
最佳答案
关键是这个评论:
Remember that these filters have delay, so you need to run the code for M points longer than the number of data points to be filtered in order to get the entire signal through the filter. A reasonable value for M is twice the group delay value.
正如示例代码所示,任何 IIR 滤波器都会有延迟。发生这种情况是因为滤波器在信号通过后继续响应。这意味着您的循环需要是信号长度
+ M 长度
才能完全处理信号。 NumSigPoints
就是这个值,基本上告诉过滤器要处理多长时间。
我认为标称群延迟的意思是滤波器的最大群延迟值。群延迟基本上是通过滤波器的频率将被延迟的程度,它是频率的函数(IIR 滤波器具有非线性群延迟)。您可以计算滤波器的最大群延迟,也可以直接观察它以便处理整个信号。如果您有 Matlab,请尝试使用 grpdelay功能。
如果这是一个连续的过程,您将需要在信号进入时按 block 进行过滤。信号的最小大小将是窗口大小( block 大小)的函数,您可以选择窗口大小你自己。您可能想要寻找实时滤波的实现,因为窗口化本身(窗口类型、重叠等)是本科 DSP 类(class)中至少一些讲座的主题。
关于filter - DSP - IIR 滤波器的群延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20598295/