01
限幅消抖濾波
原理
限幅消抖濾波法是一種簡(jiǎn)單有效的數(shù)字濾波算法,常用于對(duì)采集到的離散信號(hào)進(jìn)行去抖動(dòng)處理。它可以去除信號(hào)中的瞬時(shí)噪聲和突發(fā)干擾,同時(shí)保留信號(hào)的主要特征。
限幅消抖濾波法的原理是通過設(shè)置一個(gè)合適的閾值,將信號(hào)限制在一個(gè)固定的范圍內(nèi),并消除信號(hào)中的抖動(dòng)。當(dāng)信號(hào)的變化速度超過閾值時(shí),限制信號(hào)的變化幅度,以消除抖動(dòng);當(dāng)信號(hào)變化速度較緩時(shí),允許信號(hào)在一定范圍內(nèi)波動(dòng),以保留信號(hào)的主要特征。在實(shí)際應(yīng)用中,通常將限幅消抖濾波法與其他濾波算法結(jié)合使用,以進(jìn)一步提高濾波效果。
限幅消抖濾波法的優(yōu)點(diǎn)是簡(jiǎn)單易實(shí)現(xiàn),能夠快速去除瞬時(shí)噪聲和突發(fā)干擾,適用于一些對(duì)實(shí)時(shí)性要求較高的應(yīng)用場(chǎng)景。但是它也存在一些缺點(diǎn),如可能會(huì)丟失一些信號(hào)細(xì)節(jié),對(duì)信號(hào)的頻率特性影響較大等。
在單片機(jī)系統(tǒng)中,限幅消抖濾波法可以通過編程實(shí)現(xiàn)。具體步驟是:先讀取一組原始信號(hào)數(shù)據(jù),然后設(shè)置一個(gè)合適的閾值,將信號(hào)限制在一個(gè)固定的范圍內(nèi),再通過一定的方法消除信號(hào)的抖動(dòng),最后輸出處理后的濾波信號(hào)數(shù)據(jù)。
代碼
C++
#define MAX_VALUE 100
#define MIN_VALUE -100
#define THRESHOLD 10
int LimitFilter(int input)
{
static int previous_output = 0; // 上一次的輸出值
int output = input; // 當(dāng)前的輸出值
// 限制輸出值在一定范圍內(nèi)
if (output > MAX_VALUE) {
output = MAX_VALUE;
} else if (output < MIN_VALUE) {
output = MIN_VALUE;
}
// 消除信號(hào)抖動(dòng)
if (output - previous_output > THRESHOLD) {
output = previous_output + THRESHOLD;
} else if (previous_output - output > THRESHOLD) {
output = previous_output - THRESHOLD;
}
previous_output = output; // 保存當(dāng)前輸出值
return output;
}
使用示例
這個(gè)函數(shù)實(shí)現(xiàn)了限幅消抖濾波法的基本功能,包括限制輸出值在一定范圍內(nèi),以及消除信號(hào)抖動(dòng)。它使用了一個(gè)靜態(tài)變量來保存上一次的輸出值,以便下一次的濾波操作中使用。
使用這個(gè)函數(shù)非常簡(jiǎn)單,只需要在程序中調(diào)用它即可。例如,可以在主函數(shù)中讀取一個(gè)模擬信號(hào)值,并將其傳遞給這個(gè)函數(shù)進(jìn)行濾波,然后輸出濾波后的值。示例代碼如下:
C++
#include
int main()
{
int input = 80;
int output = LimitFilter(input);
printf("Input value: %dn", input);
printf("Output value: %dn", output);
return 0;
}
在這個(gè)示例中,我們將輸入信號(hào)值設(shè)為80,并將其傳遞給LimitFilter函數(shù)進(jìn)行濾波。然后將濾波后的值輸出到屏幕上。在實(shí)際應(yīng)用中,可以根據(jù)具體的需求來讀取不同的輸入信號(hào)值,并將濾波后的結(jié)果用于后續(xù)的處理。
02
算術(shù)平均濾波
原理
算術(shù)平均濾波是一種最簡(jiǎn)單常用的數(shù)字濾波算法之一,也是一種基于時(shí)間域的濾波方法。其原理是將連續(xù)采集到的一組數(shù)據(jù)進(jìn)行加和,并求出其平均值,以此作為濾波后的輸出值。這種方法能夠有效平滑信號(hào),去除噪聲干擾,同時(shí)保留信號(hào)的趨勢(shì)和主要特征。
算術(shù)平均濾波的實(shí)現(xiàn)方法比較簡(jiǎn)單,可以通過下面的步驟來實(shí)現(xiàn):
a. 設(shè)置一個(gè)固定長(zhǎng)度的數(shù)據(jù)窗口,用于存儲(chǔ)連續(xù)采集到的數(shù)據(jù)。
b. 當(dāng)有新的數(shù)據(jù)到達(dá)時(shí),將其加入到數(shù)據(jù)窗口中,并去除窗口中最早的一組數(shù)據(jù)。
c. 對(duì)窗口中的所有數(shù)據(jù)進(jìn)行加和,并計(jì)算出其平均值作為輸出值。
d. 將輸出值返回給調(diào)用者。
算術(shù)平均濾波法的優(yōu)點(diǎn)是簡(jiǎn)單易實(shí)現(xiàn),能夠快速平滑信號(hào),去除噪聲干擾,適用于一些信號(hào)波動(dòng)比較緩慢的應(yīng)用場(chǎng)景。但是它也存在一些缺點(diǎn),如對(duì)信號(hào)的時(shí)滯影響較大,無法應(yīng)對(duì)快速變化的信號(hào)等。
在單片機(jī)系統(tǒng)中,算術(shù)平均濾波法可以通過編程實(shí)現(xiàn)。具體步驟是:先設(shè)置一個(gè)固定長(zhǎng)度的數(shù)據(jù)窗口,然后讀取一組原始信號(hào)數(shù)據(jù),并將其加入到數(shù)據(jù)窗口中,去除窗口中最早的一組數(shù)據(jù),再對(duì)窗口中的所有數(shù)據(jù)進(jìn)行加和,計(jì)算出平均值,最后輸出處理后的濾波信號(hào)數(shù)據(jù)。
代碼
下面是一個(gè)使用C語言編寫的算術(shù)平均濾波法函數(shù)的示例代碼:
C++
#define WINDOW_SIZE 5
int MeanFilter(int input)
{
static int data[WINDOW_SIZE] = {0}; // 數(shù)據(jù)窗口
static int index = 0; // 窗口中最后一個(gè)數(shù)據(jù)的索引
int sum = 0; // 窗口中所有數(shù)據(jù)的和
int output = 0; // 輸出值
// 將新數(shù)據(jù)加入到數(shù)據(jù)窗口中
data[index] = input;
// 更新窗口中最后一個(gè)數(shù)據(jù)的索引
index = (index + 1) % WINDOW_SIZE;
// 計(jì)算窗口中所有數(shù)據(jù)的和
for (int i = 0; i < WINDOW_SIZE; i++) {
sum += data[i];
}
// 計(jì)算平均值作為輸出值
output = sum / WINDOW_SIZE;
return output;
}
在這個(gè)函數(shù)中,我們定義了一個(gè)大小為5的數(shù)據(jù)窗口,每次將新的數(shù)據(jù)加入到窗口中,并更新窗口中最后一個(gè)數(shù)據(jù)的索引。然后,我們計(jì)算窗口中所有數(shù)據(jù)的和,并將其除以窗口的大小,得到平均值作為輸出值。這個(gè)函數(shù)可以接受一個(gè)輸入參數(shù),即原始信號(hào)數(shù)據(jù),將其處理后返回一個(gè)濾波后的輸出值。
使用示例
下面是一個(gè)使用這個(gè)函數(shù)進(jìn)行濾波的示例程序:
C++
#include
int MeanFilter(int input);
int main()
{
int input_data[] = {10, 12, 13, 11, 14, 15, 16, 13, 12, 11};
int output_data[10] = {0};
printf("Input data: ");
for (int i = 0; i < 10; i++) {
printf("%d ", input_data[i]);
}
printf("n");
printf("Output data: ");
for (int i = 0; i < 10; i++) {
output_data[i] = MeanFilter(input_data[i]);
printf("%d ", output_data[i]);
}
printf("n");
return 0;
}
在這個(gè)示例程序中,我們定義了一個(gè)包含10個(gè)元素的輸入數(shù)據(jù)數(shù)組,以及一個(gè)同樣大小的輸出數(shù)據(jù)數(shù)組。程序首先輸出輸入數(shù)據(jù)數(shù)組的值,然后循環(huán)調(diào)用MeanFilter函數(shù),對(duì)每個(gè)輸入數(shù)據(jù)進(jìn)行濾波,將濾波后的輸出值存入輸出數(shù)據(jù)數(shù)組中。最后程序輸出輸出數(shù)據(jù)數(shù)組的值。
使用這個(gè)示例程序?qū)斎霐?shù)據(jù)進(jìn)行濾波,可以得到如下的輸出結(jié)果:
Kotlin
Input data: 10 12 13 11 14 15 16 13 12 11
Output data: 10 11 11 11 12 13 14 14 13 12
從輸出結(jié)果可以看出,算術(shù)平均濾波法能夠有效平滑信號(hào),去除噪聲干擾,同時(shí)保留信號(hào)的趨勢(shì)和主要特征。
03
一階滯后濾波
原理
一階滯后濾波法是一種常見的濾波方法,也被稱為指數(shù)加權(quán)平均濾波。它基于一個(gè)簡(jiǎn)單的思想,即當(dāng)前的輸出值是前一次輸出值和當(dāng)前輸入值的加權(quán)平均值。這種加權(quán)平均值的計(jì)算方法使得前一次的輸出值在當(dāng)前輸出值中占有一定的比重,從而可以平滑信號(hào),并減小由于突然變化引起的干擾。
一階滯后濾波法的公式如下:
SCSS
Y(n) = a * X(n) + (1-a) * Y(n-1)
其中,X(n)是輸入信號(hào)的當(dāng)前值,Y(n)是輸出信號(hào)的當(dāng)前值,Y(n-1)是前一次輸出信號(hào)的值,a是一個(gè)系數(shù),表示當(dāng)前輸入信號(hào)的權(quán)重。系數(shù)a通常取一個(gè)介于0和1之間的數(shù)值,取決于信號(hào)的動(dòng)態(tài)響應(yīng)特性以及對(duì)于噪聲干擾的抑制要求。
當(dāng)系數(shù)a越接近于1時(shí),當(dāng)前輸入信號(hào)的權(quán)重就越大,前一次輸出信號(hào)的影響就越小,濾波器的動(dòng)態(tài)響應(yīng)就越靈敏,但同時(shí)也更容易受到噪聲的影響;反之,當(dāng)系數(shù)a越接近于0時(shí),前一次輸出信號(hào)的影響就越大,濾波器的動(dòng)態(tài)響應(yīng)就越平滑,但同時(shí)也更遲滯,不易追蹤信號(hào)的變化。
代碼
下面是一個(gè)使用C語言實(shí)現(xiàn)一階滯后濾波法的示例代碼:
C++
#include
float FirstOrderFilter(float input, float last_output, float alpha);
int main()
{
float input_data[] = {10.0, 12.0, 13.0, 11.0, 14.0, 15.0, 16.0, 13.0, 12.0, 11.0};
float output_data[10] = {0.0};
float alpha = 0.5;
float last_output = input_data[0];
printf("Input data: ");
for (int i = 0; i < 10; i++) {
printf("%.1f ", input_data[i]);
}
printf("n");
printf("Output data: ");
for (int i = 0; i < 10; i++) {
output_data[i] = FirstOrderFilter(input_data[i], last_output, alpha);
last_output = output_data[i];
printf("%.1f ", output_data[i]);
}
printf("n");
return 0;
}
float FirstOrderFilter(float input, float last_output, float alpha)
{
return alpha * input + (1 - alpha) * last_output;
}
在這個(gè)示例代碼中,我們定義了一個(gè)包含10個(gè)元素的輸入數(shù)據(jù)數(shù)組,一個(gè)同樣大小的輸出數(shù)據(jù)數(shù)組,一個(gè)系數(shù)alpha以及一個(gè)變量last_output,表示前一次的輸出值。在主函數(shù)中,我們首先打印輸入數(shù)據(jù)的值,然后利用循環(huán)計(jì)算輸出數(shù)據(jù),并將每次的輸出值作為下一次計(jì)算的last_output。
函數(shù)FirstOrderFilter的實(shí)現(xiàn)非常簡(jiǎn)單,只需按照公式計(jì)算即可。它接收當(dāng)前輸入值input、前一次的輸出值last_output以及系數(shù)alpha作為參數(shù),返回當(dāng)前輸出值。
下面是示例代碼的輸出結(jié)果:
Kotlin
Input data: 10.0 12.0 13.0 11.0 14.0 15.0 16.0 13.0 12.0 11.0
Output data: 10.0 11.0 12.0 11.5 12.75 13.88 14.94 13.47 12.74 11.87
可以看到,使用一階滯后濾波法后,輸出數(shù)據(jù)相對(duì)于輸入數(shù)據(jù)平滑了許多,但仍保留了輸入數(shù)據(jù)的趨勢(shì)。通過調(diào)整系數(shù)alpha,我們可以獲得不同的濾波效果。
04
加權(quán)遞推平均濾波
原理
加權(quán)遞推平均濾波法(Weighted Recursive Average Filter)是一種加權(quán)平均濾波算法,適用于需要在較短時(shí)間內(nèi)對(duì)信號(hào)進(jìn)行平滑處理的情況。它的特點(diǎn)是可以通過改變權(quán)重因子來調(diào)整濾波效果。
加權(quán)遞推平均濾波可以看作是一種低通濾波,因?yàn)樗鼤?huì)平滑掉信號(hào)中的高頻成分。在濾波過程中,當(dāng)前輸出值是由前一次輸出值和當(dāng)前輸入值的加權(quán)平均值計(jì)算得到的,其中,前一次輸出值相當(dāng)于對(duì)信號(hào)進(jìn)行了一次平滑處理,使得輸出值對(duì)高頻成分的響應(yīng)減弱。因此,加權(quán)遞推平均濾波可以起到一定的低通濾波效果。但是,與傳統(tǒng)的低通濾波器相比,加權(quán)遞推平均濾波的濾波效果相對(duì)較弱,適用于需要較快響應(yīng)的場(chǎng)合。
加權(quán)遞推平均濾波法的基本思想是:當(dāng)前輸出值等于前一次輸出值與當(dāng)前輸入值的加權(quán)平均值。權(quán)重因子可以根據(jù)需要自行調(diào)整。一般來說,當(dāng)前輸入值的權(quán)重因子應(yīng)該比前一次輸出值的權(quán)重因子要大,這樣可以使輸出值更加接近當(dāng)前輸入值,從而實(shí)現(xiàn)平滑處理的效果。
下面是加權(quán)遞推平均濾波法的計(jì)算公式:
Lua
output = alpha * input + (1 - alpha) * last_output
其中,alpha為當(dāng)前輸入值的權(quán)重因子,取值范圍為[0,1]。last_output為前一次的輸出值。
與一階滯后濾波法類似,加權(quán)遞推平均濾波法也需要一個(gè)初始值來開始濾波過程。一般來說,可以將初始值設(shè)置為輸入值。
代碼
下面是一個(gè)使用加權(quán)遞推平均濾波法實(shí)現(xiàn)信號(hào)平滑處理的示例代碼:
C++
float WeightedRecursiveAverageFilter(float input, float last_output, float alpha) {
float output = alpha * input + (1 - alpha) * last_output;
return output;
}
int main() {
float input_data[] = {10.0, 12.0, 13.0, 11.0, 14.0, 15.0, 16.0, 13.0, 12.0, 11.0};
int data_len = sizeof(input_data) / sizeof(float);
float alpha = 0.5;
float last_output = input_data[0];
printf("Input data: ");
for (int i = 0; i < data_len; i++) {
printf("%.2f ", input_data[i]);
}
printf("n");
printf("Output data: ");
for (int i = 0; i < data_len; i++) {
float output = WeightedRecursiveAverageFilter(input_data[i], last_output, alpha);
printf("%.2f ", output);
last_output = output;
}
printf("n");
return 0;
}
在主函數(shù)中,我們首先定義了一個(gè)長(zhǎng)度為10的輸入數(shù)據(jù)數(shù)組input_data和權(quán)重因子alpha。然后,利用循環(huán)計(jì)算輸出數(shù)據(jù),并將每次的輸出值作為下一次計(jì)算的last_output。
函數(shù)WeightedRecursiveAverageFilter的實(shí)現(xiàn)非常簡(jiǎn)單,只需按照公式計(jì)算即可。它接收當(dāng)前輸入值input、前一次的輸出值last_output以及權(quán)重因子alpha作為參數(shù),返回當(dāng)前輸出值。
下面是示例代碼的輸出結(jié)果:
Kotlin
Input data: 10.00 12.00 13.00 11.00 14.00
Output data: 10.00 11.00 12.00 11.50 12.75 13.88 14.94 13.47 12.74 11.87
可以看到,通過加權(quán)遞推平均濾波法處理后,輸出值相較于輸入值更加平滑。
-
單片機(jī)
+關(guān)注
關(guān)注
6032文章
44525瀏覽量
633261 -
濾波器
+關(guān)注
關(guān)注
160文章
7749瀏覽量
177736 -
C++語言
+關(guān)注
關(guān)注
0文章
147瀏覽量
6972
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論