Python 从频谱图识别时间相关信号

Python 从频谱图识别时间相关信号,python,image-processing,spectrogram,Python,Image Processing,Spectrogram,我正试图从一张光谱图中追踪几个信号。问题在于,随着时间的推移,信号的频率会发生变化,因此很难将其隔离。(见下图)是否有一个python函数能够随时间跟踪信号?请注意,在进行任何FTs之前,我没有访问原始数据的权限-只有光谱图本身的2D阵列 我所尝试的(为了缓和成功:) 按时间对2D频谱图进行切片,并在每次识别频率中的峰值 尝试跟踪峰值位置,以捕获每个信号随时间的变化 这种方法是拼凑的代码,但结果看起来很有希望,如下所示: 原始光谱图: 跨时间的频率跟踪: 我所寻找的是一种更稳健的方法来实现这

我正试图从一张光谱图中追踪几个信号。问题在于,随着时间的推移,信号的频率会发生变化,因此很难将其隔离。(见下图)是否有一个python函数能够随时间跟踪信号?请注意,在进行任何FTs之前,我没有访问原始数据的权限-只有光谱图本身的2D阵列

我所尝试的(为了缓和成功:)

  • 按时间对2D频谱图进行切片,并在每次识别频率中的峰值
  • 尝试跟踪峰值位置,以捕获每个信号随时间的变化
  • 这种方法是拼凑的代码,但结果看起来很有希望,如下所示:

    原始光谱图:

    跨时间的频率跟踪:

    我所寻找的是一种更稳健的方法来实现这一点。我希望不用写我自己的脚本,而是使用一些开发的工具来进行数据分析。这样的python工具存在吗

    谢谢

    这是我用来绘制这些图的代码。完全开放以完成大修,因为这显然不可靠

    import numpy as np
    from matplotlib.pyplot import *
    from matplotlib.colors import LogNorm
    
    data = np.load('spectrogram.npz')
    
    ## ---- trim data ---- ###
    
    it1=1000
    it2=1700
    if1=0
    if2=1900
    tvec = data['tvec'][it1:it2]
    fvec = data['fvec'][if1:if2]
    spect = data['spect'][0][if1:if2,it1:it2]
    v = np.linspace(min(spect.flatten()),0.1*max(spect.flatten()),100)
    
    ## ---- spectrogram ---- ###
    
    figure()
    contourf(tvec,fvec,spect,v,cmap=plt.cm.jet,norm=LogNorm())
    xlabel('Time (ms)')
    ylabel('Frequency (Hz)')
    
    ## ---- find modes ---- ###
    
    # initialize to NaNs
    kHz12 = np.full(len(tvec),np.nan)
    kHz25 = np.full(len(tvec),np.nan)
    kHz50 = np.full(len(tvec),np.nan)
    kHz50_f0 = 50E3
    kHz70 = np.full(len(tvec),np.nan)
    for i in range(it2-it1):
        x = spect[:,i]
        peaks, _ = scipy.signal.find_peaks(x,height=100,prominence=50)
        #scatter([tvec[i]]*len(peaks),fvec[peaks],1,marker='o')
    
        ### --- scroll through time and keep track of each frequency --- ###
        kHz12_subsel = [y for j,y in zip(peaks,x[peaks]) if fvec[j] > 11E3 and fvec[j] < 15E3]
        if kHz12_subsel: kHz12[i] = fvec[peaks][np.where(x[peaks] == np.max(kHz12_subsel))]
    
        kHz25[i] = fvec[peaks][np.argmax(x[peaks])]
    
        kHz50_subsel = [y for j,y in zip(peaks,x[peaks]) if fvec[j] > 45E3 and fvec[j] < 60E3]
        if kHz50_subsel: 
            kHz50[i] = fvec[peaks][np.argmin([abs(f-kHz50_f0) for f in fvec[peaks]])]
            kHz50_f0 = kHz50[i]
    
        kHz70_subsel = [j for j in peaks if fvec[j] > 60E3 and fvec[j] < 80E3]
        if kHz70_subsel:
            kHz70[i] = np.average(fvec[kHz70_subsel])
    
    ## ---- plot modes ---- ###
    
    plot(tvec,kHz12,lw=2,c='k')
    plot(tvec,kHz25,lw=2,c='k')
    plot(tvec,kHz50,lw=2,c='k')
    plot(tvec,kHz70,lw=2,c='k')
    
    将numpy导入为np
    从matplotlib.pyplot导入*
    从matplotlib.colors导入LogNorm
    data=np.load('spectrogram.npz'))
    ##----修剪数据----###
    it1=1000
    it2=1700
    如果1=0
    if2=1900
    tvec=数据['tvec'][it1:it2]
    fvec=数据['fvec'][if1:if2]
    spect=data['spect'][0][if1:if2,it1:it2]
    v=np.linspace(最小(spect.flatte()),0.1*max(spect.flatte()),100)
    ##----光谱图----###
    图(
    轮廓图(tvec,fvec,spect,v,cmap=plt.cm.jet,norm=LogNorm())
    xlabel(‘时间(毫秒)’)
    ylabel('频率(Hz)')
    ##----查找模式--###
    #初始化为NaNs
    kHz12=np.full(len(tvec),np.nan)
    kHz25=np.full(len(tvec),np.nan)
    kHz50=np.full(len(tvec),np.nan)
    kHz50_f0=50E3
    kHz70=np.full(len(tvec),np.nan)
    对于范围内的i(it2-it1):
    x=spect[:,i]
    峰值,u=scipy.signal.find_峰值(x,高度=100,突出度=50)
    #散射([tvec[i]]*len(峰值),fvec[峰值],1,标记为'o')
    ###---滚动时间并跟踪每个频率--###
    如果fvec[j]>11E3且fvec[j]<15E3,则kHz12_subsel=[y代表j,y在zip中(峰值,x[peaks])
    如果kHz12_海底:kHz12[i]=fvec[peaks][np.式中(x[peaks]==np.max(kHz12_海底))]
    kHz25[i]=fvec[峰值][np.argmax(x[峰值]]
    kHz50_subsel=[y代表j,y在zip中(峰值,x[peaks]),如果fvec[j]>45E3且fvec[j]<60E3]
    如果kHz50_海底:
    kHz50[i]=fvec[峰值][np.argmin([abs(f-kHz50_f0)表示fvec[峰值]]
    kHz50_f0=kHz50[i]
    kHz70_subsel=[j,如果fvec[j]>60E3且fvec[j]<80E3,则峰值中的j为j]
    如果kHz70_海底:
    kHz70[i]=np.平均值(fvec[kHz70_subsel])
    ##----打印模式--###
    绘图(tvec,kHz12,lw=2,c='k')
    绘图(tvec,kHz25,lw=2,c='k')
    绘图(tvec,kHz50,lw=2,c='k')
    绘图(tvec,kHz70,lw=2,c='k')
    
    请提供您用于创建第二幅图像的代码,好吗?@arnavpodar我已经添加了代码对不起,我找不到一个简单的函数来重建您所做的操作。但是,您可以将代码转换为带有
    def timething(foo,bar):
    和参数的函数,并使用它。稍后,您甚至可以尝试将您的函数/模块上载到python.org,以便其他人也可以使用它。请提供您用于创建第二个映像的代码给我们好吗?@arnavpodar我添加了代码抱歉,我找不到一个简单的函数可以重新创建您所做的操作。但是,您可以将代码转换为带有
    def timething(foo,bar):
    和参数的函数,并使用它。稍后,您甚至可以尝试将函数/模块上传到python.org,以便其他人也可以使用它。