跳轉到

2.2 過零率#

概念說明#

過零率(zero-crossing rate, ZCR)統計訊號在一框內「由正變負或由負變正」的次數,是最廉價的頻率內容指標——完全不需要任何傅立葉轉換。

直覺很簡單:振動越快,波形穿越零點越頻繁。因此 ZCR 大致與訊號的「主頻」或「高頻含量」成正比:

  • 對單一正弦波 \(f\) Hz,每個週期穿越零點 2 次,故 ZCR(以每樣本計) \(\approx 2f/f_s\) 。
  • 對寬頻的雜訊(如嘶嘶聲、摩擦音),高頻成分多,ZCR 高。
  • 對低頻的哼聲、母音的共振峰區,ZCR 低。

ZCR 在語音處理中的經典用途是有聲/無聲判別(voiced / unvoiced):母音(如「啊」)能量集中在低頻、ZCR 低;擦音(如「斯」、「西」)像雜訊、ZCR 高。結合 2.1 節的短時能量,「能量 + ZCR」兩個特徵就能做初階的語音端點偵測與音素粗分類。此外 ZCR 也常用於打擊樂器(鼓、鈸)與音高樂器的粗略區分。

標準定義(每樣本平均):

\[ ZCR = \frac{1}{2N}\sum_{n=1}^{N-1} |\operatorname{sgn}(x[n]) - \operatorname{sgn}(x[n-1])| \]

其中 \(\operatorname{sgn}\) 是正負號函數;除以 \(2N\) 把「穿越次數」換算成每樣本穿越率(一次穿越在差分中貢獻 2)。

實務陷阱:當訊號接近零但有低量的直流偏移或量測雜訊時,會在零點附近抖動,產生大量假穿越。解法是先把訊號減去均值(去直流),或要求穿越幅度超過一個小門檻(門檻化過零,thresholded ZCR)。

演算法步驟#

  1. 取一框訊號 \(x[0..N-1]\) 。
  2. 減去框內均值,去除直流偏移。
  3. 計算相鄰樣本乘積 \(x[n] \cdot x[n-1]\) ;乘積 \(< 0\) 代表發生一次過零(門檻化版本另要求 \(|x[n]|\) 與 \(|x[n-1]|\) 皆超過門檻)。
  4. 統計過零次數 \(c\) ,回報 \(c/(N-1)\) 或 \(c/(2(N-1))\) (視定義)。
  5. 逐框重複,得到 ZCR 的時間序列,與能量包絡並列分析。

Python 範例#

import numpy as np

fs = 8000
t = np.arange(0, 1.0, 1/fs)

def zcr(frame, threshold=0.0):
    frame = frame - frame.mean()                 # 去直流
    a, b = frame[:-1], frame[1:]
    crossing = (a * b < 0) & (np.abs(a) > threshold) & (np.abs(b) > threshold)
    return crossing.mean()

# 三種典型訊號
x_tone  = np.sin(2*np.pi*220*t)                  # 低頻純音
x_vowel = np.sin(2*np.pi*220*t) + 0.5*np.sin(2*np.pi*700*t) + 0.2*np.sin(2*np.pi*2400*t)
x_noise = np.random.default_rng(0).normal(0, 0.3, len(t))

for name, sig in [("220Hz 純音", x_tone), ("母音模擬", x_vowel), ("白雜訊", x_noise)]:
    frame = sig[:800]                            # 100ms
    z = zcr(frame)
    est_f = z * fs / 2                           # 每樣本穿越率 * fs/2 ≈ 主頻
    print(f"{name:10s}  ZCR={z:.4f}  (以穿越率推估主頻 ≈ {est_f:6.1f} Hz)")

輸出:

220Hz 純音   ZCR=0.0549  (以穿越率推估主頻 ≈  220.0 Hz)
母音模擬   ZCR=0.0797  (以穿越率推估主頻 ≈  318.8 Hz)
白雜訊   ZCR=0.4894  (以穿越率推估主頻 ≈ 1957.6 Hz)

純音的推估頻率與真值完全一致;混合多個諧波的「母音」落在成分頻率之間;白雜訊則接近理論上限 0.5(樣本正負獨立時,相鄰兩樣本異號的機率恰為 \(1/2\) )。

複雜度分析#

單框 \(N\) 樣本的 ZCR 只需一次線性掃描與比較,時間 \(O(N)\) 、空間 \(O(1)\) ,且只用到減法、乘法與比較,在嵌入式系統上甚至不需要浮點乘法(可用符號判斷替代)。整段訊號逐框計算的總成本為 \(O(N \cdot L/H)\) ,與音量包絡同階。相較 FFT 的 \(O(N\log N)\) ,ZCR 是「每一分運算換最多資訊」的特徵,適合即時、低功耗場景。

練習#

  1. 產生 8 kHz 取樣、330 Hz 的方波與三角波,計算並比較兩者的 ZCR;解釋為何方波的 ZCR 略低於正弦波推估值的兩倍。
  2. 在 220 Hz 正弦波上加入均值 0.01 的直流偏移,比較「有去直流」與「無去直流」的 ZCR 差異,並實作門檻化過零修正它。
  3. 錄一段(或合成一段)包含母音「ㄚ」與擦音「ㄙ」的訊號,畫出(或以文字列出)逐框「能量 + ZCR」表格,設計簡單規則區分有聲與無聲段。