图形和音频编辑与处理软件通常包含称为"高通滤波器"和"低通滤波器"的功能。这些究竟是做什么的,以及实现它们的算法是什么?
以下是使用卷积实现低通滤波器的方法:
1 2 3 4 5 6 7 8 9 10 11
| double[] signal = (some 1d signal);
double[] filter = [0.25 0.25 0.25 0.25]; // box-car filter
double[] result = new double[signal.Length + filter.Length + 1];
// Set result to zero:
for (int i=0; i < result.Length; i++) result[i] = 0;
// Do convolution:
for (int i=0; i < signal.Length; i++)
for (int j=0; j < filter.Length; j++)
result[i+j] = result[i+j] + signal[i] * filter[j]; |
请注意,该示例已大大简化。它不进行范围检查,并且不能正确处理边缘。所用的滤波器(箱式车)是一种特别糟糕的低通滤波器,因为它会引起很多伪像(振铃)。阅读滤波器设计。
您也可以在频域中实现滤波器。这是使用FFT实现高通滤波器的方法:
1 2 3 4 5 6 7 8 9 10 11 12
| double[] signal = (some 1d signal);
// Do FFT:
double[] real;
double[] imag;
[real, imag] = fft(signal)
// Set the first quarter of the real part to zero to attenuate the low frequencies
for (int i=0; i < real.Length / 4; i++)
real[i] = 0;
// Do inverse FFT:
double[] highfrequencysignal = inversefft(real, imag); |
同样,这是简化的,但是您明白了。该代码看起来不像数学那么复杂。
维基百科:
这些"高","低"和"频带"术语是指频率。在高通中,您尝试消除低频。在低通中,您尝试消除高。在带通中,您只允许保留一个连续的频率范围。
选择截止频率取决于您的应用。可以通过模拟RC电路或通过对基于时间的数据进行傅里叶变换来对这些滤波器进行编码。有关代码示例,请参见Wikipedia文章。
过滤描述了以对数据中不同频率施加不同程度的衰减的方式处理数据的行为。
高通滤波器将对高频施加最小的衰减(即,保持电平不变),但对低频施加最大衰减。
相反,低通滤波器-通过对高频施加衰减,不会对低频施加衰减。
使用了许多不同的过滤算法。最简单的两个可能是有限冲激响应滤波器(又名FIR滤波器)和无限冲激响应滤波器(又名IIR滤波器)。
FIR滤波器的工作原理是保留一系列样本,然后将每个样本乘以固定系数(该系数基于序列中的位置)。这些乘积的每一个的结果都是累加的,并且是该样本的输出。这被称为乘法累加-在专用DSP硬件中,有一条专门的MAC指令可以做到这一点。
在获取下一个样本时,将其添加到系列的开始,并删除该系列中最旧的样本,并重复该过程。
通过选择滤波器系数来固定滤波器的性能。
图像处理软件通常提供的最简单的滤波器之一是平均滤波器。这可以通过FIR滤波器将所有滤波器系数设置为相同的值来实现。
高通滤波器使高频(详细信息/本地信息)通过。
低通滤波器使低频(粗/粗/全局信息)通过。
通常是倾向于传递模拟信号一部分的电路。高通倾向于传输更多的高频部分,而低通则倾向于通过更多的低频部分。
它们可以在软件中模拟。例如,移动平均线可以充当低通滤波器,而移动平均线与其输入之间的差可以用作高通滤波??器。
这是C语言中一个低通滤波器的超级简单示例,它一次处理一个样本的信号:
1 2 3 4 5
| float lopass(float input, float cutoff) {
lo_pass_output= outputs[0]+ (cutoff*(input-outputs[0]));
outputs[0]= lo_pass_output;
return(lo_pass_output);
} |
除了高通以外,这里几乎是同一件事:
1 2 3 4 5
| float hipass(float input, float cutoff) {
hi_pass_output=input-(outputs[0] + cutoff*(input-outputs[0]));
outputs[0]=hi_pass_output;
return(hi_pass_output);
} |