我希望使用FFT和Kissfft库来计算快速相关性,并且缩放需要精确.需要进行哪些缩放(向前和向后)以及我使用什么值来扩展数据?
标题解释了我的问题.
我想要做的很简单:
到目前为止我尝试过的
inline float scale(kiss_fft_scalar val)
{
int g = 0;
return val < 0 ? val*(1/32768.0f ) : val*(1/32767.0f);
}
void main()
{
mpg123_handle *m = NULL;
int channels = 0, encoding = 0;
long rate = 0;
int err = MPG123_OK;
err = mpg123_init();
m = mpg123_new(NULL, &err);
mpg123_open(m, "L:\\audio-io\\audio-analysis\\samples\\zero.mp3");
mpg123_getformat(m, &rate, &channels, &encoding);
err = mpg123_format_none(m);
err = mpg123_format(m, rate, channels, encoding);
// Get 2048 samples
const int TIME = 2048;
// …Run Code Online (Sandbox Code Playgroud) 我有一个使用常规卷积的高斯模糊的当前实现.对于小内核来说它足够有效,但是一旦内核的大小变得更大,性能就会受到影响.所以,我正在考虑使用FFT实现卷积.我从未有过与FFT相关的图像处理经验,所以我有几个问题.
基于2D FFT的卷积是否也可分为两个1D卷积?
现在我明白内核大小应该与图像大小相同(在1D的情况下为行).但它会如何影响边缘?我是否必须用零填充图像边缘?如果是这样,内核大小应该等于填充之前或之后的图像大小?
此外,这是一个C++项目,我打算使用kissFFT,因为这是一个商业项目.欢迎您提出更好的选择.谢谢.
编辑:感谢您的回复,但我还有一些问题.
我看到输入图像的虚部将全部为零.但输出虚部也会是零吗?我是否必须将高斯核与实部和虚部相乘?
我有相同图像的实例在不同尺度上被模糊,即相同的图像被缩放到不同的尺寸并且在不同的内核尺寸下被模糊.每次缩放图像时都必须执行FFT还是可以使用相同的FFT?
最后,如果我想要显示FFT,我知道必须将一个对数滤波器应用于FFT.但我真的迷失在哪个部分应该用于可视化FFT?真实的部分或虚部.
对于尺寸为512x512的图像,实部和虚部的大小也是如此.它们的长度是一样的吗?
再次感谢您的详细回复.
我编写了 C 程序,计算波函数的时间步迭代,以求解时间相关的 Schr\xc3\xb6dinger 方程。\n在某些步骤中,我需要进行前向和后向快速傅立叶变换 (FFT),我使用了库Kissfft。\ n(https://github.com/mborgerding/kissfft)
\n我的程序结构有点像这样:
\n现在,当我编译inttest_analytical.c它时,它可以工作。\n但是当之后尝试运行可执行文件时,我收到以下错误:
(base) user TDSE % ./inttest_analytical\ndyld: Library not loaded: libkissfft-double.dylib\n Referenced from: /Users/user/Documents/Uni/HU Berlin/Computational Physics 2/Project 3 - Time-dependet Schroedinger Equation/TDSE/./inttest_analytical\n Reason: image not found\nzsh: abort ./inttest_analytical\nRun Code Online (Sandbox Code Playgroud)\n运行后otool -L ./inttest_analytical我得到
/inttest_analytical:\n libkissfft-double.dylib (compatibility version 0.0.0, …Run Code Online (Sandbox Code Playgroud) 我对傅里叶变换的有限理解是,您应该能够在时域和频域之间切换,而无需更改原始数据.所以,这里是我(我想)我在做什么的总结:
使用kiss_fft_next_fast_size(994)以确定我应该使用1000.
使用kiss_fft_alloc(...)创建kiss_fft_cfg用nfft = 1000.
通过将额外点填充为零,将输入数据从大小994扩展到1000.
将kiss_fft_cfg传递给kiss_fft(...)我的输入和输出数组.
使用kiss_fft_alloc(...)创建逆kiss_fft_cfg用nfft = 1000.
传递逆kiss_fft_cfg以kiss_fft(...)输入先前的输出数组.
期待原始数据回来,但每个数据准确地大1000倍!
我在这里放了一个完整的例子,最后可以找到我的50多行代码.虽然我可以通过将每个结果除以OPTIMAL_SIZE(即1000)的值来解决这个问题,但是如果没有理解为什么那么修复会使我感到非常不安.
请问你能说出我做错的愚蠢事吗?
我目前正在尝试使用Kiss FFT将FFT实施到AVR32微控制器中,以进行信号处理。而且我的输出有一个奇怪的问题。基本上,我会将ADC样本(使用函数发生器进行测试)传递到fft(真实输入,256 n大小)中,并且检索到的输出对我来说很有意义。但是,如果我将汉明窗应用于ADC样本,然后将其传递给FFT,则峰值幅度的频率仓是错误的(并且与之前没有开窗的结果不同)。ADC样本具有DC偏移,因此我消除了偏移,但仍不适用于窗口样本。
以下是通过rs485的前几个输出值。第一列是没有窗口的fft输出,而第二列是有窗口的输出。从第1列开始,峰值位于第6行(6 x fs(10.5kHz)/ 0.5N)为我提供了正确的输入频率结果,其中第2列在第2行具有峰值幅度(直流仓除外),这对我来说没有意义。任何建议都会有所帮助。提前致谢。
488260 //直流仓
5 97
5 41
5 29
4 26
10 35
133 76
33 28
21 6
17 3
kiss_fft_scalar zero;
memset(&zero,0,sizeof(zero));
kiss_fft_cpx fft_input[n];
kiss_fft_cpx fft_output[n];
for(ctr=0; ctr<n; ctr++)
{
fft_input[ctr].r = zero;
fft_input[ctr].i = zero;
fft_output[ctr].r =zero;
fft_output[ctr].i = zero;
}
// IIR filter calculation
for (ctr=0; ctr<n; ctr++)
{
// filter calculation
y[ctr] = num_coef[0]*x[ctr];
y[ctr] += (num_coef[1]*x[ctr-1]) - (den_coef[1]*y[ctr-1]);
y[ctr] += (num_coef[2]*x[ctr-2]) - (den_coef[2]*y[ctr-2]);
//y1[ctr] += y[ctr] - 500; …Run Code Online (Sandbox Code Playgroud) 我正在使用 KissFFT 的 real 函数来转换一些真实的音频信号。我很困惑,因为我输入了带有 nfft 样本的真实信号,但结果是 nfft/2+1复数频率箱。
来自 KissFFT 的自述文件:
真正的(即不复杂)优化代码仅适用于偶数长度的 fft。它并行执行两个半长 FFT(打包为 real&imag),然后通过旋转将它们组合起来。结果是从 DC 到奈奎斯特的 nfft/2+1 复数频率档。
所以我不知道如何解释结果。我的假设是数据被打包成r[0]i[0]r[1]i[1]...r[nfft/2]i[nfft/2],其中 r[0] 是 DC,i[0] 是第一个频率仓,r[1] 是第二个频率仓,依此类推。是这样吗?
我是FFT概念的初学者,所以我理解的是,如果我输入1024个信号,我将获得513个区间,范围从0hz到22050Hz(在44100Hz采样率的情况下).在Cinder中使用KISS FFT,getBinSize函数返回1024个信号输入的预期513值.我不明白为什么会出现重复的峰值.运行经过20Hz到22000Hz频率(按顺序)的测试音频样本,我看到整个时间有两个峰值.它看起来像:
__ _ __ |__ _ __ _ __ |__ _ __
随着音频播放,峰值似乎彼此相向移动,因此第二个峰值似乎确实是第一个峰值的镜像副本.我经历过的每个例子似乎只是继续绘制所有513个值并且它们似乎没有这个镜像问题.我不确定我错过了什么.
我想找到持续时间为10秒的音频信号的4096点DFT,采样率为44100 Hz.因此,有441000个输入样本.但KissFFT最多只需4096作为输入大小.如何查找如此大信号的FFT?