Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the difference between two signals

I have two signals, let's call them 'a' and 'b'. They are both nearly identical signals (recorded from the same input and contain the same information) however, because I recorded them at two different 'b' is time shifted by an unknown amount. Obviously, there is random noise in each.

Currently, I am using cross correlation to compute the time shift, however, I am still getting improper results.

Here is the code I am using to calculate the time shift:

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));

However the result from the function is a period wave, rather than random noise, so the lag must still be off. I would post an image of the plot, but imgur is currently not cooperating.

Is there a more accurate way to calculate lag other than cross correlation, or is there a way to improve the results from cross correlation?

like image 362
Kyle Avatar asked Dec 21 '22 08:12

Kyle


1 Answers

Cross-correlation is usually the simplest way to determine the time lag between two signals. The position of peak value indicates the time offset at which the two signals are the most similar.

%// 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

Note that the two signals have to be normalized first to the same energy level, so that the results are not biased.

By the way, don't use diff as a name for a variable. There's already a built-in function in MATLAB with the same name.

like image 116
Eitan T Avatar answered Jan 05 '23 22:01

Eitan T