1

私はスペクトログラムを持っています:

ここに画像の説明を入力

スペクトログラムをクリーンアップしたいので、特定の範囲内 (つまり、この例では 2627 ~ 3939) の周波数のみをキャプチャし、この周波数より下にあるすべてのブロックを削除します。私の全体的な目標は、この周波数範囲内にあり、識別できる 4 つのセグメントのみを残すことです。

これまでの私のコードは次のとおりです。

import wave, struct, numpy as np, matplotlib.mlab as mlab, pylab as pl
def wavToArr(wavefile):
    w = wave.open(wavefile,"rb")
    p = w.getparams()
    s = w.readframes(p[3])
    w.close()
    sd = np.fromstring(s, np.int16)
    return sd,p

def wavToSpec(wavefile,log=False,norm=False):
    wavArr,wavParams = wavToArr(wavefile)
    print wavParams
    return  mlab.specgram(wavArr, NFFT=256,Fs=wavParams[2],window=mlab.window_hanning,noverlap=128,sides='onesided',scale_by_freq=True)

wavArr,wavParams = wavToArr("4bats.wav")
Pxx, freqs, bins = wavToSpec("4bats.wav")
Pxx += 0.0001

freqs += (len(wavArr) / wavParams[2]) / 2.
hf=pl.figure(figsize=(12,12));
ax = hf.add_subplot(2,1,1);
#plot spectrogram as decibals
hm = ax.imshow(10*np.log10(Pxx),interpolation='nearest',origin='lower',aspect='auto')
hf.colorbar(hm)
ylcnt = len(ax.get_yticklabels())
ycnt = len(freqs)
ylstep = int(ycnt / ylcnt)
ax.set_yticklabels([ int(freqs[f]) for f in xrange(0,ycnt,ylstep) ])
pl.show()

問題は、Python を使用してこれを行う方法がわからないことです。範囲 (2627 ~ 3939) はわかっていますが、2D 配列全体を反復処理してすべてのブロックを合計するか、スペクトログラム内の各ブロックについて周波数を計算し、それがしきい値よりも高い場合はそれを維持します。それ以外の場合、値は 0.0 になりますか?

各ビンを合計すると、次のようになります。

ここに画像の説明を入力

これらのブロックを保持する必要がありますが、これら以外のすべてのブロックを削除したいと考えています。

誰かが私を助けてくれることを願っています!

4

1 に答える 1