FFT补零计算的前后效果
有时候我们采集的数据不够256,512,1024等数据,就可以通过补零来解决,比如下面是采集了200个点,通过补零到512个点fs=200; % 采样频率
N=200; % 信号长度
n=1:N; % 样点索引
t=(n-1)/fs; % 时间刻度
x=cos(2*pi*30*t)+cos(2*pi*65.5*t); % 信号
X1=fft(x, N); % 按N点进行FFT
freq1=(0:N/2)*fs/N; % N点时正频率刻度
X1_abs=abs(X1(1:N/2+1))*2/N; % 信号幅值
L=512;
X2=fft(x,L); % 按L长进行FFT
freq2=(0:L/2)*fs/L; % L点时频率刻度
X2_abs=abs(X2(1:L/2+1))*2/N; % 信号幅值
subplot 211;
plot(freq1,X1_abs);
grid;
ylim();
xlabel('频率/Hz');
ylabel('幅值');
title('(a) 补零前FFT谱图')
subplot 212;
plot(freq2,X2_abs);
grid;
ylim();
xlabel('频率/Hz');
ylabel('幅值');
title('(b) 补零后FFT谱图')
效果
这个能无限提高分辨率么 卡卡倬 发表于 2020-6-5 14:59
这个能无限提高分辨率么
不能 想问下,波形采样后,能在进行分频吗?也就是原有数据上做降低采样率处理,而不用通过降低ADC采样率实现。
我的目的是,FFT点数不变情况下提高中低频信号的分辨率。比如32khz做256点变换是125hz分辨率,对中低频音频信号来说太低,所以想降低采样率。 飛饵 发表于 2020-8-18 13:21
想问下,波形采样后,能在进行分频吗?也就是原有数据上做降低采样率处理,而不用通过降低ADC采样率实现。
...
貌似无法实现这种骚操作。
eric2013 发表于 2020-8-18 13:47
貌似无法实现这种骚操作。
哈哈,网上找到个8分频的的算法,好像是用若干个已采样点数据相加取平均,算了下采样时间间隔是变大了,但不知道这样的做法合不合理。
/**
* 显示频谱时进行FFT计算
*
* @param buf
* @param samplerate 采样率
*/
public void spectrogram(int[] buf, double samplerate) {
first_fft_real = buf;
first_fft_imag = 0;
second_fft_real = buf;
second_fft_imag = 0;
for (int i = 0; i < FFT_SIZE; i++) {
first_fft_real = buf;
first_fft_imag = 0;
// 八分频(相当于降低了8倍采样率),这样1024缓存区中的fft频率密度就越大,有利于取低频
second_fft_real = (buf + buf + buf
+ buf + buf + buf
+ buf + buf) / 8.0;
second_fft_imag = 0;
}
// 高频部分从原始数据取
fft(first_fft_real, first_fft_imag, FFT_SIZE);
// 八分频后的1024个数据的FFT,频率间隔为5.512Hz(samplerate / 8),取低频部分
fft(second_fft_real, second_fft_imag, FFT_SIZE);
//这里算出的是每一个频点的坐标,对应横坐标的值,因为是定值,所以只需要算一次
if (loc == null) {
loc = new int;
sampleratePoint = new double;
for (int i = 0; i < loc.length; i++) {
//20000表示的最大频点20KHZ,这里的20-20K之间坐标的数据成对数关系,这是音频标准
double F = Math.pow(20000 / 20, 1.0 / SPECTROGRAM_COUNT);//方法中20为低频起点20HZ,31为段数
sampleratePoint = 20 * Math.pow(F, i);//乘方,30为低频起点
//这里的samplerate为采样率(samplerate / (1024 * 8))是8分频后点FFT的点密度
loc = (int) (sampleratePoint / (samplerate / (1024 * 8)));//估算出每一个频点的位置
}
}
//低频部分
for (int j = 0; j < LowFreqDividing; j++) {
int k = loc;
// 低频部分:八分频的数据,取31段,以第14段为分界点,小于为低频部分,大于为高频部分
// 这里的14是需要取数后分析确定的,确保低频有足够的数可取
real = second_fft_real; //这里的real和imag对应fft运算的实部和虚部
imag = second_fft_imag;
}
// 高频部分,高频部分不需要分频
for (int m = LowFreqDividing; m < loc.length; m++) {
int k = loc;
real = first_fft_real;
imag = first_fft_imag;
}
}
飛饵 发表于 2020-8-18 13:54
哈哈,网上找到个8分频的的算法,好像是用若干个已采样点数据相加取平均,算了下采样时间间隔是变大了, ...
可以,刚刚想到过采样了,没有想通这个逻辑关系。
比如现在主频是32KHz,采集32K个点,1秒1次,如果实现8分频的话,即4KHz采样,也要采集32K个点,就只能提升采样时间,8秒一次。
而你要求采样不变,那就只能过采样,32KHz频率的情况下,采样8秒,求平均,即8倍过采样 ====>等效于 4KHz采样,1秒采集32K个点。
eric2013 发表于 2020-8-18 14:16
可以,刚刚想到过采样了,没有想通这个逻辑关系。
比如现在主频是32KHz,采集32K个点,1秒1次,如果实 ...
这算法好像和你说的不太一样?他貌似是一次就完采1024个点,然后就取平均了,这样也能达到效果吗?
还有以前你有个帖子说没总结出对数横坐标的公式,这算法里也做了,您研究研究?{:13:} 飛饵 发表于 2020-8-18 16:41
这算法好像和你说的不太一样?他貌似是一次就完采1024个点,然后就取平均了,这样也能达到效果吗?
还 ...
他这个我没有看程序,我楼上的回复是没问题的。
另外你说的取对数,我专门发过一个帖子
【原创】2017年第一天,说说音乐频谱的那些事,主流的音频软件一般都是采用对数谱。
http://www.armbbs.cn/forum.php?mod=viewthread&tid=25129&fromuid=58
(出处: 硬汉嵌入式论坛)
eric2013 发表于 2020-8-18 16:49
他这个我没有看程序,我楼上的回复是没问题的。
另外你说的取对数,我专门发过一个帖子
好吧,有空试下效果。
还有那个帖子我也在底下讨论过。纵坐标轴我也做对数化了,效果很好。
只是,横坐标一直不知道怎么对数化 可以利用先滤波,然后在降低采样率提高分辨率,可以在32k采样率获得的数据每个N个抽一个采样率就变成了32/N了 补零补超过多少就没效果了呢? 落叶凋零 发表于 2021-9-27 10:50
补零补超过多少就没效果了呢?
这个要实测下,一般稍补点,问题不大。
页:
[1]