<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 一,一維信號的拓延 在Mallat算法的推導中,假定輸入序列是無限長的,而實際應用中常常是分時采樣,即輸入序列為有限長.此時,濾波器系數與輸入序列卷積時就會出現輪空的現象.因此有必要對原始信號進行邊界延拓,減小邊界誤差.解決的方法通常有補零法和周期延拓法. 1)補零法是在輸入序列的末尾補零.補零法的缺點是可能人為造成輸入序列邊界的不連續,從而使得較高頻率的小波系數很大. 2)周期延拓法是將原來有限長的輸入序列拓展成周期的序列.周期延拓可適用于任何小波變換,但可能導致輸入序列邊緣的不連續,使得高頻系數較大.這種方式的拓延卷積后與源信號的長度一致。 3)對稱延拓(matlab默認采取這種方式)可避免輸入序列邊緣的不連續,但只適用于對稱小波變換.本文根據Mallat算法公式,編寫了對稱延拓方式的小波變換的一般實現方法. 注:筆者采用的編譯器為VS2013,當前系統為win10。 ### 1,常見的3種邊緣拓延方法 設輸入信號為f(n),長度為srcLen,濾波器長度為filterLen.下面給出信號邊界處理幾種方法的具體表達式如下: 1)周期拓延: ? ? ? ? ? ??f(n+ srcLen) ? , ?-(filterLen -1)≤ n< 0 ? f′(n)=??f(n) ? ? ? ? ? ? ? ? , ?0≤ n≤ srcLen?-1 ? ? ? ? ? ? f(n -srcLen) ? ?, ?srcLen -1< n≤srcLen+filterLen?-2 舉例說明:以“1 2 3 4 5 6 7 8”這個長度為8的信號為例,當濾波器的長度為4時,其具體的拓延長度為6(單邊為3): 6 7 8 (1 2 3 4 5 6 7 8)1 2 3 2)對稱延拓(本文重點) ? ? ? ? ? ? f(-n -1) ? ? ? ? ? ? ? ? ? ? , ? -(filterLen-1)≤ n< 0 f′(n)=? ? f(n) ? ? ? ? ? ? ? ? ? ? ? ? ?, ? 0≤ n≤srcLen-1 ? ? ? ? ? ? f(2srcLen -n -1) ? ? ? , ? srcLen-1< n≤ srcLen+ filterLen-2 舉例說明:以“1 2 3 4 5 6 7 8”這個長度為8的信號為例,當濾波器的長度為4時,其具體的拓延長度為6(單邊為3): 3 2 1 (1 2 3 4 5 6 7 8)8 7 6 3)零值填補 ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ?, ? -(filterLen -1)≤ n< 0 f′(n)=?? ? f(n) ? ? ? ? ? ?, ?0≤ n≤srcLen?-1 ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ?, ?srcLen?-1< n≤srcLen+filterLen?-2 舉例說明:以“1 2 3 4 5 6 7 8”這個長度為8的信號為例,當濾波器的長度為4時,其具體的拓延長度為6(單邊為3): 0 0 0 (1 2 3 4 5 6 7 8)0 0 0? #二,Mallat算法分解過程 在Mallat算法中,信號分解過程按照系數形式, ![](https://box.kancloud.cn/2016-03-02_56d65265429bc.jpg) 其中:hd(n)和gd(n)分別為分解的低通和高通濾波器系數,長度為filterLen?. 吐槽:信號濾波的過程其實就是濾波器與信號卷積的過程,也就是濾波器的頻譜和信號的頻譜相乘的過程。 那么低通濾波器頻譜是高頻低,低頻高,與信號相乘時高頻的會被過濾掉;高通濾波器同理! ### 1,詳細的分解過程 以db2小波為例,通過對稱拓延后的詳細計算過程如下: ![](https://box.kancloud.cn/2016-03-02_56d6526550cb8.jpg) 從上圖可知,小波的Mallat算法分解后的序列長度由原序列長srcLen和濾波器長filterLen決定。從Mallat算法(采用對稱拓延)的分解原理可知,分解后的序列就是原序列與濾波器序列的卷積再進行隔點抽取而來。即分解抽取的結果長度為(srcLen+filterLen-1)/2。 上述方法也是matlab默認采取的方法,在MATLAB中輸入代碼,查看結果便知: ~~~ [Lo_D,Hi_D,Lo_R,Hi_R] = wfilters('db2');%獲取小波系數 xx=[420.2, 423.53, 423.52, 423.35, 424.52, 428, 430.79, 428.92]; wname='db2'; level=1; [c,l]=wavedec(xx,level,wname);%進行一層分解 ~~~ 結果為(被存儲在系數矩陣c中,l記錄的是每段系數的長度): 595.429871699852??597.374655846484598.449909371632?604.108998389031607.245626013478 -2.03920021086643 ??0.509501871423169-1.289053089583672.33989974581161??-1.14513645475084 與上圖一致 ### 2,C++實現分解算法 獲取db2小波系數: ~~~ //系數精度很高,采自matlab extern double db2_Lo_D[4] = { -0.129409522550921, 0.224143868041857, 0.836516303737469, 0.482962913144690 }; extern double db2_Hi_D[4] = { -0.482962913144690, 0.836516303737469, -0.224143868041857, -0.129409522550921 }; extern double db2_Lo_R[4] = { 0.482962913144690, 0.836516303737469, 0.224143868041857, -0.129409522550921 }; extern double db2_Hi_R[4] = { -0.129409522550921, -0.224143868041857, 0.836516303737469, -0.482962913144690 }; ~~~ C++實現如下: ~~~ // 一維信號的小波分解 int CWavelet::DWT( double *pSrcData,//分解的源信號 int srcLen,//源信號的長度 double *pDstCeof//分解出來的,本函數將返回此長度 ) { //本程序禁止出現這種情況,否則數據出錯(對稱拓延長度為filterLen-1,如果大于了signalLen將越界) if (srcLen < m_dbFilter.filterLen - 1) { //實際上信號的長度可以是任意的(matlab順序:信號拓延-》卷積-》下采樣), //但是本程序為了算法速度,寫法上不允許 cerr << "錯誤信息:濾波器長度大于信號!" << endl; Sleep(1000); exit(1); } int exLen = (srcLen + m_dbFilter.filterLen - 1) / 2;//對稱拓延后系數的長度 int k = 0; double tmp = 0.0; for (int i = 0; i < exLen; i++) { pDstCeof[i] = 0.0; pDstCeof[i + exLen] = 0.0; for (int j = 0; j < m_dbFilter.filterLen; j++) { k = 2 * i - j + 1; //信號邊沿對稱延拓 if ((k<0) && (k >= -m_dbFilter.filterLen + 1))//左邊沿拓延 tmp = pSrcData[-k - 1]; else if ((k >= 0) && (k <= srcLen - 1))//保持不變 tmp = pSrcData[k]; else if ((k>srcLen - 1) && (k <= (srcLen + m_dbFilter.filterLen - 2)))//右邊沿拓延 tmp = pSrcData[2 * srcLen - k - 1]; else tmp = 0.0; pDstCeof[i] += m_dbFilter.Lo_D[j] * tmp; pDstCeof[i + exLen] += m_dbFilter.Hi_D[j] * tmp; } } return 2 * exLen; } ~~~ 處理結果為:(與matlab一致) ![](https://box.kancloud.cn/2016-03-02_56d652656a82a.jpg) 附帶測試主函數: ~~~ int main() { system("color 0A"); double s[8] = { 420.2, 423.53, 423.52, 423.35, 424.52, 428, 430.79, 428.92}; int signalLen = sizeof(s) / sizeof(double); cout << "原始信號:" << endl; for (int i = 0; i < signalLen; i++) cout << s[i] << " "; cout << endl; CWavelet cw(2); double *dst = new double[10]; cw.DWT(s, signalLen,dst); cout << "分解后的系數:" << endl; for (int i = 0; i < 10; i++) cout << dst[i] << " "; cout << endl; delete[] dst; dst = NULL; system("pause"); return 0; } ~~~ # 三,Mallat算法重構過程 ![](https://box.kancloud.cn/2016-03-02_56d652657e552.jpg) ### 1,詳細的重構過程 以db2小波為例,通過對稱拓延后的詳細重構過程如下: ![](https://box.kancloud.cn/2016-03-02_56d65265a06b5.jpg) 在matlab中我們可以通過以下代碼實現重構(完全實現原信號) ~~~ [Lo_D,Hi_D,Lo_R,Hi_R] = wfilters('db2');%獲取小波系數 xx=[420.2, 423.53, 423.52, 423.35, 424.52, 428, 430.79, 428.92]; wname='db2'; level=1; [c,l]=wavedec(xx,level,wname);%進行一層分解 cc=waverec(c,l,wname); ~~~ ###2,C++實現重構算法 ~~~ // 一維小波反變換,重構出源信號 void CWavelet::IDWT( double *pSrcCoef,//源分解系數 int dstLen,//重構出來的系數的長度 double *pDstData//重構出來的系數 ) { int p = 0; int caLen = (dstLen + m_dbFilter.filterLen - 1) / 2; for (int i = 0; i < dstLen; i++) { pDstData[i] = 0.0; for (int j = 0; j < caLen; j++) { p = i - 2 * j + m_dbFilter.filterLen - 2; //信號重構 if ((p >= 0) && (p<m_dbFilter.filterLen)) pDstData[i] += m_dbFilter.Lo_R[p] * pSrcCoef[j] + m_dbFilter.Hi_R[p] * pSrcCoef[j + caLen]; } } } ~~~ 處理結果(與matlab一致) ![](https://box.kancloud.cn/2016-03-02_56d65265c2c17.jpg) 附帶測試主函數: ~~~ int main() { system("color 0A"); double s[8] = { 420.2, 423.53, 423.52, 423.35, 424.52, 428, 430.79, 428.92}; int signalLen = sizeof(s) / sizeof(double); cout << "原始信號:" << endl; for (int i = 0; i < signalLen; i++) cout << s[i] << " "; cout << endl; CWavelet cw(2); double *dst = new double[10]; cw.DWT(s, signalLen,dst); cout << "分解后的系數:" << endl; for (int i = 0; i < 10; i++) cout << dst[i] << " "; cout << endl; double *dstsrc = new double[signalLen]; cw.IDWT(dst, signalLen, dstsrc); cout << "重構后的系數:" << endl; for (int i = 0; i < signalLen; i++) cout << dstsrc[i] << " "; cout << endl; delete[] dstsrc; dstsrc = NULL; delete[] dst; dst = NULL; system("pause"); return 0; } ~~~ #參考資源: 【1】喬世杰.小波圖像編碼中的對稱邊界延拓法[ J].中國圖像圖形學報,2000,5(2):725-729. ![](https://box.kancloud.cn/2016-03-02_56d65265d8a79.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看