🎧

Pythonで音声に画像を埋め込む

2022/07/04に公開

はじめに

Togetterを見ていたら,「とあるアイドルの楽曲に画像が仕込まれていた話」というまとめ記事が目に留まった.少し旬を過ぎてしまっている感はあるが,せっかくの機会なので,楽曲に画像を仕込む方法をメモしておく.

スペクトログラムとはなにか

本題へと入る前に,スペクトログラムとはなにか大まかに説明しておく.音声を解析するときは,しばしば「だいたい何Hzくらいの高さか」だとか「どんな高さの音が混ざっているか」だとかが重要になる.スペクトログラムは,これらを解析するのに便利なツールの1つである.

数学的なことは参考文献[2]と[3]にあるが,さしあたり,以下のことが重要である.

  1. 有限長の離散信号から計算される複素スペクトログラムXは,m\times n複素行列になる
  2. 振幅スペクトログラムAは,(i,j)成分がA_{i\,j}=\lvert X_{i\,j}\rvertm\times n実行列である
  3. A_{i\,j}は,時刻iNの十分近くにおける,j番目の周波数成分の強さを表している.ただし,Nはフレームシフトというパラメータであり,通常は正の整数である

たとえば,信号x(t)=\cos(\pi ft^2)をサンプリングしてできた離散信号の振幅スペクトログラムは,次のような直線状になる[1].ただし,上半分が振幅スペクトログラム,下半分が波形である.要するに,振幅スペクトログラムは時間変化する周波数の軌跡に相当する.

Audacityのスクリーンショット

画像をスペクトログラムに埋め込む

本題に入る.引用したツイートの画像は,振幅スペクトログラムを図示したものであった.振幅スペクトログラムは複素スペクトログラムの位相\arg X_{i\,j}をすべて0に変えてしまったものなので,振幅スペクトログラムだけが与えられても,元の音声信号を復元できるとは限らない.

しかし,スペクトログラムの性質をうまく使って,(少なくとも0よりは)自然な位相を後からつけ加える方法が知られている.その代表的な方法がGriffin-Limアルゴリズムである.

ここでは理論へと立ち入る代わりに,Griffin-Limアルゴリズムでスペクトログラムへと画像を埋め込めることをPythonで確かめる.Griffin-Limアルゴリズムにはlibrosa,スペクトログラムの表示はMatplotlibというライブラリを使い,以下のプログラムを作成した.

import numpy as np
from PIL import Image
import soundfile as sf
import librosa
import librosa.display
import matplotlib.pyplot as plt
from matplotlib import cm


def getGrayscaleMatrix(filename: str) -> np.ndarray:
    with Image.open(filename) as img:
        mat = np.array(img.convert(mode="L"))
        return np.flipud(mat) / 255


mag = getGrayscaleMatrix("wathematica.bmp")
wave = librosa.griffinlim(mag)
sf.write(file="embedded.wav", data=wave, samplerate=44100)

fig, ax = plt.subplots()
ax.specgram(wave, Fs=44100, NFFT=2048, noverlap=1024, cmap=cm.Greys)
ax.set(xlabel="Time [s]", ylabel="Frequency [Hz]")
plt.tight_layout()
plt.savefig("specgram.png", dpi=200)

このプログラムによって,次の画像wathematica.bmpを,音声embedded.wavへと変換した.その結果がリンク先の音声ファイルである.

Wathematicaの画像

この音声は雑音のようにしか聞こえないが,スペクトログラムを表示すると,次のように変換前の画像が現れてくる.

スペクトログラム

おわりに

実はこの記事,Wathematicaというサークルの企画で書いたものである.〆切前日に書き始めるとマジで地獄を見るので,こういうのは早めに着手すべきだと学んだ[2]

参考文献

  1. 諦メロン. “14平米にスーベニア 広川恵一Remixで一番ヤバいのは、スペクトログラムを表示すると凪の絵が出現すること”. Twitter. 2022-06-18. https://twitter.com/_Akira_Melon_/status/1538172760622776321, (参照 2022-07-03).
  2. 矢田部浩平, 升山義紀, 草野翼, 及川靖広. 特集, 位相情報を考慮した音声音響信号処理: 位相変換による複素スペクトログラムの表現. 日本音響学会誌. 2019, 75(3), p.147-155. https://www.jstage.jst.go.jp/article/jasj/75/3/75_147/_article/-char/ja, (参照 2022-07-03).
  3. 矢田部浩平. 特集, 短時間フーリエ変換入門~離散信号の時間周波数解析の理論と実装~: 第三回:短時間フーリエ変換. 日本音響学会誌. 2021, 77(6), p.396-403. https://www.jstage.jst.go.jp/article/jasj/77/6/77_396/_article/-char/ja/, (参照 2022-07-03).
脚注
  1. この図はAudacityというフリーソフトを使って作成した.さくっとスペクトログラムを見るのに便利なので,よく使っている. ↩︎

  2. 同じことは前回も学んだはずだったので,多分今回も学んでいない. ↩︎

Discussion