精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

FIR頻域重疊相加法

安費諾傳感器學堂 ? 來源:安費諾傳感器學堂 ? 2024-09-09 11:29 ? 次閱讀

[編者按]傳感器信號處理僅一線之隔,信號的前后端合理搭配,是我們更準確地感知這個世界的一種基本態度和方式。

FIR頻域重疊相加法

還記得我們(此處有重復之嫌)之前的發文《FIR連續采樣分段卷積時域重疊相加法》?不過那是在時域處理的模擬仿真。這次我們的內容是用C++在頻域實現的濾波卷積法,仍然是重疊相加法,屆時大家可以比較一下兩種方式的差異。

基本是通過兩個處理過程。

(1)頻域的重疊相加法示意圖再拿來用一下。如下圖所示[1]。

image.png

(2)再借用一下的時域卷積經傅里葉FFT變換后,在頻域成為對應的相乘;然后再通過IFFT將中間結果轉換回時域時序結果。

image.png

讓我們直接跳進話題,先看模擬測試結果,后看C++源碼。

模擬情節設定

50Hz選頻濾波,信號中混有110Hz和210H在的干擾信號和幅值為1的直流DC

模擬信號及其頻譜的輸出請查看我們前面的文章。這里的代碼只提供將模擬信號進行了頻域重疊相加處理,生成的濾波前后模擬信號和被濾波處理后的數據波形的比較(見下圖)。

還記得我們(此處重復)之前用C++來模擬時域處理的濾波模擬程序嗎?

你又猜對了,又是那個濾波器,又被用上了!但,是不同的實現處理方式。

image.png

濾波處理之前的波形和頻譜圖

濾波之后,直流和其他頻率的信號已經不見,只留下50Hz的正弦波(見下圖)。

image.png

頻域重疊相加濾波前后的波形比較

圖由csv文件處理后生成。又見此圖,是不是有熟悉的感覺?

頻域連續濾波模擬和驗證C++源碼

/*
Project Name: Demonstration & Validation for signal filtering via the 
"Overlap-Add" method implemented through FFT/IFFT based on Fast Fourier Transform (FFT)
based on the Cooley-Tukey algorithm.
Copyright(c)2024AmphenolSensors
Author: L.L.


This software is provided 'as-is', without any express or implied
warrantyandforsimulation/demostrationpurpose.Innoeventwilltheauthorsbeheldliableforanydamages
arising from the use of this software.


Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:


The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


const double PI = 3.1415926535897932384;
const double SAMPLE_RATE = 1000.0;      // 1000Hz
const int N = 1024;                     // 假設采樣分段數為1024


using namespace std; // 聲明使用std命名空間


#define SEL_FFT     0
#define SEL_IFFT    1
#define SEL_FFTIFFT 2


#define SIM_CYCLE_CNT   3.0


// 模擬信號函數
vector> generateSignal(double sampleRate, double seconds)
{
    size_t signal_len = (size_t)(sampleRate * seconds);
    vector> signal(signal_len); // 定義模擬信號的數組長度
    for (size_t i = 0; i < signal_len; ++i)
    {
        // 包含50Hz和110Hz,210Hz信號,DC
        signal[i].real(1+ sin((2 * PI * (double)i * 50) / sampleRate) + sin((2 * PI * (double)i * 210) / sampleRate) + sin((2 * PI * (double)i * 110) / sampleRate));
        signal[i].imag(0);
    }
    return signal;
}


// 基于Cooley-Tukey算法的FFT
void fft2(vector> &x)
{
    size_t n = x.size();
    if (n <= 1)
        return;


    // 把序列分為奇偶兩部分
    vector> even(n / 2), odd(n / 2);
    for (size_t i = 0; 2 * i < n; i++)
    {
        even[i] = x[i * 2];
        odd[i] = x[i * 2 + 1];
    }


    // 遞歸解決每一個序列
    fft2(even);
    fft2(odd);


    // 結合步驟
    for (size_t i = 0; 2 * i < n; i++)
    {
        complex t = polar(1.0, -2 * PI * (double)i / (double)n) * odd[i];
        x[i] = even[i] + t;
        x[i + n / 2] = even[i] - t;
    }
}
// 基于Cooley-Tukey算法的IFFT
void ifft2(vector> &x)
{
    size_t n = x.size();
    if (n <= 1)
        return;


    vector> even(n / 2), odd(n / 2);
    for (size_t i = 0; 2 * i < n; i++)
    {
        even[i] = x[i * 2];
        odd[i] = x[i * 2 + 1];
    }


    ifft2(even);
    ifft2(odd);


    for (size_t i = 0; 2 * i < n; i++)
    {
        complex t = polar(1.0, 2 * PI * (double)i /(double) n) * odd[i];
        x[i] = even[i] + t;
        x[i + n / 2] = even[i] - t;
    }
    // 最后除以n
    if (n > 1)
    {
        for (size_t i = 0; i < n; i++)
        {
            x[i] /= 2;
        }
    }
}


// 將數據寫入文件
void writeToFile(const vector> &Original_signal, const vector> &Proceeded_Signal, const string &filename, int Type_sel)
{
    ofstream file(filename);
    if (Type_sel==SEL_FFTIFFT)
    {
        file << "time(s)" << ", " << "Original Signal"<< ", " << "Filtered Signal" << "
";
        for (size_t i = 0; i < Original_signal.size(); i++)
        {
            file << (double)i / SAMPLE_RATE << ", " < b{0.0010175493084400998, 0.0010954624020866333, 0.001080635650435545, 0.0009293052645812359,
                   0.0005868808563577278, -8.138309855847798e-19, -0.0008644147524968251, -0.0019966389877814107,
                   -0.003323586744207458, -0.004696461345361978, -0.005892320462621699, -0.006633249964255378,
                   -0.006623614506478284, -0.005601944833604465, -0.0034001773970723163, -7.334366341273803e-18,
                   0.004425290874832446, 0.00949426225087417, 0.014634010415364655, 0.019132982942933127,
                   0.022226796444847933, 0.023207550009729024, 0.021541722692400025, 0.01697833945185371,
                   0.009628503914736117, -6.755395515820625e-18, -0.01102370844120733, -0.02226281209657117,
                   -0.032372473621654914, -0.04001099412924139, -0.04402269970024527, -0.043609484958132556,
                   -0.03846490807520255, -0.028848803480728435, -0.015588116829396594, -9.10410551538968e-18,
                   0.016255406162706088, 0.031374390998733945, 0.04363491329762711, 0.051616779739690075,
                   0.05438594145724075, 0.051616779739690075, 0.04363491329762711, 0.031374390998733945,
                   0.016255406162706088, -9.10410551538968e-18, -0.015588116829396594, -0.028848803480728435,
                   -0.03846490807520255, -0.043609484958132556, -0.04402269970024527, -0.0400109941292414,
                   -0.032372473621654914, -0.022262812096571168, -0.01102370844120733, -6.755395515820627e-18,
                   0.009628503914736117, 0.016978339451853702, 0.021541722692400025, 0.023207550009729034,
                   0.022226796444847933, 0.01913298294293312, 0.014634010415364655, 0.009494262250874175,
                   0.004425290874832446, -7.3343663412738e-18, -0.0034001773970723163, -0.005601944833604469,
                   -0.006623614506478284, -0.006633249964255374, -0.005892320462621699, -0.00469646134536198,
                   -0.003323586744207458, -0.001996638987781409, -0.0008644147524968251, -8.138309855847805e-19,
                   0.0005868808563577278, 0.0009293052645812359, 0.001080635650435545, 0.0010954624020866333,
                   0.0010175493084400998};


    // (1) Resize filter coefficients
    vector> H(b.size());


    for(size_t i=0; i< b.size(); i++)
    {
        H[i] = complex(b[i],0);
    }
    H.resize(N, complex(0.0, 0.0));


    // (2)Generate simulation data sequences
    size_t DataSeg_len_L = N - b.size() + 1;                // Data segmeng Length = L


    double daq_duration = (double)DataSeg_len_L * SIM_CYCLE_CNT / SAMPLE_RATE;
    vector>Original_signal = generateSignal(SAMPLE_RATE, daq_duration);     // Generate data sequence, L * 3


    // (3-1) Define a 2-D vector,3 columns, to simulate DAQ and filtering process for 3 rounds
    vector>> seg_Dates(3); 
    // (3-2) Initialize data segment
    for (size_t i = 0; i < seg_Dates.size(); i++)
    {
        seg_Dates[i].resize(DataSeg_len_L,complex(0.0, 0.0));
        // devide Original_signal into 3 parts to simulate consequent DAQ for 3 cycles
        for(size_t j=0; j(0.0, 0.0));                     // resize each data segment to N = L + M - 1
    }


    // (4) Start to FFT/IFFT and generate involution result
    vector> Filtered_signal(DataSeg_len_L * (size_t)(SIM_CYCLE_CNT) +  b.size() -1 );     //L * 3 + (M - 1)
    fft2(H);  


//(4-1)Simulate3cyclesofinvolution:L*3
    for(size_t i=0; i< seg_Dates.size(); i++)
    {
        fft2(seg_Dates[i]);
        for(size_t j = 0; j< seg_Dates[i].size(); j++)
        {
            seg_Dates[i][j] = seg_Dates[i][j] * H[j];
        }


        ifft2(seg_Dates[i]);
        for(size_t k = 0; k< seg_Dates[i].size(); k++)
        {
            Filtered_signal[i*DataSeg_len_L + k] += seg_Dates[i][k];
        }
    }


????//?(5)?Save?Origianl?signal & result?(data?after?filtering)?into?csv?file
    writeToFile(Original_signal, Filtered_signal,"output_Filtered2.csv", SEL_FFTIFFT);


    return 0;
}

時間倉促,有些功能和細節并沒有考慮太多,這里功能驗證是第一。

FFT/IFFT是基于庫里-圖基的算法,各位可以選用其他的來優化替代;

有些參數可以單獨變,有些參數卻是關聯的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 傳感器
    +關注

    關注

    2548

    文章

    50677

    瀏覽量

    751993
  • FIR
    FIR
    +關注

    關注

    4

    文章

    146

    瀏覽量

    33112
  • 頻域
    +關注

    關注

    1

    文章

    87

    瀏覽量

    26274

原文標題:數字濾波器(6)—FIR頻域連續濾波“重疊相加法”C++源碼

文章出處:【微信號:安費諾傳感器學堂,微信公眾號:安費諾傳感器學堂】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    運算放大器的同相加法器和反相加法

      運算放大器構成加法器 可以分為同相加法器和反相加法
    發表于 08-05 17:17 ?3w次閱讀
    運算放大器的同<b class='flag-5'>相加法</b>器和反<b class='flag-5'>相加法</b>器

    什么是加法器?加法器的原理是什么 ?

    什么是加法器?加法器的原理是什么 反相加法器等效原理圖解析
    發表于 03-11 06:30

    相加法電路(由LF155組成的)

    相加法電路(由LF155組成的)
    發表于 01-21 14:16 ?5029次閱讀
    同<b class='flag-5'>相加法</b>電路(由LF155組成的)

    相加法電路

    相加法運算電路為若干個輸入信號從集成運放的反相輸入端引入,輸出信號為它們反相按比例放大的代數和。
    發表于 09-22 11:44 ?3271次閱讀
    反<b class='flag-5'>相加法</b>電路

    相加法器電路原理與同相加法器計算

    相加法器輸入阻抗高,輸出阻抗低 反相加法器輸入阻抗低,輸出阻抗高.加法器是一種數位電路,其可進行數字的加法計算。當選用同相加法器時,如A輸
    發表于 09-13 17:23 ?5.7w次閱讀
    同<b class='flag-5'>相加法</b>器電路原理與同<b class='flag-5'>相加法</b>器計算

    運算電路:同相加法運算電路與反相加法運算電路解析

    加法運算電路能實現多個模擬量的求和運算。圖1所示為一個3個輸入信號的反相加法運算電路。
    發表于 05-15 09:41 ?20.8w次閱讀
    運算電路:同<b class='flag-5'>相加法</b>運算電路與反<b class='flag-5'>相加法</b>運算電路解析

    加法器與減法器_反相加法器與同相加法

    加法器是產生數的和的裝置。加數和被加數為輸入,和數與進位為輸出的裝置為半加器。減法電路是基本集成運放電路的一種,減法電路可以由反相加法電路構成,也可以由差分電路構成。基本集成運放電路有加、減、積分和微分等四種運算。一般是由集成運放外加反饋網絡所構成的運算電路來實現。
    發表于 08-16 11:09 ?16.6w次閱讀
    <b class='flag-5'>加法</b>器與減法器_反<b class='flag-5'>相加法</b>器與同<b class='flag-5'>相加法</b>器

    相加法器電路與原理

    加法器是為了實現加法的。即是產生數的和的裝置。加數和被加數為輸入,和數與進位為輸出的裝置為半加器。若加數、被加數與低位的進位數為輸入,而和數與進位為輸出則為全加器。常用作計算機算術邏輯部件,執行邏輯操作、移位與指令調用。
    發表于 01-29 10:49 ?3.3w次閱讀
    反<b class='flag-5'>相加法</b>器電路與原理

    相加法器EWB電路仿真的詳細資料免費下載

    本文檔的主要內容詳細介紹的是反相加法器EWB電路仿真的詳細資料免費下載。
    發表于 09-21 15:38 ?12次下載
    反<b class='flag-5'>相加法</b>器EWB電路仿真的詳細資料免費下載

    相加法器的應用領域

    相加法器(又稱為同相組合器、輸入能量合成器、同相求和器)是一種電子電路器件,主要應用在通信、信號處理、調試和測量等領域。
    的頭像 發表于 06-06 17:21 ?1490次閱讀
    同<b class='flag-5'>相加法</b>器的應用領域

    實用電路分享-同相加法

    相加法器(又稱為同相組合器、輸入能量合成器、同相求和器)是一種電子電路器件,主要應用在通信、信號處理、調試和測量等領域。
    的頭像 發表于 06-13 14:53 ?1.1w次閱讀
    實用電路分享-同<b class='flag-5'>相加法</b>器

    什么是反相加法運算電路?反相加法運算電路與減法運算電路

    在電子技術的海洋中,有一種電路如同數學中的加法器一樣,能夠將不同的信號進行相加處理。這就是被廣泛應用于信號處理領域的反相加法運算電路。
    的頭像 發表于 02-17 15:34 ?4231次閱讀
    什么是反<b class='flag-5'>相加法</b>運算電路?反<b class='flag-5'>相加法</b>運算電路與減法運算電路

    相加法運算電路原理介紹

    相加法運算電路利用運算放大器(通常簡稱為Op-Amp)的特性來實現多個輸入信號的加法運算。每個輸入信號都通過一個電阻連接到運算放大器的反相輸入端,而運算放大器的同相輸入端則接地或虛擬接地。輸出電壓
    的頭像 發表于 01-31 15:53 ?3312次閱讀
    反<b class='flag-5'>相加法</b>運算電路原理介紹

    相加法器和反相加法器的區別是什么

    相加法器和反相加法器是運算放大器在模擬電路設計中常用的兩種基本電路結構,它們在信號處理方面有著不同的特性和應用場景。
    的頭像 發表于 05-23 14:35 ?2265次閱讀

    FIR連續采樣分段卷積時域重疊相加法

    在上一個文檔里,我們提到了FIR系統在時域的分段卷積中使用“重疊保留(Overlap-Save)”的處理方式,這里我們續集,說明一下“重疊相加(Overlap-Add)”的處理方式。
    的頭像 發表于 06-14 10:30 ?1003次閱讀
    <b class='flag-5'>FIR</b>連續采樣分段卷積時域<b class='flag-5'>重疊</b><b class='flag-5'>相加法</b>