# 經典頻率濾波器 (低通、高通、帶通) 實戰速查表

在處理感測器訊號、音訊或心電圖 (ECG) 時，我們的訊號通常會混雜著各種不同頻率的波。透過濾波器，我們可以精準地「切出」我們想要的頻段。

---

## 1. 三大濾波器白話解析

### 🐢 低通濾波器 (Low-pass Filter, LPF)
* **保鑣規則：** 「低頻率 (變化慢的) 通過，高頻率 (變化快的) 擋下來！」
* **白話情境：** 就像你隔著牆壁聽隔壁開趴的音樂，你只會聽到「咚、咚、咚」的低音貝斯，因為高音（人聲、鈸聲）被牆壁（低通濾波器）擋住了。
* **工程用途：** **消除雜訊、平滑訊號。** 感測器的雜訊通常是高頻的毛刺（上下劇烈跳動），用 LPF 切掉高頻，訊號就會變得非常平滑。

### 🐇 高通濾波器 (High-pass Filter, HPF)
* **保鑣規則：** 「高頻率 (變化快的) 通過，低頻率 (變化慢的) 擋下來！」
* **白話情境：** 就像照相機的「邊緣檢測」。一整面平滑的白牆（低頻）會變成黑色的，但牆壁邊緣的銳利輪廓（高頻/劇烈變化）會被保留下來凸顯。
* **工程用途：** **消除基準線飄移 (Baseline Wander)、捕捉突發事件。** 比如移除重力造成的長期固定偏差，只保留瞬間的撞擊震動。

### 🎯 帶通濾波器 (Band-pass Filter, BPF)
* **保鑣規則：** 「只有某個『特定頻率範圍』的可以通過，太低或太高的通通擋掉！」
* **白話情境：** 收音機調頻！空氣中充滿了幾千個頻道的電磁波，當你轉到 FM 91.7，你的收音機就是啟動了一個 BPF，只讓 91.7 MHz 附近的頻率進來。
* **工程用途：** **提取特定特徵。** 例如人聲大約落在 300 Hz 到 3400 Hz 之間，用 BPF 把這個區間切出來，就能消除超低頻的風聲和超高頻的電流嘶嘶聲。

---

## 2. MATLAB 濾波器實戰：巴特沃斯濾波器 (Butterworth)

在 MATLAB 裡，最經典、最平滑、最常用的就是巴特沃斯濾波器。
⚠️ **核心觀念：奈奎斯特頻率 (Nyquist Frequency)**
在設計數位濾波器時，MATLAB 需要的頻率參數通常是「正規化」的。你必須先算出你的**取樣頻率 (Sampling Rate, $f_s$) 的一半**，這就是奈奎斯特頻率。

```matlab
% 1. 創造一個混合訊號 (低頻主訊號 + 高頻雜訊)
fs = 1000;                     % 取樣頻率 1000 Hz (每秒抓 1000 個點)
t = 0 : 1/fs : 1 - 1/fs;       % 建立 1 秒的時間軸

f_low = 5;                     % 5 Hz 的緩慢波 (我們想要的訊號)
f_high = 100;                  % 100 Hz 的快速波 (我們討厭的雜訊)

% 混合在一起的原始訊號
sig_raw = sin(2 * pi * f_low * t) + 0.5 * sin(2 * pi * f_high * t);

% --- 準備濾波器參數 ---
nyquist = fs / 2;              % 奈奎斯特頻率 (1000/2 = 500 Hz)
order = 4;                     % 濾波器階數 (數字越大，切得越乾淨，但運算越慢且可能變形)

% 2. 設計並應用【低通濾波器 LPF】(砍掉 50Hz 以上的)
cutoff_LPF = 50 / nyquist;     % 設定截止頻率 $f_c$ 為 50 Hz，並正規化
[b_low, a_low] = butter(order, cutoff_LPF, 'low');
sig_lpf = filtfilt(b_low, a_low, sig_raw);  % 使用 filtfilt 可以達成「零相位延遲」(訊號不會往後平移)

% 3. 設計並應用【高通濾波器 HPF】(砍掉 20Hz 以下的)
cutoff_HPF = 20 / nyquist;     % 設定截止頻率為 20 Hz
[b_high, a_high] = butter(order, cutoff_HPF, 'high');
sig_hpf = filtfilt(b_high, a_high, sig_raw);

% 4. 設計並應用【帶通濾波器 BPF】(只保留 80Hz 到 120Hz 之間的)
cutoff_BPF = [80 120] / nyquist; % 帶通需要輸入兩個數字的陣列
[b_band, a_band] = butter(order, cutoff_BPF, 'bandpass');
sig_bpf = filtfilt(b_band, a_band, sig_raw);

% 5. 畫圖大車拚
figure;
subplot(4,1,1); plot(t, sig_raw); title('1. 原始混合訊號 (5Hz + 100Hz)'); grid on;
subplot(4,1,2); plot(t, sig_lpf, 'r'); title('2. 低通濾波結果 (只剩 5Hz)'); grid on;
subplot(4,1,3); plot(t, sig_hpf, 'g'); title('3. 高通濾波結果 (只剩 100Hz)'); grid on;
subplot(4,1,4); plot(t, sig_bpf, 'm'); title('4. 帶通濾波結果 (精準抓出 100Hz)'); grid on;
```

### 💡 實戰隱藏秘訣：`filter` vs `filtfilt`
如果你去查網路，很多人會教你用 `filter(b, a, data)`。但強烈建議在「非即時（已經錄好整段數據）」的情況下，一律改用 `filtfilt(b, a, data)`！
因為一般濾波器會造成訊號「時間延遲（相位偏移）」，導致濾完波的波峰跟原始波峰對不起來。`filtfilt` 會正向濾一次、反向再濾一次，完美消除延遲，讓你的波形前後完全對齊！