Этот пример показывает, как использовать взаимную корреляцию, чтобы выровнять сигналы. В наиболее общем случае сигналы имеют различные длины, и синхронизировать их правильно, необходимо учесть длины и порядок, в котором вы вводите аргументы к xcorr
.
Рассмотрите два сигнала, идентичные за исключением количества окружающих нулей и для того, что один из них изолирует другой.
sz = 30;
sg = randn(1,randi(8)+3);
s1 = [zeros(1,randi(sz)-1) sg zeros(1,randi(sz)-1)];
s2 = [zeros(1,randi(sz)-1) sg zeros(1,randi(sz)-1)];
mx = max(numel(s1),numel(s2));
subplot(2,1,1)
stem(s1)
xlim([0 mx+1])
subplot(2,1,2)
stem(s2,'*')
xlim([0 mx+1])
Определите, какой из двух сигналов более длинен, чем другой в смысле наличия большего количества элементов, быть ими нули или нет.
if numel(s1) > numel(s2) slong = s1; sshort = s2; else slong = s2; sshort = s1; end
Вычислите взаимную корреляцию двух сигналов. Запустите xcorr
с более длинным сигналом так же первый аргумент и более коротким сигналом как второй аргумент. Постройте результат.
[acor,lag] = xcorr(slong,sshort); [acormax,I] = max(abs(acor)); lagDiff = lag(I)
lagDiff = 15
figure stem(lag,acor) hold on plot(lagDiff,acormax,'*') hold off
Выровняйте сигналы. Думайте об отстающем сигнале, как являющемся "более длинным", чем другой, в том смысле, что необходимо "ожидать дольше", чтобы обнаружить его.
Если lagDiff
положителен, "сократите" длинный сигнал путем рассмотрения его элементов от lagDiff
+1 в конец.
Если lagDiff
отрицателен, "удлините" короткий сигнал путем рассмотрения его элементов от -lagDiff
+1 в конец.
Необходимо добавить 1 к различию в задержке, потому что MATLAB® использует индексацию на основе одну.
if lagDiff > 0 sorig = sshort; salign = slong(lagDiff+1:end); else sorig = slong; salign = sshort(-lagDiff+1:end); end
Постройте выровненные сигналы.
subplot(2,1,1)
stem(sorig)
xlim([0 mx+1])
subplot(2,1,2)
stem(salign,'*')
xlim([0 mx+1])
Метод работает, потому что операция взаимной корреляции антисимметрична и потому что xcorr
имеет дело с сигналами различных длин путем добавления нулей в конце более короткого сигнала. Эта интерпретация позволяет вам выровнять сигналы легко с помощью оператора MATLAB® end
, не имея необходимость заполнять их вручную.
Можно также выровнять сигналы одним махом путем вызова функции alignsignals
.
[x1,x2] = alignsignals(s1,s2);
subplot(2,1,1)
stem(x1)
xlim([0 mx+1])
subplot(2,1,2)
stem(x2,'*')
xlim([0 mx+1])