【scipy 基礎】--訊號處理

wang_yb發表於2023-11-21

scipy.signal模組主要用於處理和分析訊號。
它提供了大量的函式和方法,用於濾波、卷積、傅立葉變換、噪聲生成、週期檢測、譜分析等訊號處理任務。

此模組的主要作用是提供一套完整的訊號處理工具,從而幫助使用者對各種連續或者離散的時間序列資料、音訊訊號、電訊號或其他物理訊號進行操作和分析。
它支援許多標準的和常用的訊號處理技術,例如傅立葉變換(用於頻譜分析和頻域濾波)、IIR和FIR濾波器設計、卷積、及相關性計算等。

1. 主要功能

訊號處理模組包含的函式非常豐富。

類別 說明
卷積相關函式 各類一維,二維陣列的卷積計算,包含約9個函式
B-樣條相關函式 n階B-樣條基函式的高斯*似,*滑樣條(立方體)濾波等等,包含約10多個函式
濾波函式相關 對 N 維陣列執行中值濾波器,維納濾波器等等,包含約20個函式
過濾器設計相關 使用雙線性變換從模擬濾波器返回數字IIR濾波器,使用最小二乘誤差最小化的FIR濾波器設計,使用視窗法進行FIR濾波器設計,包含約30個函式
連續時間線性系統 連續時間的,狀態空間形式的等各類線性時不變系統,計算其階躍響應,頻率響應等,包含約10個函式
離散時間線性系統 離散時間的,狀態空間形式的等各類線性時不變系統,計算其階躍響應,頻率響應等,包含約10個函式
LTI(線性非時變)表示 用於求解LTI系統的函式和方法,包括從輸入到輸出的傳遞函式的計算、系統穩定性的分析、系統響應的求解等,包含約10個函式
窗函式相關 用於濾波和譜估計的一套窗函式,包含約30個函式
小波相關函式 處理小波變換,濾波等,包含約7個函式
訊號峰值計算函式 計算訊號的極大,極小值,峰值的突出程度等,包含約7個函式
光譜分析相關函式 用於分析連續和離散的時間訊號、實數和複數的訊號等。分析訊號的頻譜分佈、頻率響應、譜密度等屬性等,包含約11個函式
線性調頻 Z 變換和變焦 FFT 是兩種特殊的訊號處理方法,用於在頻域對訊號進行變換和縮放,包含約5個函式

與其他子模組相比,明顯可以看出scipy.signal子模組的函式數量非常多。

這是因為訊號處理涉及的領域和應用場景非常廣,
包括通訊、計算機應用、物理、化學、生物學、軍事、經濟等領域;
以及聲音處理、影像處理、訊號分析、訊號檢測、頻譜分析、雷達、無線通訊、音訊處理、影片處理、遙感、生物醫學訊號處理、控制系統、訊號壓縮、模式識別等各種場景。

2. 功能示例

scipy.signal子模組的功能太多,下面演示其中幾個函式拋磚引玉。

2.1. 濾波器示例

既然是訊號處理模組,肯定離不開對波的處理。

我們首先構造兩個正弦波,一個10HZ,一個30HZ

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

sig1 = np.sin(2 * np.pi * 10 * t)
sig2 = np.sin(2 * np.pi * 30 * t)
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=[6, 4])
ax1.plot(t, sig1)
ax1.set_title("10 Hz 正弦波")
ax1.axis([0, 1, -2, 2])

ax2.plot(t, sig2)
ax2.set_title("30 Hz 正弦波")
ax2.axis([0, 1, -2, 2])

plt.show()

image.png

然後將2個正弦波混合起來,同一個20HZ的濾波器進行高通低通濾波。

t = np.linspace(0, 1, 1000, False)  # 1 second
sig = np.sin(2 * np.pi * 10 * t) + np.sin(2 * np.pi * 30 * t)
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=[6,6])
ax1.plot(t, sig)
ax1.set_title("10 Hz 和 30 Hz 混合")
ax1.axis([0, 1, -2, 2])

# 用20HZ的頻率 高通濾波
sos_high = signal.butter(10, 20, 'hp', fs=1000, output='sos')
# 用20HZ的頻率 低通濾波
sos_low = signal.butter(10, 20, 'lp', fs=1000, output='sos')

# 沿著一維過濾資料
filtered_high = signal.sosfilt(sos_high, sig)
filtered_low = signal.sosfilt(sos_low, sig)

ax2.plot(t, filtered_high)
ax2.set_title('20 Hz 高通濾波')
ax2.axis([0, 1, -2, 2])

ax3.plot(t, filtered_low)
ax3.set_title('20 Hz 低通濾波')
ax3.axis([0, 1, -2, 2])
ax3.set_xlabel('Time [seconds]')
plt.tight_layout()

plt.show()

image.png
從圖中可以看出,高通濾波之後的結果接* 30HZ 的波;
低通濾波之後的結果接* 10HZ 的波。

2.2. 圖片模糊度示例

圖片中的畫素也可以看做是二維的訊號,所以也可以用濾波器來調整圖片的模糊度。

from scipy import signal
import cv2

# 網路上隨便找的python logo 圖片
fp = "d:/share/python.png"
image = plt.imread(fp)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = np.asarray(gray, np.float64)

fig, ax = plt.subplots(2, 2, sharex=True, sharey=True, figsize=(4, 5))

# 高斯視窗
w1 = signal.windows.gaussian(101, 2.0)
w2 = signal.windows.gaussian(101, 6.0)
# 卷積與二維可分離FIR濾波器
image_new1 = signal.sepfir2d(gray, w1, w1)
image_new2 = signal.sepfir2d(gray, w2, w2)

ax[0][0].imshow(image)
ax[0][0].set_title("原始圖片")
ax[0][1].imshow(gray, cmap="gray")
ax[0][1].set_title("灰度圖片")

ax[1][0].imshow(image_new1)
ax[1][0].set_title("模糊度較低的圖片")
ax[1][1].imshow(image_new2)
ax[1][1].set_title("模糊度較高的圖片")

plt.show()

image.png

3. 總結

總的來說,scipy.signal模組的意義在於它提供了一個統一、強大且靈活的介面,使得對訊號進行處理和分析變得相對簡單。

它不僅支援基本的訊號處理操作,還提供了一些更高階的功能,例如使用不同的視窗函式進行傅立葉變換、使用不同的方法進行濾波等。
此外,它還與NumPy緊密整合,使得使用者可以方便地在陣列上執行各種操作。

相關文章