Мне было интересно, как можно обнаружить новые пики на графике БПФ в Python. скажем, у меня есть этот простой сюжет: И я хочу автоматически измерить «Сходство» или расположение пиков в зашумленном сигнале, я пытался использовать косинусное сходство, но мой реальный сигнал слишком шумно, и даже если я добавлю к сигналу новый пик, я продолжаю получать косинус 0,9, поскольку это только один пик. Это пример моего реального сигнала, и у меня также есть проблема, заключающаяся в том, что мой сигнал может смещаться в пределах измерений, поэтому я не могу получить стабильный массив частот, они могут находиться в окне +/- 100 Гц: Это код, который использовался для первого сюжета:
import numpy as np
from pylab import *
import scipy.fftpack
# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y1 = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)+ 0.7*np.sin(30.0 * 2.0*np.pi*x)+ 0.5*np.sin(10.0 * 2.0*np.pi*x)
y2 = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)+ 0.2*np.sin(60.0 * 2.0*np.pi*x)+ 0.4*np.sin(40.0 * 2.0*np.pi*x)
yf1 = scipy.fftpack.fft(y1)
yf2 = scipy.fftpack.fft(y2)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
fig, ax = plt.subplots()
plot(xf, 2.0/N * np.abs(yf1[:N/2]))
plot(xf, 2.0/N * np.abs(yf2[:N/2]))
xlabel('Freq (Hz)',fontsize=16,weight='bold')
ylabel('|Y(freq)|',fontsize=16,weight='bold')
ax = gca()
fontsize = 14
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
tick.label1.set_fontweight('bold')
for tick in ax.yaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
tick.label1.set_fontweight('bold')
grid(True)
show()
def cosine_similarity(v1,v2):
"compute cosine similarity of v1 to v2: (v1 dot v2)/{||v1||*||v2||)"
sumxx, sumxy, sumyy = 0, 0, 0
for i in range(len(v1)):
x = v1[i]; y = v2[i]
sumxx += x*x
sumyy += y*y
sumxy += x*y
return sumxy/math.sqrt(sumxx*sumyy)
print 'Cosine Similarity', cosine_similarity(2.0/N * np.abs(yf1[:N/2]),2.0/N * np.abs(yf2[:N/2]))
Я также хотел установить порог, но иногда пики в реальном сигнале могут быть меньше, чем предварительно определенный порог. Есть идеи ?