Python實(shí)現(xiàn)數(shù)據(jù)濾波的示例詳解
維納濾波
信號經(jīng)過系統(tǒng)之后,相當(dāng)于進(jìn)行了卷積操作,若想讓其復(fù)原,只需再用系統(tǒng)進(jìn)行反卷積即可。如果沒有信號,系統(tǒng)卻有了響應(yīng),那么這種噪聲可以理解為系統(tǒng)的噪聲。如果系統(tǒng)的數(shù)學(xué)形式是已知的,這種噪聲就很容易濾掉,如果未知,那就需要進(jìn)行估計(jì),這就是維納做的工作。
一個有限脈沖響應(yīng)(finite impulse response, FIR),其離散形式可通過卷積表示為

x=sin(1.5πt(1−t)+2.1)+0.1sin(2.5πt+1)+0.18cos(7.6πt)
其濾波效果如下

實(shí)現(xiàn)代碼如下
import numpy as np
import scipy.signal as ss
t = np.linspace(-1, 1, 201)
PI = 2*np.pi
x = (np.sin(PI*0.75*t*(1-t) + 2.1) +
0.1*np.sin(PI*1.25*t + 1) +
0.18*np.cos(PI*3.85*t))
# 原始數(shù)據(jù)添加噪聲
np.random.seed(42)
xn = x + np.random.rand(len(t))
w = ss.wiener(xn, 9) # 維納濾波
plt.scatter(t, xn, marker='.', label="original")
plt.plot(t, w, c = 'r', label="wiener")
plt.legend()
plt.show()
【wiener】是signal模塊中的濾波函數(shù),其輸入?yún)?shù)分別是待濾波數(shù)據(jù)和濾波模板,此外還有一個noise,表示系統(tǒng)噪聲,默認(rèn)為None,表示自行估計(jì)噪聲。
巴特沃斯濾波器
FIR的特點(diǎn)是無反饋,yn 完全由xn決定,如果響應(yīng)受到反饋的影響,便是無限脈沖響應(yīng)(infinite impulse response, IIR),其離散形式變?yōu)?/p>

濾波器設(shè)計(jì),就是對ak,bk具體形式的求解,signal模塊中提供了一些函數(shù),對這兩種信號進(jìn)行濾波。仍以函數(shù)x為例,在添加噪聲之后,進(jìn)行濾波,對于不同的濾波函數(shù),其效果如下

代碼為
import scipy.signal as ss import matplotlib.pyplot as plt b, a = ss.butter(3, 0.05) z = ss.lfilter(b, a, xn) z2 = ss.lfilter(b, a, z) z3 = ss.filtfilt(b, a, xn) # 下面為繪圖代碼 plt.plot(t, z, 'r--', label="lfilter, once") plt.plot(t, z2, 'g--', label="lfilter, twice") plt.plot(t, z3, 'b', label="filtfilt") plt.scatter(t, xn, marker='.', alpha=0.75) plt.grid() plt.legend() plt.show()
其中,
【butter】函數(shù)生成3階巴特沃斯濾波器對應(yīng)的 a aa和b bb值
【lfilter】是最基礎(chǔ)的脈沖響應(yīng)濾波器,從左側(cè)開始進(jìn)行濾波,故而會產(chǎn)生相位差
【filtfilt】從正反兩個方向?yàn)V波,可消除了lfilter產(chǎn)生的相位差
中值濾波
中值濾波,就是挑選出將個濾波模板范圍內(nèi)數(shù)據(jù)的中位數(shù),例如[1,3,2,4]這個數(shù)組,給定一個長度為3的濾波窗口,那么元素3所在位置的濾波范圍就是1,3,2,其中位數(shù)是2,所以要把3更改為2。
import numpy as np import scipy.signal as ss x = [1,3,2,4] ss.medfilt(x,3) # [1, 2, 3, 2]
二維的中值濾波在圖像處理中非常常見,對椒鹽噪聲有著非常霸道的濾除效果。所謂椒鹽噪聲,如下方左圖所示,就是圖像中隨機(jī)產(chǎn)生的黑色和白色的斑點(diǎn)。在使用二維的中值濾波之后,整張圖片都變得清澈了。

繪圖代碼如下。
from scipy.misc import ascent
import matplotlib.pyplot as plt
img = ascent()
img = img[:256, :256]
r = np.random.rand(*img.shape)
img[r>0.96] = 255
img[r<0.04] = 0
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.subplot(122)
imFilt = ss.medfilt2d(img, [3,3])
plt.imshow(imFilt, cmap='gray')
plt.axis('off')
plt.show()
排序?yàn)V波
排序?yàn)V波是中值濾波概念的擴(kuò)充,和中值濾波的區(qū)別是,在對濾波窗口中的數(shù)據(jù)進(jìn)行排序之后,可以指定用以替代當(dāng)前數(shù)據(jù)的數(shù)值序號。下面四個矩陣,展示了以3×3單位矩陣為濾波模板,排序?yàn)V波在不同排序參數(shù)下的結(jié)果。

此濾波過程在scipy中的實(shí)現(xiàn)方式如下。
x = np.arange(25).reshape(5, 5).astype(float)
I = np.identity(3)
mats = {"original":x}
for i in range(3):
mats[f"order_filter:{i}"] = ss.order_filter(x, I, i)
【order_filter】即為signal模塊提供的排序?yàn)V波函數(shù),以輸入?yún)?shù)(x, I, i)為例,表示從矩陣x中選出單位陣I所覆蓋區(qū)域中第i小的元素。I是一個單位陣,就實(shí)際情況來看,其覆蓋的第一個子陣中,以0為中心,則只能覆蓋到2x2的范圍,對角元素0,6,最小值是0,最大值是6。如以6為中心,則可以完全覆蓋3x3的內(nèi)容,最小值為0,最大值為12。
下面是繪圖代碼。
def drawMat(x, ax=None):
M, N = x.shape
if not ax:
ax = plt.subplot()
arrM, arrN = np.arange(M), np.arange(N)
plt.yticks(arrM+0.5, arrM)
plt.xticks(arrN+0.5, arrN)
ax.pcolormesh(x)
ax.invert_yaxis()
for i,j in product(range(M),range(N)):
ax.text(j+0.2, i+0.6, f"{x[i,j]}")
for i,key in enumerate(mats,1):
ax = plt.subplot(2,2,i)
drawMat(mats[key], ax)
plt.title(key)
plt.show()
到此這篇關(guān)于Python實(shí)現(xiàn)數(shù)據(jù)濾波的示例詳解的文章就介紹到這了,更多相關(guān)Python數(shù)據(jù)濾波內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python將微信image下.dat文件解密為.png的方法
這篇文章主要介紹了使用python將微信image下.dat文件解密為.png的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
將pycharm配置為matlab或者spyder的用法說明
這篇文章主要介紹了將pycharm配置為matlab或者spyder的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
pip已經(jīng)安裝好第三方庫但pycharm中import時還是標(biāo)紅的解決方案
這篇文章主要介紹了python中pip已經(jīng)安裝好第三方庫但pycharm中import時還是標(biāo)紅的問題,本文給大家分享解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10

