什么是高通和低通滤波器?

什么是高通和低通滤波器?

问题描述:

图形和音频编辑和处理软件通常包含称为“高通滤波器”和“低通滤波器”的功能。它们究竟做了什么,以及实现它们的算法是什么?什么是高通和低通滤波器?

百科:

这些 “高”, “低”,以及 “带” 的术语是指频率。在高通中,您尝试去除低频。在低通中,您尝试删除高位。带通中,您只允许保持连续的频率范围。

选择截止频率取决于您的应用。对这些滤波器进行编码既可以通过模拟RC电路来完成,也可以通过对基于时间的数据进行傅立叶变换来完成。有关代码示例,请参阅wikipedia文章。

它们通常是倾向于传递部分模拟信号的电路。高通倾向于传输更多的高频部分,而低通倾向于传递更多的低频部分。

它们可以用软件模拟。例如,步行平均值可以用作低通滤波器,而步行平均值和输入值之间的差值可以用作高通滤波​​器。

高通滤波器 - 频率(详细/本地信息)
低通过滤器让 - 频率(粗/粗/全球信息)

这里是你使用卷积如何实现低通滤波器:

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]; 

注意,例如被极度简化。它不会进行范围检查,也不会正确处理边缘。使用的滤波器(box-car)是一个特别糟糕的低通滤波器,因为它会导致很多伪像(振铃)。阅读滤波器设计。

您也可以在频域中实现滤波器。下面介绍如何使用FFT实现高通滤波器:

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); 

此外,这是简化的,但您明白了。代码看起来不像数学那么复杂。

+2

非常酷的代码示例。为什么在一种情况下卷积和FFT在另一种情况下? – dfrankow 2009-03-13 19:03:28

+2

@dfrankow没有特别的理由。只是为了展示它在不同领域的外观。更新了文字以反映这一点。谢谢。 – Hallgrim 2009-03-16 21:31:43

过滤描述了处理数据的行为,这种处理方式对数据中的不同频率应用不同级别的衰减。

高通滤波器对高频应用最小衰减(即保持电平不变),但对低频应用最大衰减。

低通滤波器是相反的 - 通过对高频进行衰减,它不会对低频施加衰减。

有许多不同的过滤算法被使用。最简单的两个可能是有限脉冲响应滤波器(又名FIR滤波器)和无限脉冲响应滤波器(又名IIR滤波器)。

FIR滤波器的工作原理是保持一系列样本并将每个样本乘以固定系数(基于系列中的位置)。每个这些乘法的结果都是累积的,并且是该样本的输出。这被称为Multiply-Accumulate - 在专用的DSP硬件中,有一个特定的MAC指令可以做到这一点。

当下一个采样被添加到系列的开始时,系列中最旧的采样被删除,并重复该过程。

滤波器的行为是通过选择滤波器系数来确定的。

图像处理软件经常提供的一种最简单的过滤器是平均过滤器。这可以通过将FIR滤波器的所有滤波器系数设置为相同的值来实现。

这里是在C++中的低通滤波器,其在一个时间处理该信号一个样本的超简单的例子:

float lopass(float input, float cutoff) { 
lo_pass_output= outputs[0]+ (cutoff*(input-outputs[0])); 
outputs[0]= lo_pass_output; 
return(lo_pass_output); 
} 

这里是几乎同样的事情,除了它的高通:

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); 
}