日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于小波变换的信号降噪处理及仿真研究_信号处理方法推荐--1(转载自用,侵删)...

發布時間:2023/12/4 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于小波变换的信号降噪处理及仿真研究_信号处理方法推荐--1(转载自用,侵删)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

綜述

作者:aresmiki
鏈接:https://www.zhihu.com/question/23701194/answer/167005497
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
非平穩信號處理應該是現在信號處理技術最新的也是最熱的研究方向了,信號處理方法從最早的時域統計到傅里葉變換的頻域分析,是人們認識信號本質的一次巨大飛躍,給了分析人員換個角度看世界的方法,這個時期傅里葉變換在調和分析,諧波分析等領域得到的巨大發展,當然工程人員將傅里葉變換也迅速運用的工程運用中,得到了巨大發展,特別是在機械故障診斷和 功能性磁共振成像fMRI 中。但是現實卻不是理論那么美好,人們發現,傅里葉變換作為一個全局變換,天然的少了另一個維度,如果將時間域信號比作一個平面中的物體的話,那么頻域信號也同樣是一個平面中的物體,只是給我們換了一個角度而已,而人們總是對三維世界的物體更具有直觀了解,平面的東西始終是不具體不形象,信號一樣,工程人員總是想知道信號有哪些頻率,且這些頻率在何時產生,而這個需求就給分析方法提出了一個要求,必須多一個維度,也就是頻域變換需要保留時間信息,聰明的Gabor第一次提出了窗口傅里葉變換,這個信號分析帶來了時間尺度,也第一次有了時頻分析的概念,當然其理論就不介紹了,而其優點當然就是同時給了我們時間和頻率的信息。科學的魅力就是,永遠沒有完美的理論,窗口福利葉變換的窗口如何選擇成為了一個難題,選的太大,時間分辨率太大,選的太小,頻率分辨率太大,如何能在該大的時候大,該小的時候小呢?偉大的Morlet告訴我們,傅里葉變換本身就是全局的,而我們為什么還非得堅守傅里葉變換這個全局框架下呢?這種變化快的信號本身就是短時局部的信號不斷變換,為什么不是一個個局部的去分析信號呢,這也是小波變換的基本思想,小波將時頻分析推向了研究高潮,這一時期小波理論不斷發展,出現了許多小波,db系列小波,morlet小波,coif系列小波等等,可以看出來,小波研究都是基于小波基函數的研究,它不像傅里葉變換一樣,基是固定的,而小波基函數有很多形式。這種靈活性給了小波廣泛的運用優勢,但是,科學就是這樣,一種方法的誕生必然伴隨著缺陷的誕生,小波基的這種靈活性卻給分析人員帶來困擾,如何針對不同信號選擇這些基呢?是否有一個通用基來處理信號分解任務呢?還有一個關鍵問題是,小波變換受到測不準原理的限制,不能無限制的細分時間和頻率。當然研究人員根據實際處理任務提出了相對通用的小波基,如圖像處理中的曲波變換和脊波變換,這一時期小波研究含有另一個方向,不是一個小波不能完全符合處理任務嗎?不是不好選擇小波基嗎?研究人員提出把多個小波基一起用,必然可以得到更好的結果,這典型的代表是多小波的發展。當然普通小波變換存在時移缺陷和頻率混疊的缺陷,而雙樹復數小波DTCWT得提出基本解決了該問題。也有針對小波基難以構造的缺陷,提出了提升框架的小波變換,但是小波變換就是小波變換,本質還是沒有改變,小波具有的問題,后面發展出來的方法依然存在這些問題,小波處理方法沒有過時,但是其諸多問題卻在工程運用中越來越明顯,工程運用中信號千變萬化,小波基選擇始終是擺在分析人員面前的問題,還有就是樓主提到的消噪,小波消噪軟閾值和硬閾值的選擇會對信號消噪能力有巨大影響,選擇不好要么消除不夠,有么太多。更直白的說,你說你消除了噪聲,那么萬一別人問你,你憑什么說你消除的是噪聲而不是有用信號了,這個問題是一個無法回答的問題。當然后小波時代崛起了一批數據驅動的非線性非平穩信號處理方法,這些方法的提出就是擺脫小波基選擇困難,測不準原理限制的問題,這類方法典型代表就是EMD,EMD方法根據信號自身特點不斷分離開來,噪聲和有用信號安照不同頻帶劃分分離開,當然由于EMD方法本身諸多問題,后來發展出來了EEMD,CEEMD,CEEMDAN。CWEEMDAN等方法,但是其數學基礎問題依然存疑,可是,EMD的提出給了人們一個啟發,信號分解就是要讓信號根據自己特點分開而不是人工的參與,一切應該是自驅動自適應才是最好的,受該思想的啟發,小波研究者也希望將小波推廣到這類方法中,其典型代表SWT和EWT,雖然方法很妙,但是其本質問題卻并非數據驅動,有興趣可以自行查閱文獻,當然繼承該思想的還有VMD、NSP、ITD方法,不得不提一下,這些方法都是非常適合非平穩非線性信號處理,但是分解中的一些參數設置卻十分困難。關于信號分析最前沿的方法和理論,推薦專欄 信號處理與機器學習 - 知乎專欄 里面講了很多信號處理方法的核心思想和最新方法。。。。

VMD(變分模態分解)(https://zhuanlan.zhihu.com/p/66898788?utm_source=qq)

這一篇寫一下變分模態分解(原始論文:Variational Mode Decomposition),跟原始論文思路思路一致但有一點點不太一樣,原始論文寫的很好,但我不是通信專業沒有學過信號相關課程一開始看起來有點費勁。模態分解認為信號是由不同“模態”的子信號疊加而成的,而變分模態分解則認為信號是由不同頻率占優的子信號疊加而成的,其目的是要把信號分解成不同頻率的子信號。變分模態分解的分解結果如圖所示

基礎

一開始論文看不懂的原因是缺少相關前置知識,但一旦順下來就會感覺其實沒有那么難,難的是作者的思路很巧妙,先寫下我遇到的這些知識盲點

第一點是傅立葉變換的微分性質,

的傅立葉變換為 ,其導數 的傅立葉變換為

另一點是解析信號,現實世界只能采集實信號,但實信號有很多不好用的性質,如存在負頻率,無法直接得到調制頻率后的實信號等。 設原始信號是一個實信號

為了方便表示 為隨 變化的函數,相當于瞬時頻率,解析信號是一個復信號,可以通過希爾伯特變換得到 解析信號的實部是原本的實數信號,并且經過調頻之后復數信號的實部仍然是調頻之后的實信號,如對信號 增加頻率 ,只需要乘以 即可 由此,其實部相當于在原本頻率 的基礎上增加了頻率 ,如下面的matlab腳本clear;close all;clc; t = 1:0.01:10; %% f1 = sin(20*t).*(t-5).^2; subplot(3,1,1); plot(f1); ylim([-25 25]); %% f2 = sin(50*t).*(t-5).^2; subplot(3,1,2); plot(f2); ylim([-25 25]); %% H = hilbert(f1); f_hat = H.*exp(1i*30.*t); subplot(3,1,3); plot(real(f_hat)); ylim([-25 25]);

matlab的hilbert函數包括希爾伯特變換和解析函數轉換兩部分,直接得到實信號的解析信號,其中希爾伯特變換

正文

接下來我們看看如何一步一步得到變分模態分解的思路

原論文通過一個信號降噪問題進行說明,現需要對采樣信號

進行降噪重構,假設觀測信號是由原始信號疊加一個獨立的高斯噪音 ,需要求 ,又說該等式是一個不適定問題(ill-posed problem),不滿足識定問題的三個條件,所以要用一個正則化的方法 第一部分是對原信號進行重構,第二部分是為了解決不適定問題的解不唯一,而且不同于機器學習的建模問題一樣 是一個權值形式可以直接加權值 的L1-norm或L2-norm,這里的 是一個純函數的形式,其導數的L2-norm最小化感覺上應該是保證了函數 不會產生太大的波動,這里可不可以跟防止過擬合聯系起來,接下來說明這個約束會使 在頻率域產生什么影響。

下面解這個式子,首先來看一下直接最小化泛函

能不能解出來 有 ,然后根據E-L方程的引理 得 ,往下忘了怎么求了。。。。。想起來怎么求再繼續寫-_-!,這個直接求的方法與原文沒什么關系的

由上面的傅立葉變換的微分性質知道,用傅立葉變換在復數域很方便可以把微分約掉,而且還有一個叫什么Plancherel傅立葉等距映射的東西,時域的L2范數與傅立葉變換到的頻率域的L2范數等距,故上面的最小化的項可以直接用傅立葉變換轉換到頻域

,這里需要注意的是利用上面的那個什么等距定理有 和 的 是同一個 ,這一點很重要,第二個是L2范數大于0,則把其展開為泛函 求最極值,由于這里面只有 直接求偏導即可也不用解微分方程

可以看到得到的

相當于對觀測信號在 在頻率段進行濾波,過濾掉了高頻部分,這說明加了該導數的L1正則約束與上面的直觀感覺是一樣的,過濾掉了高頻部分,減弱 的波動

再往下進行,模態分解需要把原始信號分解成多個子信號的和,我們為了和原文對應修改一下符號表示,

表示觀測的采樣信號, 表示分解得到的基函數,則上面的約束對象變為 同樣先轉化為頻率域再求極值 泛函

每個基函數基于其他的基函數更新,相當于每個基函數是原信號剩余部分的低通濾波,每次迭代都是保留剩余信號的低頻率部分。

到現在為止我們發現每個基函數都會趨向于每次的剩余信號分量的低頻部分,這與我們原始的假設“每個基函數都有不同的頻率分量”是相悖的,但根據上面的低通濾波的性質,每個基函數進行特定頻率的濾波應該就能解決這個問題了,那么上面的式子就簡單的變為

其中, 為每個基函數 的中心頻率,該式就是變分模態分解的基函數的更新公式,我們來看一下這個式子應該如何得到,以便于找到中心頻率的更新公式

由上面的一步一步的演化發現,基函數對剩余信號的低通濾波是由導數的L2正則最小化帶來的,要得到基函數的中心頻率約束也要從這個地方入手,由上面的推導可知每個基函數都會被約束到

頻率附近,那么我們把基函數的頻率增加各自的中心頻率 得到 ,并保證 即可,則相當于對每個基函數乘以了一個 ,這里需要對頻率進行變換,我們沿用文章開頭的解析信號的性質,認為 是一個復數的解析信號,同樣也需要把觀測信號 預先轉化為解析信號,下文默認都是解析信號,則每一個基函數轉換頻率后的導數變為

傅立葉變換得 先來看看傅立葉變換為什么會得到這個,而不是 反傅立葉變換 感覺應該不是這樣證的,我數學不是很好,不怎么會這個變量變換

至此,約束變為

傅立葉變換 根據論文原文把 然后求最小就可以得到上面 的更新公式

最后,為了保證每個點處的重構信號與原信號盡可能相似,增加了每個點處的重構約束,其實這一項并不是必需的,最終的約束對象為

,然后拉格朗日乘子法帶進去,但其需要滿足下式才有意義 這個式子還是符合Parseval定理,故整理一下

最后整理一下更新公式:

其中 使用梯度下降更新

代碼

%matplotlib inline from matplotlib import pyplot as plt import numpy as np from scipy.signal import hilbertT = 1000 fs = 1./T t = np.linspace(0, 1, 1000,endpoint=True) f_1 = 10 f_2 = 50 f_3 = 100 mode_1 = (2 * t) ** 2 mode_2 = np.sin(2 * np.pi * f_1 * t) mode_3 = np.sin(2 * np.pi * f_2 * t) mode_4 = np.sin(2 * np.pi * f_3 * t) f = mode_1 + mode_2 + mode_3 + mode_4 + 0.5 * np.random.randn(1000)plt.figure(figsize=(6,3), dpi=150) plt.plot(f, linewidth=1)

class VMD:def __init__(self, K, alpha, tau, tol=1e-7, maxIters=200, eps=1e-9):""":param K: 模態數:param alpha: 每個模態初始中心約束強度:param tau: 對偶項的梯度下降學習率:param tol: 終止閾值:param maxIters: 最大迭代次數:param eps: eps"""self.K =Kself.alpha = alphaself.tau = tauself.tol = tolself.maxIters = maxItersself.eps = epsdef __call__(self, f):T = f.shape[0]t = np.linspace(1, T, T) / Tomega = t - 1. / T# 轉換為解析信號f = hilbert(f)f_hat = np.fft.fft(f)u_hat = np.zeros((self.K, T), dtype=np.complex)omega_K = np.zeros((self.K,))lambda_hat = np.zeros((T,), dtype=np.complex)# 用以判斷u_hat_pre = np.zeros((self.K, T), dtype=np.complex)u_D = self.tol + self.eps# 迭代n = 0while n < self.maxIters and u_D > self.tol:for k in range(self.K):# u_hatsum_u_hat = np.sum(u_hat, axis=0) - u_hat[k, :]res = f_hat - sum_u_hatu_hat[k, :] = (res + lambda_hat / 2) / (1 + self.alpha * (omega - omega_K[k]) ** 2)# omegau_hat_k_2 = np.abs(u_hat[k, :]) ** 2omega_K[k] = np.sum(omega * u_hat_k_2) / np.sum(u_hat_k_2)# lambda_hatsum_u_hat = np.sum(u_hat, axis=0)res = f_hat - sum_u_hatlambda_hat -= self.tau * resn += 1u_D = np.sum(np.abs(u_hat - u_hat_pre) ** 2)u_hat_pre[::] = u_hat[::]# 重構,反傅立葉之后取實部u = np.real(np.fft.ifft(u_hat, axis=-1))omega_K = omega_K * Tidx = np.argsort(omega_K)omega_K = omega_K[idx]u = u[idx, :]return u, omega_KK = 4 alpha = 2000 tau = 1e-6 vmd = VMD(K, alpha, tau) u, omega_K = vmd(f) omega_K # array([0.85049797, 10.08516203, 50.0835613, 100.13259275])) plt.figure(figsize=(5,7), dpi=200) plt.subplot(4,1,1) plt.plot(mode_1, linewidth=0.5, linestyle='--') plt.plot(u[0,:], linewidth=0.2, c='r')plt.subplot(4,1,2) plt.plot(mode_2, linewidth=0.5, linestyle='--') plt.plot(u[1,:], linewidth=0.2, c='r')plt.subplot(4,1,3) plt.plot(mode_3, linewidth=0.5, linestyle='--') plt.plot(u[2,:], linewidth=0.2, c='r')plt.subplot(4,1,4) plt.plot(mode_4, linewidth=0.5, linestyle='--') plt.plot(u[3,:], linewidth=0.2, c='r') # [<matplotlib.lines.Line2D at 0x7fac532f4dd8>]


可以看到有比較強的端點效應,端點處會有重疊,文章原始論文中采用的方法是對稱拼接的方法,把原信號復制一份然后拼成兩半,一半對稱放前面,一般對稱放后面

%matplotlib inline from matplotlib import pyplot as plt import numpy as np from scipy.signal import hilbertT = 1000 fs = 1./T t = np.linspace(0, 1, 1000,endpoint=True)f_1 = 10 f_2 = 50 f_3 = 100 mode_1 = np.sin(2 * np.pi * f_1 * t) mode_2 = np.sin(2 * np.pi * f_2 * t) mode_3 = np.sin(2 * np.pi * f_3 * t) f = np.concatenate((mode_1[:301], mode_2[301:701], mode_3[701:])) + 0.1 * np.random.randn(1000)plt.figure(figsize=(6,3), dpi=150) plt.plot(f, linewidth=0.5) # [<matplotlib.lines.Line2D at 0x7fc2134b8630>]

class VMD:def __init__(self, K, alpha, tau, tol=1e-7, maxIters=200, eps=1e-9):""":param K: 模態數:param alpha: 每個模態初始中心約束強度:param tau: 對偶項的梯度下降學習率:param tol: 終止閾值:param maxIters: 最大迭代次數:param eps: eps"""self.K =Kself.alpha = alphaself.tau = tauself.tol = tolself.maxIters = maxItersself.eps = epsdef __call__(self, f):N = f.shape[0]# 對稱拼接f = np.concatenate((f[:N//2][::-1], f, f[N//2:][::-1]))T = f.shape[0]t = np.linspace(1, T, T) / Tomega = t - 1. / T# 轉換為解析信號f = hilbert(f)f_hat = np.fft.fft(f)u_hat = np.zeros((self.K, T), dtype=np.complex)omega_K = np.zeros((self.K,))lambda_hat = np.zeros((T,), dtype=np.complex)# 用以判斷u_hat_pre = np.zeros((self.K, T), dtype=np.complex)u_D = self.tol + self.eps# 迭代n = 0while n < self.maxIters and u_D > self.tol:for k in range(self.K):# u_hatsum_u_hat = np.sum(u_hat, axis=0) - u_hat[k, :]res = f_hat - sum_u_hatu_hat[k, :] = (res + lambda_hat / 2) / (1 + self.alpha * (omega - omega_K[k]) ** 2)# omegau_hat_k_2 = np.abs(u_hat[k, :]) ** 2omega_K[k] = np.sum(omega * u_hat_k_2) / np.sum(u_hat_k_2)# lambda_hatsum_u_hat = np.sum(u_hat, axis=0)res = f_hat - sum_u_hatlambda_hat -= self.tau * resn += 1u_D = np.sum(np.abs(u_hat - u_hat_pre) ** 2)u_hat_pre[::] = u_hat[::]# 重構,反傅立葉之后取實部u = np.real(np.fft.ifft(u_hat, axis=-1))u = u[:, N//2 : N//2 + N]omega_K = omega_K * T / 2idx = np.argsort(omega_K)omega_K = omega_K[idx]u = u[idx, :]return u, omega_KK = 3 alpha = 2000 tau = 1e-6 vmd = VMD(K, alpha, tau)u, omega_K = vmd(f) omega_K # array([ 9.68579292, 50.05232833, 100.12321047])plt.figure(figsize=(5,7), dpi=200) plt.subplot(3,1,1) plt.plot(mode_1, linewidth=0.5, linestyle='--') plt.plot(u[0,:], linewidth=0.2, c='r')plt.subplot(3,1,2) plt.plot(mode_2, linewidth=0.5, linestyle='--') plt.plot(u[1,:], linewidth=0.2, c='r')plt.subplot(3,1,3) plt.plot(mode_3, linewidth=0.5, linestyle='--') plt.plot(u[2,:], linewidth=0.2, c='r') # [<matplotlib.lines.Line2D at 0x7fc2134075c0>]

好像結果要好一點,VMD的一個缺點是K的值對結果有很大影響,但這個迭代過程,怎么開始怎么迭代怎么結束都可以自己控制,感覺可以按照自己的需求來定制怎么動態決定K

總結

以上是生活随笔為你收集整理的基于小波变换的信号降噪处理及仿真研究_信号处理方法推荐--1(转载自用,侵删)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。