看到一篇有关于信号相关、卷积的文章,感觉写的很好,借鉴一下,记录一下信号相关性的知识。
互相关反映向量 x 和移位(滞后)向量 y 之间的相似性。
最直观的解释是:互相关的作用是为了找到信号在哪一时刻与另一信号最像(另一信号为本身时就是自相关)!
互相关和自相关在本质上是两个函数做内积运算。即向量内积的连续形式。其在线性空间角度上的意义是:一个向量在另一个向量上的投影,内积结果越大,投影越大,两个向量间夹角越小,方向越一致,相似度越高。
把互相关的两个输入序列变成一样的,就是求一个序列的自相关了。自相关能够找出重复模式(如被噪声掩盖的周期信号),或识别隐含在信号谐波频率中消失的基频。
(互相关计算式中,
即可)
下面是一个简单的求序列自相关(滑动点积)的例子:
求序列 A = [1 2 3 4] 的自相关系数:
结果:[4 11 20 30 20 11 4],长度为 N 的序列,其自相关函数结果长度为 2N-1,是偶函数,且关于 N 中心对称,这也是自相关函数的特性。
计算互相关的过程和计算卷积很像,其本质都是两个序列滑动乘累加(滑动内积),但区别在于:
在时域中计算相关,matlab 提供了 xcorr 函数,它实际上就是把一个序列固定 A,另一个序列 B 从最后一位对齐序列 A 的第一位到序列 B 的第一位对齐序列 A 的最后一位,每一次移动一位的同时再将对应的值相乘再累加。
如上图所示:
代码如下:
% 定义序列 A 和 B
A = [1 2 3 4];
B = [1 2 3 4];
% 计算互相关
[correlation, lags] = xcorr(A, B);
% 绘制互相关结果
figure;
stem(lags, correlation);
title('Cross-Correlation between A and B');
xlabel('Lags');
ylabel('Correlation');
结果如下:
对于信号 A(长度为 M)和信号 B(长度为 N),不指定额外的参数时,xcrorr(A,B)
函数返回一个长度为 2*max(M,N)-1
的向量,其中包含了所有可能的滞后值的互相关。例如上面结果,如果 M=4 和 N=4,则滞后范围从 -3 到 +3。
频域的相乘等于时域的卷积,时域的卷积和相关不同的是,它计算时需要把序列反转再去做相乘累加。
傅立叶变换在处理信号时具有一个重要的性质:对信号取共轭复数在时间域相当于时间反转(即
变为
)。那么只要我们做频域相乘的时候把其中一个取共轭,就可以得到时域的相关。
这里还涉及到一个循环卷积和线性卷积的问题:直接把两个信号做FFT,取共轭相乘,再做 IFFT 得出来的是循环卷积的结果。
刚刚我们在时域做相关的时候,第一个数是 B 的最右边和 A 的最左边相乘的结果,也就是这样
A: 1 2 3 4
B: 1 2 3 4
但用 FFT 等效的循环卷积,它会把超出相乘范围的值移动到另一边去,当算到 B 的最右边和 A 的最左边相乘时,本来其他位置应该用 0 计算的,却成了序列中其他的元素去计算了:
A: 1 2 3 4
B: 4 1 2 3
所以为了让我们的结果能正确,我们需要给两个序列补 0,使得每个序列长度为
,差多少补多少。这里 A 和 B 的长度都为 4,所以要把他们都补到 4+4-1=7;此时 A=[1 2 3 4 0 0 0],B=[1 2 3 4 0 0 0],我们再来看这个时候的相乘累加值:
A: 1 2 3 4 0 0 0
B: 4 0 0 0 1 2 3
代码如下:
A = [1, 2, 3, 4]; % 信号A
B = [1, 2, 3, 4]; % 信号B
N = length(A) + length(B)-1;
lags = -3 : 1 : 3;
% 计算A和B的FFT
FA = fft(A, N);
FB = fft(B, N);
% 乘以B的共轭复数FFT并做IFFT得到互相关,fftshift完成频谱搬移
% r0 = ifft( FA .*conj(FB), N);
r0 = fftshift(ifft( FA .*conj(FB), N));
% 绘制互相关结果
figure;
stem(lags, r0);
title('Cross-Correlation between A and B');
xlabel('Lags');
ylabel('Correlation');
结果如下:
可以看到,我们通过补 0 来使得循环卷积获得线性卷积一样的结果。
下面我们分析一下正弦波信号和 Zadoff-Chu 序列的频域自相关结果
% 参数设置
N = 128; % 序列长度
u = 5; % Zadoff-Chu序列的根序号,通常选择一个与N互质的正整数
% 步骤 1: 生成128点的Zadoff-Chu序列
zc_seq = exp(-1i*pi*u*(0:N-1).^2/N); % Zadoff-Chu序列公式
% 步骤 2: 绘制时域波形
figure;
subplot(2,1,1);
stem(0:N-1, real(zc_seq), 'b'); % 绘制实部
hold on;
stem(0:N-1, imag(zc_seq), 'r'); % 绘制虚部
title('Original Zadoff-Chu Sequence (Time Domain)');
xlabel('Sample Index');
ylabel('Amplitude');
legend('Real Part', 'Imaginary Part');
% 步骤 3: 进行FFT
zc_fft = fft(zc_seq);
% 步骤 4: 计算FFT结果和其复共轭的乘积
zc_fft_conj_product = zc_fft .* conj(zc_fft);
% 步骤 5: 进行IFFT
zc_ifft = ifft(zc_fft_conj_product);
% 步骤 6: 绘制IFFT的时域图
subplot(2,1,2);
plot(0:N-1, real(zc_ifft), 'b');
hold on;
plot(0:N-1, imag(zc_ifft), 'r');
title('IFFT of the Product of FFT and its Complex Conjugate');
xlabel('Sample Index');
ylabel('Amplitude');
legend('Real Part', 'Imaginary Part');
图中第二个子图显示的IFFT结果几乎全为直流偏置(实部),而虚部几乎为零,这反映了处理后信号的功率主要集中在 0 频率处。原信号的细节和动态结构在这一处理过程中已经丢失。
% 步骤 1: 生成128点的正弦信号
N = 128; % 信号长度
t = 0:N-1; % 时间向量
f = 1; % 频率
x = sin(2*pi*f*t/N); % 正弦信号
% 步骤 2: 绘制时域波形
figure;
subplot(2,1,1); % 分为两行一列,这是第一幅图
plot(t, x);
title('Original Sinusoidal Signal');
xlabel('Time');
ylabel('Amplitude');
% 步骤 3: 对信号进行FFT
X = fft(x);
% 步骤 4: 计算FFT的结果和其复共轭的乘积
Y = X .* conj(X);
% 步骤 5: 对结果进行IFFT
y = ifft(Y);
% 步骤 6: 绘制IFFT的时域图
subplot(2,1,2); % 分为两行一列,这是第二幅图
plot(t, y);
title('IFFT of the Product of FFT and its Complex Conjugate');
xlabel('Time');
ylabel('Amplitude');
正弦信号经过 FFT、与其复共轭乘积以及 IFFT 的过程后,结果看似与原始信号在幅度上一致,但相位有所不同。这种现象可以通过理解 FFT、复共轭和 IFFT 在处理信号时的作用来解释。
正弦信号和 Zadoff-Chu 序列在经过 FFT、乘以其复共轭、进行 IFFT 的处理后显示不一致的结果,主要归因于这两种信号的本质差异及其在频域中的表现。
参考: https://zhuanlan.zhihu.com/p/613949451 https://blog.csdn.net/weixin_44253012/article/details/136293715