Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python scipy.fftpack.rfft频率bin映射_Python_Numpy_Scipy_Signal Processing_Fft - Fatal编程技术网

Python scipy.fftpack.rfft频率bin映射

Python scipy.fftpack.rfft频率bin映射,python,numpy,scipy,signal-processing,fft,Python,Numpy,Scipy,Signal Processing,Fft,我试图根据给定的频率得到正确的FFT bin索引。音频采样频率为44.1k Hz,FFT大小为1024。假设信号是真实的(从PyAudio捕获,通过numpy.fromstring解码,通过scipy.signal.hann加窗),然后通过scipy.fftpack.rfft执行FFT,并计算结果的分贝,总的来说,幅值=20*scipy.log10(abs(rfft(音频样本)) 基于和,我最初将FFT bin索引k映射到任何频率F,如下所示: F=k*Fs/N表示k=0。。。N/2-1其中Fs

我试图根据给定的频率得到正确的FFT bin索引。音频采样频率为
44.1k Hz
,FFT大小为
1024
。假设信号是真实的(从PyAudio捕获,通过
numpy.fromstring
解码,通过
scipy.signal.hann
加窗),然后通过
scipy.fftpack.rfft
执行FFT,并计算结果的分贝,总的来说,
幅值=20*scipy.log10(abs(rfft(音频样本))

基于和,我最初将FFT bin索引
k
映射到任何频率
F
,如下所示:

F=k*Fs/N表示k=0。。。N/2-1
其中
Fs
是采样率,
N
是FFT单元大小,在这种情况下,
1024
。反之亦然:

k=F*N/Fs表示F=0Hz。。。Fs/2-Fs/N

然而,意识到
rfft
的结果不像
fft
那样是对称的,并且在
N
大小的数组中提供结果。我现在有一些关于映射和函数的问题。不幸的是,文档并没有提供太多的信息,因为我是这方面的新手

我的问题是:

  • 对我来说,音频样本的
    rfft
    结果可以直接从第一个存储箱使用到最后一个存储箱,因为输出中没有对称性,对吗

  • 鉴于上述情况缺乏对称性,频率分辨率似乎有所提高,这种解释正确吗

  • 由于使用了
    rfft
    ,我从bin索引
    k
    到频率
    F
    的映射函数现在是
    F=k*Fs/(2N)表示k=0。。。N-1
    是否正确

  • 相反,从频率
    F
    到bin索引
    k
    的反向映射函数现在变为
    k=2*F*N/Fs,F=0Hz。。。Fs/2-(Fs/2/N)
    ,这个的正确性如何


  • 我的一般困惑源于
    rfft
    如何与
    fft
    相关,以及如何在使用
    rfft
    时正确进行映射。我相信我的映射会被少量偏移,这在我的应用程序中是至关重要的。如果可能,请指出错误或就此提出建议,非常感谢。

    首先要为您澄清一些事情:

    快速参考显示rfft仅提供0..512的输出向量(在您的示例中)。其原因正是因为计算实值输入的离散傅里叶变换时存在对称性: y[k]=y*[N-k](参见)。因此,rfft函数仅计算和存储N/2+1值,因为您可以通过只获取复数共轭来计算另一半值(如果您真的希望它用于打印(比如))。fft函数对输入值不作任何假设(它们可以有实部和虚部),因此在输出中不能假设对称性,它提供了一个具有N个值的完整输出向量。诚然,大多数应用程序使用真实输入,因此人们倾向于假设对称性总是存在的。请注意,快速傅里叶变换(FFT)是计算离散傅里叶变换(DFT)的有效算法,rfft函数也使用FFT进行计算

    鉴于上述情况,用于访问输出向量的索引超出范围,即>512。这样做的原因/方式取决于您的代码。您应该清楚地区分“逻辑N”(用于映射bin频率、定义DFT等)和“计算N”(输出向量中的实际值数),然后所有问题都应该消失

    具体回答您的问题:

  • 不,这是对称的,你需要用它来计算最后的箱子(但它们不会给你额外的信息)

  • 不可以。提高DFT分辨率的唯一方法是增加采样长度

  • 没有,但差不多了。F=k*Fs/N表示k=0..N/2

  • 对于具有N个单元的输出向量,可以得到0到(N-1)/N*Fs的频率。使用rfft,您将有一个带有N/2+1个箱子的输出向量。你做数学,但我得到0..Fs/2


  • 希望事情现在变得更清楚。

    您是否确实尝试过在长度为N的向量上使用
    scipy.fftpack.rfft
    ?你会发现它确实给你一个长度N的输出。您可能正在考虑
    np.fft.rfft
    ,它将为您提供长度为
    N//2+1
    的输出。我没有使用fftpack,也没有使用Python,但我引用的文档确实是用于fftpack的,并且不影响理论的解释,我认为这是造成混淆的原因。正如我所暗示的,我不知道N个元素可以访问的原因(可能是N个输入值被复制,转换运行到位),但我不相信N/2以上的值,因为它与文档以及rfft函数的基本要点相矛盾。再次查看文档,以获得均匀长度的输入,输出是
    [y(0),Re(y(1)),Im(y(1)),…,Re(y(n/2))]
    ,即它似乎包含交错的实部和虚部。进一步,它澄清了“
    如果未指定n(默认值),则n=x.shape[轴]
    ”。是对这个输出的解释混淆了OP,坦率地说,我也是。好的,我理解你的观点。我引用的(逻辑)值是复数值,而不是数组的实际元素(我假设它存储为复数数据类型)。假设输出将(n/2+1)复数值存储为向量中的n个独立元素,而不是复数数据类型,则应仅使用适当的索引来计算各个存储单元的大小。访问输出的机制/语法我无能为力。正如我所说,区分逻辑和计算