文章

傅里叶级数与傅里叶变换

本篇文章详细介绍傅里叶级数、傅里叶变换(离散型、逆变换、快速傅里叶变换等)

傅里叶级数与傅里叶变换

简述:

傅里叶级数与傅里叶变换在数论、信号处理、概率论、统计学、密码学、声学、光学等领域都有广泛的应用(傅里叶变换在声音处理,图片处理都有很大的用处,比如mp3压缩、jpeg、音频的可视化、计算机视觉等等这些东西几乎都离不开傅里叶变换)。 这篇文章将从傅里叶级数开始一步一步的到FFT和RFFT算法再到应用角度(以mp3压缩为例)。

傅里叶级数:

引(声音的叠加):

我先从声音的叠加入手, 简单的来讲, 我们日常听到的声音实际上都是由一系列的波叠加而成的比如:

下面有两组声音:

采样率: 44100; 采样深度: 16; 声道数: 2

声音1

声音2:

我们用简单的削峰算法(代码库):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bool mixWav(const WAVHeader& header1, const vector<short>& data1,const WAVHeader& header2, const vector<short>& data2,WAVHeader& outHeader, vector<short>& outData){
    if(
        header1.numChannels != header2.numChannels || 
        header1.sampleRate != header2.sampleRate
    ){
        cerr << "采样率不一致" << endl;
        return false;
    }

    outHeader = header1;
    
    uint32_t maxSamples = max(data1.size(),data2.size());
    outHeader.dataSize = maxSamples * sizeof(short);
    outHeader.fileSize = 36 + outHeader.dataSize;
    outData.resize(maxSamples);

    for(size_t i = 0;i<maxSamples;i++){
        short s1 = (i<data1.size()) ? data1[i] : 0;
        short s2 = (i<data2.size()) ? data2[i] : 0;
        int sum = s1 + s2;
        sum = max(min(sum,0x7FFF),-0x7FFF);
        outData[i] = static_cast<short>(sum);
    }

    return true;
}

得到的音频:

我们能够很清晰的听到两个声音同时传入了我们大脑,而且我们能听出来是不同的声音

emm,那么如果我们想要实现这一操作的逆变换呢?

叠加波的拆解

两个声音的叠加太复杂了,我们从简单的一个正弦波入手: $A\sin(\frac{2\pi}{T}x + \varphi)$

那么一个声音就可以表示为:

\[\sum_{i=0}^{n}{A_i\sin{(\frac{2\pi}{T_i}x} + \varphi_i)}\]

我们先从简单的入手:

\[\sum_{i=0}^{n}{A_i\sin{(\frac{2\pi}{T_i}x})}\]

好了那么我们怎么得到每一项的 ${A_i}$ 和 ${T_i}$呢?

我们看一个正弦波很有意思的特性: 假设存在两个正弦波: \(a_1\sin{(\omega _1x)}\) 和 \(a_2sin{(\omega _2 x)}\) 我们尝试去求 \(\int_{T}{a_1\sin{(\omega _1x)} \cdot a_2sin{(\omega _2 x)} \mathrm{d}x}\) 其中 $T$ 为两个正弦函数的公共周期;

我们先看情况1: \(\omega _1 = \omega _2 = \omega\)

\[\begin{array}{l} \int_{T}{a_1\sin{(\omega _1x)} \cdot a_2sin{(\omega _2 x)} \mathrm{d}x} \\ =\int_{T}{a_1a_2\sin^2{(\omega x)} \mathrm{d}x} \\ =a_1a_2\int_{T}{\frac{1-\cos{2x}}{2}}\mathrm{d}x \\ =a_1a_2\cdot \frac{T}{2} \end{array}\]

情况2: \(\omega _1 \neq \omega _2\)

\[\begin{array}{l} \int_{T}{a_1\sin{(\omega_1x)}\cdot a_2\sin{(\omega_2x)}}dx \\ = \frac{a_1a_2}{2}\int_{T}{\cos(\omega_1x - \omega_2x) - \cos(\omega_1x + \omega_2x)}dx \\ = \frac{a_1a_2}{2} \cdot (\frac{\sin(\omega_1 - \omega_2)T}{\omega_1 - \omega_2} - \frac{\sin(\omega_1 + \omega_2)T}{\omega_1 + \omega_2}) \end{array}\]

我们之前的条件: $T$ 为 公共周期,那么有:

\(\omega_1 = \frac{k_1 2 \pi}{T}, \omega_2 = \frac{k_2 2 \pi}{T}\\ k_1,k_2 = 1,2,3,4,5,...\) 则: \(\omega_1 \pm \omega_2 = (k_1 \pm k_2)\cdot \frac{2\pi}{T} \\ \text{那么:} \frac{a_1a_2}{2} \cdot (\frac{\sin(\omega_1 - \omega_2)T}{\omega_1 - \omega_2} - \frac{\sin(\omega_1 + \omega_2)T}{\omega_1 + \omega_2}) = 0\)

到这里我们就可以得到一个有意思的性质: 假设有一函数: \(f(x)\) 由一系列正弦波叠加而成,我们只要让他去和 \(\sin{wx}\)去相乘然后去求x的积分,我们就可以得到\(f(x)\) 所包含的正弦波\(\sin{wx}\) 以及他的 振幅 但是呢,到这里我们实际上就是将没有 初相的正弦波叠加 进行了拆分,那有初相呢?

首先:

\[a\sin{(\omega_1x + \varphi)} = a(\sin{(\omega_1)} \cos{(\varphi)} + \sin{(\varphi)}\cos{(\omega_1)})\]

我们发现有初相可以把初相分为 一个 正弦函数 和一个 余弦函数 再分别乘以他们的系数。 也就是说 我们只要保证 \(\sin{\omega_1x}\cos{\omega_2x} = 0\) 那么上述的性质就依然满足。 这个证明就忽略了,自己可以试试。 那么 \(\cos{\omega x}\) 的系数呢? 他会不会和 正弦函数 有一样的性质? 答案是 是的 这点就不给出证明了。

实际上这是因为三角函数是一种正交函数 有以下性质: 1.\(\omega_1 \neq \omega_2\) \(\int_{T}{sin{\omega_1x}\cdot sin{\omega_2x}} dx = \int_{T}{cos{\omega_1x}\cdot cos{\omega_2x}} dx = \int_{T}{sin{\omega_1x}\cdot cos{\omega_2x}} dx = 0\) 2.\(\omega_1 = \omega_2\) \(\int_{T}{sin{\omega_1x}\cdot sin{\omega_2x}} dx = \int_{T}{cos{\omega_1x}\cdot cos{\omega_2x}} dx = \frac{T}{2} \\ \int_{T}{sin{\omega_1x}\cdot cos{\omega_2x}} dx = 0\)

到这里我们就可以拆解叠加波了:

本文由作者按照 CC BY 4.0 进行授权