Оцінка часових затримок сигналів осцилоскопа за допомогою поперечної кореляції


12

Я записав 2 сигнали від оскопа. Вони виглядають так: введіть тут опис зображення

Я хочу виміряти часову затримку між ними в Матлабі. Кожен сигнал має 2000 зразків із частотою вибірки 2001000.5.

Дані є у файлі csv. Це те, що я маю досі.
Я видалив дані про час із файлу csv, щоб у файлі csv були лише рівні напруги.

x1 = csvread('C://scope1.csv');
x2 = csvread('C://scope2.csv');  
cc = xcorr(x1,x2);
plot(cc);  

Це дає такий результат: введіть тут опис зображення

З того, що я прочитав, мені потрібно взяти перехресну кореляцію цих сигналів, і це повинно дати мені пік, пов'язаний із затримкою у часі. Однак, коли я беру перехресну кореляцію цих сигналів, я отримую пік у 2000 році, який я знаю, що це не правильно. Що мені робити з цими сигналами, перш ніж перетинати їх? Просто шукаю якийсь напрямок.

EDIT: після зняття зміщення постійного струму це результат, який я отримую зараз:
введіть тут опис зображення

Чи є спосіб це очистити, щоб отримати більш певну затримку часу?

EDIT 2: Ось файли:
http://dl.dropbox.com/u/10147354/scope1col.csv
http://dl.dropbox.com/u/10147354/scope2col.csv


Як саме ви робите перехресну кореляцію? Відповідаючи на ваше пряме запитання, вам не потрібно робити нічого для своїх сигналів перед перехресною кореляцією, хоча в деяких випадках фільтрація спочатку допомагає позбутися від шуму, який може спотворити результати.
Джим Клей

1
Будь ласка, опублікуйте використаний код і, що важливіше, графік сигналу перехресної кореляції. Деякі інструменти / бібліотеки ставлять оцінку (lag = 0) у середину графіка; Я не пам'ятаю, чи зробив це Матлаб.
пікенети

@pichenettes: оновлений пост
Нік Сінас

@JimClay: оновлений пост
Нік Сінас

@NickS. Якщо ваші сигнали ідеально вирівняні, ви отримаєте пік в середині вашого куб. Тож пік у 2000 році означає не затримку. Тепер скажемо, що у вас затримка 10 зразків, а це означає, що сигнал2 відключений від сигналу 10 зразків. Це просто перемістить ваш пік у кубічному центрі з 2000 по 2010 рік (або з 1990 року). Отже, ваша затримка у часі відповідає вашому фактичному піковому розташуванню, MINUS 2000.
Spacey

Відповіді:


11

@NickS

Оскільки далеко не певне, що другий сигнал у сюжетах насправді є виключно запізнілою версією першого, слід застосувати інші методи, крім класичної перехресної кореляції. Це тому, що перехресна кореляція (CC) - це лише максимальна оцінка ймовірності, якщо ваш сигнал (и) мають затримки версій один одного. У цьому випадку їх явно немає, нічого не говорити і про нестаціонарність їх.

У цьому випадку я вважаю, що може працювати - це оцінка часу значної енергії сигналів. Зазначається, що "значуще" може чи не може бути дещо суб'єктивним, але я вважаю, що, дивлячись на ваші сигнали зі статистичної точки зору, ми зможемо оцінити "значущі" та піти звідти.

З цією метою я зробив наступне:

КРОК 1: Обчисли сигнальні огинаючі:

Цей крок простий, оскільки обчислюється абсолютне значення виходу Гільберта-Трансформації кожного з ваших сигналів. Є й інші методи обчислення конвертів, але це досить прямо. Цей метод по суті обчислює аналітичну форму вашого сигналу, іншими словами, подання фазора. Коли ви приймаєте абсолютну величину, ви руйнуєте фазу і тільки після енергії.

Крім того, оскільки ми проводимо оцінку затримки часу енергії ваших сигналів, такий підхід є гарантованим.

введіть тут опис зображення

КРОК 2: Зниження шуму з нелінійними медіальними фільтрами, що зберігають краю:

Це важливий крок. Завдання тут - згладити енергетичні оболонки, але без руйнування або згладжування ваших країв і швидкого підйому. Насправді цьому присвячено ціле поле, але для наших цілей тут ми можемо просто використовувати простий у впровадженні нелінійний медіальний фільтр . (Середня фільтрація). Це потужна техніка, оскільки на відміну від середньої фільтрації, медіальна фільтрація не зведе нанівець ваші краї, але в той же час 'згладить' ваш сигнал без істотного погіршення важливих країв, оскільки жоден арифметичний за вашим сигналом не виконується (за умови, що довжина вікна непарна). Для нашого випадку тут я вибрав медіальний фільтр вікна розміром 25 проб:

введіть тут опис зображення

КРОК 3: Час видалення: побудуйте функції оцінки щільності ядра Гаусса:

Що трапилося б, якби ви дивилися на вищезазначений сюжет збоку замість звичайного? Математично кажучи, це означає, що ви отримали, якби спроектували кожен зразок наших позначених сигналів на вісь амплітуди y? Роблячи це, нам вдасться прибрати час, так би мовити, і зможемо вивчати статистику сигналів виключно.

Що інтуїтивно вискакує з фігури вище? Хоча енергія шуму низька, вона має перевагу в тому, що вона є більш «популярною». На відміну від цього, хоча сигнальна оболонка, яка має енергію, енергійна більше, ніж шум, вона фрагментована через поріги. Що робити, якщо ми розглядали популярність як міру енергії? Це те, що ми будемо робити з моєю сирою реалізацією функції щільності ядра (KDE) з ядром Гаусса.

Для цього береться кожен зразок і побудована гауссова функція, використовуючи його значення як середнє значення, а заздалегідь задана пропускна здатність (дисперсія), вибрана a-priori. Налаштування дисперсії вашої гаусса є важливим параметром, але ви можете встановити її на основі статистики шуму на основі вашої програми та типових сигналів. (У мене є лише два файли, які потрібно вимкнути). Якщо потім побудуємо оцінку KDE, отримаємо такий сюжет:

введіть тут опис зображення

Ви можете розглядати KDE як суцільну форму гістограми, так би мовити, і дисперсію як вашу ширину бін. Однак це має перевагу в тому, щоб гарантувати плавний PDF-файл, що ми можемо виконувати перше та друге розрахункове обчислення. Тепер, коли у нас є гауссові KDE, ми можемо побачити, де зразки шуму мають найвищу популярність. Пам'ятайте, що ось ось x представляє проекції наших даних на амплітудний простір. Таким чином, ми можемо бачити, в яких порогових значеннях шум є найбільш "енергійним", і ті кажуть нам, яких порогів слід уникати.

У другому сюжеті береться перша похідна гауссових KDE, і ми вибираємо абсцису першого зразка після першої похідної після піку суміші гауссів, щоб досягти певного значення, близького до нуля. (Або перший нульовий перехід). Ми можемо використовувати цей метод і бути "безпечним", оскільки наш KDE був побудований з гладких гауссів з розумною пропускною здатністю, і було взято першу похідну від цієї плавної та безшумної функції. (Зазвичай первісні похідні можуть бути проблематичними в будь-якому, крім високих SNR сигналах, оскільки вони збільшують шум).

Тоді чорні лінії показують, при яких порогах нам було б розумно «сегментувати» зображення, таким чином, щоб уникнути всієї шумової підлоги. Якщо потім застосувати до наших вихідних сигналів, ми отримаємо наступні графіки, чорними лініями яких вказується початок енергії наших сигналів:

введіть тут опис зображення

δt=241

Я сподіваюся, що це допомогло.


Ого. Дуже дякую. Це все нові методи для мене, які я почну досліджувати. Чи є якимось чином я можу подивитися на код, який ви використовували?
Нік Сінас

Отже, у мене є кроки №1 та №2, зроблені в Matlab, і результати відповідають вашим, але у мене є проблеми з кроком №3. Які функції ви використовували?
Нік Сінас

@NickS. Запитайте, .. і ви отримаєте, знімайте мені електронний лист, і я можу надіслати вам використаний вами код.
Спейси

@Mohammed Чи можете ви, будь ласка, опублікуйте свій код, щоб оцінити затримку часу. Я надіслав вам електронний лист з цього приводу, тому, будь ласка, допоможіть

6

Існує кілька проблем, які роблять це з автокореляцією

  1. Величезний зміщення постійного струму (вже виправлено)
  2. Тимчасове вікно: xcorr () Matlab має прикрою умовою по суті "нульову колодку" сигналу з обох кінців, коли ви ковзаєте часовий лаг. Тобто вікно даних - це функція затримки часу. Це створить трикутну форму для будь-якого нерухомого сигналу (включаючи синусоїди). Кращим варіантом є вибір вікна кореляції, щоб розмір вікна плюс максимум часового відставання вписувався у ваше загальне вікно даних, або нормалізувати перехресну кореляцію за кількістю нерозкладених зразків.
  3. Два сигнали для мене не виглядають особливо кореляційно. Форма дещо схожа, але специфічний інтервал піків і занурень зовсім інший, тому я сумніваюся, що навіть правильна автокореляція дала б багато розуміння тут.

Набагато простішим підходом було б використовувати пороговий детектор для пошуку вихідних точок і просто використовувати різницю між цими точками як затримку.


4

Як зазначено пікенети, в цьому випадку пік в середині виводу вказує на 0 відставання. Зсув піку від середньої точки - це ваш відставання у часі.

EDIT: Мене хвилює, що співвідношення є майже майже ідеальним трикутником. Це вказує на мене, що перехресне співвідношення не нормалізує потужність. Це дає несправедливе упередження меншим відставанням у порівнянні з більшими відставаннями. Я б змінив ваш виклик xcorr на "cc = xcorr (x1, x2, 'unbiased');".

Це, на вашу думку, не є ідеальним рішенням, оскільки результати з великим відставанням зараз нестабільніші, ніж результати з низьким відставанням, оскільки вони базуються на меншій кількості даних. Великий пік на кінцівках може бути хитрим з тієї ж причини, що ви можете отримати 100% голови і відсутність хвостів лише на кілька монетних кидок, тоді як на багатьох кидках це вкрай малоймовірно.


Значить, сигнали не затримуються?
Нік Сінас

Я не впевнений - де пік? Я бачу, що це близько середини, але не ясно, що насправді знаходиться посередині. Також є питання нормалізації потужності, до якого я звернуся в редакції своєї відповіді.
Джим Клей

Параметр "неупереджений", безумовно, робить його краще. більше того, що я очікував. Я буду продовжувати вивчати це. Дякую.
Нік Сінас

@JimClay Можливо, Нік С співвідносить огинаючі його сигнали, а не фактичні сигнали (Нік це правда?). Це дало б (приблизно) цю трикутну форму, яку я собі уявляю.
Спейси

2
@NickS. Коментар Мухаммеда змусив мене подивитися і зрозуміти, що у вас величезне зміщення постійного струму, яке псує ваші результати. Відніміть середнє з обох ваших сигналів, а потім запустіть на них xcorr. Я спробував би це спочатку без "неупередженого" варіанту.
Джим Клей

4

Як зазначали інші, і, здається, ви зрозуміли, виходячи з останньої редакції питання, не здається, що перехресне співвідношення дасть вам хорошу оцінку затримки часу для показаних наборів даних. Кореляція вимірює подібність за формою між двома часовими рядами, ковзаючи один за іншим за проміжок часу та обчислюючи внутрішній виріб між двома серіями на кожному відставанні. Результат матиме велику величину, коли два ряди якісно схожі, або вони "співвідносяться" між собою. Це схоже на те, як внутрішній добуток двох векторів найбільший, коли два вектори спрямовані в одному напрямку.

Проблема з показаними вами даними полягає в тому, що (принаймні, для фрагментів, які ми можемо бачити), схоже, за формою схоже не дуже. Не можна затримувати, що ви можете застосувати один із сигналів, щоб він був схожим на інший, саме це ви робите, обчислюючи їх перехресну кореляцію.

Однак є випадки, коли крос-кореляція корисна. Скажіть, що ваш другий сигнал був справді зміненою у часі версією оригіналу, навіть із додаванням додаткового шуму:

a = csvread('scope1col.csv');
a = a - mean(a);               % to remove DC offset
b = a(200:end) + sqrt(0.05)*randn(1801,1);
figure; subplot(211); plot(a); subplot(212); plot(b)

введіть тут опис зображення

Зараз не відразу зрозуміло, що два сигнали пов'язані затримкою в часі. Однак якщо взяти перехресну кореляцію, ми отримаємо:

[c,lags] = xcorr(a,b);
igure; plot(lags,c); grid on; xlabel('Lag'); ylabel('Cross-correlation');

введіть тут опис зображення

що показує пік при правильному відставанні 200 проб. Кореляція може бути корисним інструментом для визначення затримки в часі, коли вона застосовується до наборів даних, що містять правильний тип подібності.


Будь-які ідеї, що я ще міг би зробити? Можливо інша техніка, крім перехресної кореляції, чи, можливо, якийсь тип фільтра? Дякую.
Нік Сінас

@NickS. Я теж переглянув це, і вони не затримували копії один одного. Якщо говорити, чи хочете ви оцінити затримку енергії ? Я думаю, що в цьому випадку було б більше сенсу, VS затримка сигналів . Якщо ви розповісте більше про базовий канал / експеримент, який ви виконуєте, ми можемо розповісти вам більше про можливі шляхи.
Спейси

@Mohammad Дякую Основним каналом є сталь. Будь-яке уявлення про те, як оцінити затримку енергії?
Нік Сінас

@Mohammad, ти думаєш, спотворення сигналів може бути певним типом реверберації, яку можна очистити за допомогою фільтрації?
Нік Сінас

@NickS. Там можуть бути якісь хитрощі очищення реверберації (я не знаю, як це можна було б виконати), але я зібрав разом щось просте, що стане оцінкою енергії, якщо ви хочете подивитися.
Спейси

0

На підставі пропозиції Мухаммада я спробував скласти сценарій Matlab. Однак я не в змозі зробити висновок, якщо він побудує розподіл Гаусса на основі дисперсій, а потім зробить оцінку KDE або він виконає оцінку KDE з припущенням Гаусса.

Крім того, важко зробити висновок, як він переводить час зміщення KDE у часову область. Ось моя спроба до цього. Будь-який користувач, зацікавлений у використанні сценарію, може безкоштовно та оновити покращену версію, якщо це можливо.

%% Initialising data

Ws1 = data1;
Ws2 = data2;
mWs1 = nanmean(Ws1);
mWs2 = nanmean(Ws2);
sdWs1 = nanstd(Ws1);
sdWs2 = nanstd(Ws2);

%% Computing the signal envelopes
Ws1d = Ws1 - mWs1;
Ws2d = Ws2 - mWs2;
h1 = abs(hilbert(Ws1d));
h2 = abs(hilbert(Ws2d));
figure();
subplot(211)
plot([Ws1d, h1])
subplot(212)
plot([Ws2d, h2])

%% Denoise the signal with edge preserving nonlinear medial filtering
w = 25;
mf1 = medfilt1(h1, w);
mf2 = medfilt1(h2, w);
figure();
subplot(211)
plot(mf1)
subplot(212)
plot(mf2)

<%% Remove time: construct the gaussian kernel density estimation functions>
% Using the kde from Matlab central directly on the filtered data
data1 = mf1;
[bw1, den1, xmesh1, cdf1] = kde(data1, 2^14);
der1 = diff(den1);
data2 = mf2;
[bw2, den2, xmesh2, cdf2] = kde(data2, 2^14);
der2 = diff(den2);
figure();
plot([der1, der2]);
legend('Sig1', 'Sig2')

% the other method as explained in Muhammad's post
for i = 1:length(mf1)
gf1(:,i) = mf1(i) + sdWs1*randn(1000,1);
gf2(:,i) = mf2(i) + sdWs2*randn(1000,1);
end
[bwM1, denM1, xmeshM1, cdfM1] = kde(gf1(:,1), 2.^11);
dd1 = diff(denM1);
[bwM2, denM2, xmeshM2, cdfM2] = kde(gf2(:,1), 2.^11);
dd2 = diff(denM2);
figure();
plot([dd1, dd2]);
legend('Sig1', 'Sig2')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.