アカデミック

【超初心者向け】pythonで音声認識⑧「ゼロ交差数で無声区間の判定をしよう」

pythonで簡単な音声認識をやってみたいぞ。

そもそも何から始めればいいのかしら。

今回は,基本的な音声認識をpythonで行う方法をお伝えしていこうと思います。本記事はpython実践講座シリーズの内容になります。その他の記事は,こちらの「Python入門講座/実践講座まとめ」をご覧ください。

【超初心者向け】python入門講座/実践講座まとめ目次 入門講座 1.実行環境2.文字の出力3.データ型4.変数5.更新と変換6.比較演算子7.論理演算子8.条件分岐9.リスト10.辞...

コーディングに関して未熟な部分がたくさんあると思いますので,もし何かお気づきの方は教えていただけると幸いです。また,誤りについてもご指摘していただけると非常に助かります。

お題

ゼロ交差数を使って無声区間を検出してみよう。

流れ

今回対象とするデータは,私が喋った「あ」とします。音声データを貼り付けるのは,どこか恥ずかしさを覚えるため,代わりにスペクトログラムをお見せしておきます。しっかり「あ」の発音区間が見え,無声区間も含まれていることが分かります。

ゼロ交差数の概要

ゼロ交差数は,音声信号を時間領域の波形で見たときに「振幅の正負が何回入れ替わるか」を表す数値です。

ゼロ交差数でなにが分かるの?

ゼロ交差数は,信号が雑音っぽいときに大きくなり,周期信号っぽいときに小さい値をとる傾向にあります。つまり,ゼロ交差数の大小で「雑音 or それ以外」を大まかに判別できるということです。この記事では,波形信号を短いフレーム単位で切り出して,そのフレームでゼロ交差数をカウントして閾値を設けることで,各フレームが雑音(無音区間)なのか,それとも有声区間なのかを判定してみたいと思います。

実装

音声の読み込み

# [path_to_your_file]にはみなさんの使用するファイルを指定してください。
y, sr = librosa.load([path_to_your_file])

# フレームのズラす幅の指定
hop_length = 512

# フレームで切り出す回数
nms = ((y.shape[0])//hop_length)+1

# 最初と最後をフレームで切り出せるようにゼロパディング
y_bf = np.zeros(hop_length*2)
y_af = np.zeros(hop_length*2)
y_concat = np.concatenate([y_bf, y, y_af])

ゼロ交差数のカウント

zero_cross_list = []
for j in range(nms):
  zero_cross = 0
  # フレームによる切り出し
  y_this = y_concat[j*512:j*512+2048]
  for i in range(y_this.shape[0]-1):
    # もし正負が変わったらという条件
    if (np.sign(y_this[i]) - np.sign(y_this[i+1]))!=0:
      zero_cross += 1
  zero_cross_list.append(zero_cross)

# 最大値が1になるように正規化
zero_cross_list = np.array(zero_cross_list)/max(zero_cross_list)

# 閾値は0.4に設定(ヒューリスティックですが…)
zero_cross_list = (zero_cross_list<0.4)*1

可視化

spec = librosa.stft(y, hop_length=512, n_fft=2048)
logmel_db = librosa.feature.melspectrogram(sr=sr, S=librosa.power_to_db(np.abs(spec)**2), n_mels=80)
plt.imshow(logmel_db, vmin=np.min(logmel_db), vmax=np.max(logmel_db), cmap="gist_heat", aspect= "auto", origin="lower")
plt.plot(np.arange(logmel_db.shape[1]), (zero_cross_list)*10)
plt.xlabel("Time_frame")
plt.ylabel("Frequency [Hz]")

今回の可視化では,有声区間を「10」,無声区間を「0」として出力しました。かなり精度よく有声区間を推定できているのではないでしょうか。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です