匹配时变(一维)信号的算法

12

我想知道有没有一种用于比较时间相关信号的算法/技术。理想情况下,这种假设的算法将接受两个信号作为输入,并返回一个数字,表示信号之间的相似度百分比(0表示两个信号在统计上无关,1表示它们完全匹配)。

当然,我意识到我的请求存在问题,即我不确定如何在比较这两个信号的上下文中正确定义“相似性”,所以如果有人能指点我方向(我应该查找/了解什么等等),我也会感激不尽。

6个回答

16

交叉相关函数是经典的信号处理解决方案。如果您可以使用Matlab,请参见XCORR函数。max(abs(xcorr(Signal1, Signal2, 'coeff')))将为您提供您要查找的特定内容,并且在Python中存在等效项。

交叉相关假设您正在寻找的"相似性"是两个信号之间线性关系的度量。对于具有时间索引n = 0..N-1的实值有限长度信号,其定义为:

C[g] = sum{m = 0..N-1} (x1[m] * x2[g+m])

g-N..N运行(超出该范围,求和内的乘积为0)。

尽管您要求一个数字,但函数非常有趣。函数域g被称为滞后域。

如果x1x2由时间移位相关,则交叉相关函数将在对应于移位的滞后处达到峰值。例如,如果您有x1 = sin[wn]x2 = sin[wn + phi],因此是两个在不同相位下具有相同频率的正弦波,交叉相关函数将在对应于相位差的滞后处达到峰值。

如果x2x1的缩放版本,则交叉相关性也会缩放。您可以通过除以sqrt(sum(x1^2)*sum(x2^2))来将函数标准化为相关系数,并通过取绝对值(Matlab中的这行代码)将其带入0..1

更一般地说,以下是交叉相关适用/不适用的概述。

交叉相关可用于确定一个信号是否与另一个信号线性相关,即如果
x2(t) = sum{n = 0..K-1}(A_n * x1(t + phi_n))
其中x1(t)x2(t)是所讨论的信号,A_n是缩放因子,phi_n是时间移位。这意味着:

  1. 如果一个信号是另一个信号的时间平移版本(phi_n <> 0 for some n),则交叉相关函数将非零。
  2. 如果一个信号是另一个信号的缩放版本(A_n <> 0 for some n),则交叉相关函数将非零。
  3. 如果一个信号是另一个信号的缩放和时间平移版本的组合(对于一些n,A_nphi_n都不为零),则交叉相关函数将非零。注意这也是线性滤波器的定义。

更具体地说,假设x1是宽带随机信号。令x2=x1。现在,归一化的交叉相关函数在g=0处完全为1,在其他地方接近0。现在让x2成为x1的(线性)滤波版本。交叉相关函数在g=0附近将非零。非零部分的宽度取决于滤波器的带宽。

对于x1x2都是周期性的特殊情况,原始答案中关于相移的信息适用。

如果两个信号不是线性相关的话,互相关将无法帮助。例如,频率不同的两个周期信号不是线性相关的。两个在不同时间从宽带随机过程中提取的随机信号也不是线性相关的。两个形状相似但时间索引不同的信号也不是线性相关的——这就像基频不等的情况。

在所有情况下,规范化互相关函数并查看最大值可以告诉您信号是否可能线性相关——如果数字较低,如低于0.1,则我会放心地声明它们不相关。高于此值,我会更仔细地研究,绘制规范化和未规范化的互相关函数并查看结构。周期性互相关意味着两个信号都是周期性的,而在g=0周围明显更高的互相关函数意味着一个信号是另一个信号的滤波版本。


从问题中并不完全清楚,但如果oort想要一种形状相似度量(而不是相位相似度),那么交叉相关性就不是最佳选择:给定一个基本信号s_b和两个测试信号t_1、t_2,它不适合确定哪个测试信号最像基本信号。 - dmckee --- ex-moderator kitten
我正在寻找一个函数,可以给出形状相似度的度量。哪个更适合? - oort
1
@oort:看看我的答案,有几个选择。这些比互相关更复杂,但它们确实直接涉及形状相似性的问题。 - dmckee --- ex-moderator kitten
熵与交叉相关性有什么好处吗? - Léo Léopold Hertz 준영

1

关于信号的具体内容以及“相似度”的衡量标准,您并没有提供太多信息。但是,如果这些信号是同相的(也就是说,您想要逐时比较这两个信号,并且不需要考虑任何时间延迟),那么我建议您尝试使用皮尔逊相关器。它会给出一个数值,如果这两个信号完全相同,则该值为1;如果它们完全不同,则该值为0;如果它们有点类似,则该值介于两者之间。此外,皮尔逊相关器还有一个优点,即它不在意信号是否被放大了不同的倍数(除非其中一个信号是另一个信号的倒数,这种情况下它会给出-1的结果)。

这听起来符合您的需求吗?

http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient


1

动态时间规整是一种方法,可以通过在不同位置加速和减慢时间来匹配信号。


1

一般解决方案:您可以将数据分成直方图,然后使用卡方检验或科尔莫戈洛夫检验。

两者显式旨在估计两个分布表示来自同一基础分布(即:在统计学意义下具有相同的形状)的随机样本的可能性。

我不知道C实现,但ROOT提供了两种的C ++实现:

我相信文档也会指向一些论文。


我认为CERNLIB提供了Fortran77算法,你可以将其链接到C语言。翻译ROOT代码可能更容易。


1

你可以尝试使用快速傅里叶变换(在维基百科上查找FFT,有开源库可用于执行转换)。

FFT将把你的数据从时间域(即1秒、2秒、3秒、4秒处的脉冲...)转换为频率域中的数据(即每秒一个脉冲)。

然后,你可以更轻松地比较频率及其相对强度。这应该是你朝着正确方向迈出的一步。


1
对于某些输入来说,这不是一个坏建议,但实际上你让OP面临同样的问题:如何比较光谱。 - dmckee --- ex-moderator kitten
dmckee:除了傅里叶变换后的信号可以逐点比较而无需移位。顺便说一下,“频谱”这个术语不适用于原始信号,因为这会暗示x轴上有能量(或等效度量)。 - Svante

0

我不懂信号处理,所以这只是一个猜测..:

你的信号是否有效地是一个有序对列表 (x,y),其中 x 是时间,y 是振幅?如果是这样,那么也许你可以丢弃时间坐标 -- 例如:

Signal 1: [(x0,y0), (x1,y1), (x2,y2), (x3,y3), ...]
Signal 2: [(x0,z0), (x1,z1), (x2,z1), (x3,z3), ...]

浪费时间:

Signal 1: [y0, y1, y2, y3, ...]
Signal 2: [z0, z1, z2, z3, ...]

然后您可以将振幅进行比较,例如通过寻找相关性。也许您可以绘制yz的图表:

Comparing: [(y0,z0), (y1,z1), (y2,z2), (y3,z3), ...]

或者计算各种相关系数之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接