2013-03-12 4 views
2

У меня есть два сигнала, назовем их «a» и «b». Они оба почти идентичные сигналы (записаны с одного и того же ввода и содержат одну и ту же информацию), однако, поскольку я записал их на двух разных «b», время сдвинуто на неизвестную величину. Очевидно, что в каждом случае есть случайный шум.Найти разницу между двумя сигналами

В настоящее время я использую кросс-корреляцию для вычисления сдвига во времени, однако, я все еще получаю неправильные результаты.

Вот код, я использую, чтобы вычислить сдвиг во времени:

function [ diff ] = FindDiff(signal1, signal2) 
%FINDDIFF Finds the difference between two signals of equal frequency 
%after an appropritate time shift is applied 
% Calculates the time shift between two signals of equal frequency 
% using cross correlation, shifts the second signal and subtracts the 
% shifted signal from the first signal. This difference is returned. 
length = size(signal1); 

if (length ~= size(signal2)) 
    error('Vectors must be equal size'); 
end 

t = 1:length; 
tx = (-length+1):length; 
x = xcorr(signal1,signal2); 
[mx,ix] = max(x); 
lag = abs(tx(ix)); 
shifted_signal2 = timeshift(signal2,lag); 
diff = signal1 - shifted_signal2; 

end 

function [ shifted ] = timeshift(input_signal, shift_amount) 
input_size = size(input_signal); 
shifted = (1:input_size)'; 
for i = 1:input_size 
    if i <= shift_amount 
     shifted(i) = 0; 
    else 
     shifted(i) = input_signal(i-shift_amount); 
    end 
end 

end 

plot(FindDiff(a,b)); 

Однако результат из функции периода волны, а не случайный шум, так что задержка должна еще быть выключен. Я бы опубликовал изображение сюжета, но imgur в настоящее время не сотрудничает.

Есть ли более точный способ расчета отставания, кроме взаимной корреляции, или есть способ улучшить результаты от взаимной корреляции?

+0

Фактически, если вы сравниваете два сигнала одного и того же размера, то xcorr не будет работать, потому что он начнется с сравнения сигнала1 с только частью сигнала2, который будет дополнен нулями (или может быть дополнен последним значением, но это по-прежнему не является хорошим способом сравнения двух сигналов). Вероятно, вам следует сравнить сегмент сигнала с более крупным сигналом, а затем определить, где вспомогательный сигнал лежит в большем сигнале. Кроме того, вы переписываете «длину» встроенную функцию и без необходимости формируете t и tx. – Justin

+0

@jucestain Я не думаю, что это правильно. Единственное, что мы рассматриваем с помощью кросс-корреляции, это его макс, поэтому эти нули в начале не будут иметь эффекта. И я знаю, что эти функции прекрасно работают, когда сигнал используется против самого себя. –

+0

Вы пробовали смотреть на всю корреляцию, а не на ее максимум? Если вы имеете дело с реальными шумовыми сигналами, существует вероятность того, что ваш сдвиг в реальном времени не даст максимальной корреляции. –

ответ

2

В настоящее время существуют две функции в Matlab:

один называется finddelay

и другой названный alignsignals, который может делать то, что вы хотите, я считаю.

+0

Учитывая новую функцию - теперь это должно рассматриваться как наилучшее решение этой проблемы. –

0

corr находит dot продукт между векторами (v1, v2). Если он плохо работает с вашим сигналом, я попытаюсь свести к минимуму сумму квадратов разностей (т. Е. abs(v1 - v2)).

signal = sin(1:100); 
signal1 = [zeros(1, 10) signal]; 
signal2 = [signal zeros(1, 10)]; 

for i = 1:length(signal1) 
    signal1shifted = [signal1 zeros(1, i)]; 
    signal2shifted = [zeros(1, i) signal2]; 
    d2(i) = sum((signal1shifted - signal2shifted).^2); 
end 

[fval lag2] = min(d2); 

lag2 

Это вычислительно хуже, чем кросс-расчет, который можно ускорить с помощью БПФ. Насколько я знаю, вы не можете сделать это с эвклидовым расстоянием.

UPD. Исправлено неправильное представление о взаимной корреляции с периодическими сигналами

5

Cross-correlation обычно является самым простым способом определения временной задержки между двумя сигналами. Положение пикового значения указывает смещение по времени, при котором два сигнала являются наиболее похожими.

%// Normalize signals to zero mean and unit variance 
s1 = (signal1 - mean(signal1))/std(signal1); 
s2 = (signal2 - mean(signal2))/std(signal2); 

%// Compute time lag between signals 
c = xcorr(s1, s2);      %// Cross correlation 
lag = mod(find(c == max(c)), length(s2)) %// Find the position of the peak 

Следует отметить, что оба сигнала должен быть нормализован первым на тот же уровень энергии, так что результаты не смещены.

Кстати, не используйте diff как имя для переменной. В MATLAB с таким же именем уже есть built-in function.

+0

Как я могу узнать из запаздывания, если сигнал2 мог или не мог быть найден в сигнале1? –

+1

@ZoltanSzabo Это пик перекрестной корреляции, а не «отставание», что помогает вам определить, о чем вы спрашиваете. Пик указывает, где два сигнала являются наиболее похожими, или, другими словами, каков временной сдвиг между сигналом и другим подобным сигналом. Отсутствие такого пика означает, что сигналы неодинаковы. –

+0

Спасибо, я мог получить пик с максимальным индексом корреляции. Вы знаете, как я могу получить некоторый процент, чтобы показать, насколько похожи эти два сигнала? Например, у меня есть два сигнала, которые почти похожи. Длина первого сигнала составляет около 130 кбайт, однако алгоритм нашел пик около 125 кбайт, поэтому кажется, что он нашел совпадение, но я знаю, что сигналы на самом деле не похожи. Поэтому мне нужен какой-то процент. –

0

Вы можете попробовать согласованной фильтрации в частотной области

function [corr_output] = pc_corr_processor (target_signal, ref_signal) 
L = length(ref_signal); 
N = length(target_signal); 

matched_filter = flipud(ref_signal')'; 
matched_filter_Res = fft(matched_filter,N); 
corr_fft = matched_filter_Res.*fft(target_signal); 
corr_out = abs(ifft(corr_fft)); 

Пик согласованного фильтра максимального показателя corr_out выше, должны дать вам сумму лаг.

Смежные вопросы