如何在声谱图中计算给定频率的出现次数

-3 投票
1 回答
647 浏览
提问于 2025-04-18 01:03

我有一个声谱图,想要把某个特定频率出现的次数加起来:

我试着把问题整理一下,但最后发现没什么意义,抱歉。

这张图显示的是我加载的一个wav文件的信息,单位是分贝(dB)。这张图是用specgram方法得到的结果。

根据我的了解,从0.8秒开始,我可以看到四个主要的频率特征,分别是7k Hz、4.5 kHz、2.5 kHz和900 Hz。看起来这些频率在时间上是持续存在的,所以我想把它们出现的次数加起来。

我现在的源代码大致是这样的。你可以看到我获取了一些频率信息,但这些信息和图中的值(7k Hz、4.5 kHz、2.5 kHz、900 Hz)并不对应。

for i in range(0, int(RATE / CHUNK_SIZE * RECORD_SECONDS)):
  # little endian, signed shortdata_chunk
  data_chunk = array('h', stream.read(CHUNK_SIZE))
  if byteorder == 'big':
data_chunk.byteswap()
  data_all.extend(data_chunk)


# Take the fft and square each value
fftData=abs(np.fft.rfft(data_chunk))**2

# find the maximum
which = fftData[1:].argmax() + 1

# use quadratic interpolation around the max
if which != len(fftData)-1:
print "which %f and %f." % (which,which)
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it

#==   THIS IS NOT the real freq ======================================
#==   How can I get the values of the freq ???========================
thefreq = (which+x1)*RATE/CHUNK_SIZE
print "The freq is %f Hz. and %d" % (thefreq,int(thefreq) )
else:
thefreq = which*RATE/CHUNK_SIZE
print "The freq is %f Hz." % (thefreq)


Fs = 16000
f = np.arange(1, 9) * 2000
t = np.arange(RECORD_SECONDS * Fs) / Fs 
x = np.empty(t.shape)
for i in range(8):
x[i*Fs:(i+1)*Fs] = np.cos(2*np.pi * f[i] * t[i*Fs:(i+1)*Fs])

w = np.hamming(512)
Pxx, freqs, bins = mlab.specgram(data_all, NFFT=512, Fs=Fs, window=w, 
                noverlap=464)


#plot the spectrogram in dB
Pxx_dB = np.log10(Pxx)
pyplot.subplots_adjust(hspace=0.4)

pyplot.subplot(311)
ex1 = bins[0], bins[-1], freqs[0], freqs[-1]
pyplot.imshow(np.flipud(Pxx_dB), extent=ex1)
#pyplot.axis('auto')
pyplot.axis('tight')
pyplot.xlabel('time (s)')
pyplot.ylabel('freq (Hz)')


#==   EXTRA LOG                    ======================================

print ("The max number is  >>>>>", np.max(Pxx), " - ",  np.max(bins))
Pxx_dB = np.log10(Pxx)
print ("The max number is  >>>>>", np.max(Pxx_dB))


np.savetxt("./tmp__PXX", Pxx, fmt = '%f')
np.savetxt("./tmp__PXX_dB", Pxx_dB, fmt = '%f')



pyplot.show()

我想做的事情类似于这张图 enter image description here,你可以在另一个问题中找到这个图,链接是 去除特定频率范围内的频率。关键是我该如何计算这些频率的出现次数。

谢谢。

1 个回答

0

我参考了这个问题的答案,链接在这里:SO,然后把结果放到一个简单的矩阵里,问题就解决了,非常感谢大家的帮助!

撰写回答