当波形存在时间偏移时,动态时间规整(Dynamic Time Warping, DTW)是比较合适的方法,因为它能够处理两个序列在时间轴上的不对齐问题。DTW通过找到最优的路径来对齐两个波形,从而计算它们的相似度,即使存在时间偏移或长度差异也能有效比较。
下面是一个完整的JavaScript实现,专门用于处理有时间偏移的波形比较:
// 归一化函数:消除振幅差异影响
function normalize(arr) {
const min = Math.min(...arr);
const max = Math.max(...arr);
const range = max - min;
// 处理所有值相同的情况
if (range === 0) {
return arr.map(() => 0);
}
return arr.map(x => (x - min) / range);
}
// 动态时间规整(DTW)算法实现
function dtwDistance(seriesA, seriesB) {
const m = seriesA.length;
const n = seriesB.length;
// 创建DTW矩阵并初始化
const dtwMatrix = Array.from({ length: m + 1 }, () =>
Array(n + 1).fill(Infinity)
);
dtwMatrix[0][0] = 0;
// 填充DTW矩阵
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 计算当前点的距离(欧氏距离的平方)
const cost = Math.pow(seriesA[i - 1] - seriesB[j - 1], 2);
// 取三个方向的最小值并加上当前成本
dtwMatrix[i][j] = cost + Math.min(
dtwMatrix[i - 1][j], // 上方
dtwMatrix[i][j - 1], // 左方
dtwMatrix[i - 1][j - 1] // 对角线
);
}
}
// 返回归一化后的距离(除以总长度,使结果不受序列长度影响)
return dtwMatrix[m][n] / (m + n);
}
// 比较两个波形的整体形状(处理时间偏移)
function compareWaveformsWithOffset(waveA, waveB, threshold = 0.001) {
// 先归一化,消除振幅差异
const normA = normalize(waveA);
const normB = normalize(waveB);
// 计算DTW距离
const distance = dtwDistance(normA, normB);
// 根据阈值判断形状是否相似
return {
distance: distance,
isSimilar: distance < threshold,
threshold: threshold
};
}
// 示例用法
function test() {
// 创建两个相似但有时间偏移的波形
const wave1 = [0, 1, 2.2, 3.5, 4.2, 3.7, 2, 1, 0, 1,6, 1, 0];
const wave2 = [0, 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 1, 0]; // 比wave1多一个初始0
// 比较波形
const result = compareWaveformsWithOffset(wave1, wave2);
console.log(`DTW距离: ${result.distance.toFixed(4)}`);
console.log(`阈值: ${result.threshold}`);
console.log(`波形形状${result.isSimilar ? '相似' : '不相似'}`);
}
// 运行测试
test();
算法说明
这个实现特别针对有时间偏移的波形比较做了优化:
- 归一化处理:首先将波形归一化到[0,1]范围,消除振幅差异对比较结果的影响,只关注形状。
DTW核心算法:
- 创建一个矩阵来存储两个序列之间的距离
- 每个点的距离计算考虑了上方、左方和对角线三个方向的最小值
- 这种设计允许波形在时间轴上"弯曲"对齐,有效处理时间偏移
结果解释:
- DTW距离越小,两个波形的形状越相似
- 通过设置合适的阈值(threshold)来判断是否"形状一致"
- 阈值需要根据实际数据特点调整,一般建议在0.01-0.1之间
使用建议
- 对于存在明显时间偏移的波形,这种方法比简单的欧氏距离或相关系数更可靠
- 如果波形长度差异很大,可以先进行重采样使长度接近,再应用DTW
- 对于实时性要求高的场景,可以考虑优化DTW算法(如限制搜索窗口)
你可以根据实际波形数据的特点,调整threshold参数来获得最佳的比较效果。
最后一次更新于2025-09-05


