eric2013 发表于 2020-5-18 14:47:20

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:32

这个能无限提高分辨率么

eric2013 发表于 2020-6-5 15:00:31

卡卡倬 发表于 2020-6-5 14:59
这个能无限提高分辨率么

不能

飛饵 发表于 2020-8-18 13:21:01

想问下,波形采样后,能在进行分频吗?也就是原有数据上做降低采样率处理,而不用通过降低ADC采样率实现。
我的目的是,FFT点数不变情况下提高中低频信号的分辨率。比如32khz做256点变换是125hz分辨率,对中低频音频信号来说太低,所以想降低采样率。

eric2013 发表于 2020-8-18 13:47:21

飛饵 发表于 2020-8-18 13:21
想问下,波形采样后,能在进行分频吗?也就是原有数据上做降低采样率处理,而不用通过降低ADC采样率实现。
...

貌似无法实现这种骚操作。

飛饵 发表于 2020-8-18 13:54:01

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;
      }
    }

eric2013 发表于 2020-8-18 14:16:57

飛饵 发表于 2020-8-18 13:54
哈哈,网上找到个8分频的的算法,好像是用若干个已采样点数据相加取平均,算了下采样时间间隔是变大了, ...
可以,刚刚想到过采样了,没有想通这个逻辑关系。

比如现在主频是32KHz,采集32K个点,1秒1次,如果实现8分频的话,即4KHz采样,也要采集32K个点,就只能提升采样时间,8秒一次。

而你要求采样不变,那就只能过采样,32KHz频率的情况下,采样8秒,求平均,即8倍过采样 ====>等效于 4KHz采样,1秒采集32K个点。

飛饵 发表于 2020-8-18 16:41:56

eric2013 发表于 2020-8-18 14:16
可以,刚刚想到过采样了,没有想通这个逻辑关系。

比如现在主频是32KHz,采集32K个点,1秒1次,如果实 ...

这算法好像和你说的不太一样?他貌似是一次就完采1024个点,然后就取平均了,这样也能达到效果吗?

还有以前你有个帖子说没总结出对数横坐标的公式,这算法里也做了,您研究研究?{:13:}

eric2013 发表于 2020-8-18 16:49:16

飛饵 发表于 2020-8-18 16:41
这算法好像和你说的不太一样?他貌似是一次就完采1024个点,然后就取平均了,这样也能达到效果吗?

还 ...

他这个我没有看程序,我楼上的回复是没问题的。

另外你说的取对数,我专门发过一个帖子

【原创】2017年第一天,说说音乐频谱的那些事,主流的音频软件一般都是采用对数谱。
http://www.armbbs.cn/forum.php?mod=viewthread&tid=25129&fromuid=58
(出处: 硬汉嵌入式论坛)

飛饵 发表于 2020-8-18 17:03:05

eric2013 发表于 2020-8-18 16:49
他这个我没有看程序,我楼上的回复是没问题的。

另外你说的取对数,我专门发过一个帖子


好吧,有空试下效果。
还有那个帖子我也在底下讨论过。纵坐标轴我也做对数化了,效果很好。
只是,横坐标一直不知道怎么对数化

老虎的菜 发表于 2020-8-26 14:09:29

可以利用先滤波,然后在降低采样率提高分辨率,可以在32k采样率获得的数据每个N个抽一个采样率就变成了32/N了

落叶凋零 发表于 2021-9-27 10:50:37

补零补超过多少就没效果了呢?

eric2013 发表于 2021-9-27 10:52:27

落叶凋零 发表于 2021-9-27 10:50
补零补超过多少就没效果了呢?

这个要实测下,一般稍补点,问题不大。
页: [1]
查看完整版本: FFT补零计算的前后效果