Stima del ritardo dei segnali dell'oscilloscopio mediante correlazione incrociata


12

Ho registrato 2 segnali da un oscope. Sembrano così: inserisci qui la descrizione dell'immagine

Voglio misurare il ritardo tra loro in Matlab. Ogni segnale ha 2000 campioni con una frequenza di campionamento di 2001000.5.

I dati sono in un file CSV. Questo è quello che ho finora.
Ho cancellato i dati temporali dal file CSV in modo che solo i livelli di tensione siano nel file CSV.

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

Questo dà questo risultato: inserisci qui la descrizione dell'immagine

Da quello che ho letto devo prendere la correlazione incrociata di questi segnali e questo dovrebbe darmi un picco relativo al ritardo. Tuttavia quando prendo la correlazione incrociata di questi segnali ottengo un picco a 2000 che so non è corretto. Cosa devo fare a questi segnali prima di metterli in correlazione incrociata? Sto solo cercando una direzione.

EDIT: dopo aver rimosso l'offset DC questo è il risultato che sto ottenendo ora:
inserisci qui la descrizione dell'immagine

C'è un modo per ripulirlo per ottenere un ritardo più definito?

EDIT 2: Ecco i file:
http://dl.dropbox.com/u/10147354/scope1col.csv
http://dl.dropbox.com/u/10147354/scope2col.csv


Come sta esattamente la correlazione incrociata? In risposta alla tua domanda diretta, non dovresti aver bisogno di fare nulla per i tuoi segnali prima della correlazione incrociata, anche se in alcuni casi il filtro aiuta a sbarazzarti del rumore che può distorcere i risultati.
Jim Clay,

1
Pubblica il codice che hai usato e, soprattutto, un diagramma del segnale di correlazione incrociata. Alcuni strumenti / librerie mettono il punteggio (lag = 0) al centro del grafico; Non ricordo se Matlab lo fa.
Pichenettes,

@pichenettes: post aggiornato
Nick Sinas,

@JimClay: post aggiornato
Nick Sinas,

@NickS. Se i tuoi segnali sono perfettamente allineati, otterrai un picco nel mezzo del tuo diagramma cc. Quindi il picco a 2000 significa nessun ritardo. Ora diciamo che hai un ritardo di 10 campioni, il che significa che il segnale2 è a 10 campioni dal segnale1. Questo sposterà il tuo picco nella cc dal 2000 al 2010 (o 1990). Quindi il tuo ritardo corrisponde alla tua attuale posizione di picco, MINUS 2000.
Spacey,

Risposte:


11

@NickS

Poiché è tutt'altro che certo che il secondo segnale nei grafici sia in realtà una versione solo ritardata della prima, si devono tentare altri metodi oltre alla classica correlazione incrociata. Questo perché la correlazione incrociata (CC) è semplicemente uno stimatore della massima verosimiglianza se i segnali sono versioni ritardate l'una dell'altra. In questo caso, chiaramente non lo sono, per non dire nulla della non stazionarietà di entrambi.

In questo caso, credo che ciò che potrebbe funzionare sia una stima temporale dell'energia significativa dei segnali. Certo, "significativo" può o non può essere in qualche modo soggettivo, ma credo che guardando i tuoi segnali da un punto di vista statistico, saremo in grado di quantificare "significativo" e andare da lì.

A tal fine, ho fatto quanto segue:

PASSAGGIO 1: calcolare gli inviluppi di segnale:

Questo passaggio è semplice, poiché viene calcolato il valore assoluto dell'output della Trasformazione di Hilbert di ciascuno dei tuoi segnali. Esistono altri metodi per calcolare le buste, ma è piuttosto semplice. Questo metodo calcola essenzialmente la forma analitica del segnale, in altre parole, la rappresentazione del fasore. Quando prendi il valore assoluto, stai distruggendo la fase e solo dopo l'energia.

Inoltre, poiché stiamo perseguendo una stima del ritardo nell'energia dei tuoi segnali, questo approccio è garantito.

inserisci qui la descrizione dell'immagine

PASSAGGIO 2: antirumore con filtri mediali non lineari che preservano i bordi:

Questo è un passo importante. L'obiettivo qui è di appianare le tue buste energetiche, ma senza distruzione o levigare i bordi e i tempi di salita rapidi. In realtà c'è un intero campo dedicato a questo, ma per i nostri scopi qui, possiamo semplicemente usare un filtro mediale non lineare facile da implementare . (Filtro mediano). Questa è una tecnica potente perché, a differenza del filtro medio , il filtro mediale non annullerà i tuoi bordi, ma allo stesso tempo "livellerà" il tuo segnale senza un significativo degrado dei bordi importanti, poiché in nessun momento viene eseguita alcuna aritmetica sul tuo segnale (a condizione che la lunghezza della finestra sia dispari). Per il nostro caso qui, ho selezionato un filtro mediale di dimensioni della finestra di 25 campioni:

inserisci qui la descrizione dell'immagine

PASSAGGIO 3: rimuovere il tempo: costruire funzioni di stima della densità del kernel gaussiano:

Cosa accadrebbe se guardassi lateralmente la trama sopra invece che nel modo normale? In termini matematici, ciò significa che cosa otterresti se proiettassi ogni campione dei nostri segnali negati sull'asse dell'ampiezza y? In questo modo riusciremo a rimuovere il tempo per così dire, e saremo in grado di studiare solo le statistiche del segnale.

Intuitivamente cosa emerge dalla figura sopra? Mentre l'energia del rumore è bassa, ha il vantaggio di essere più "popolare". Al contrario, mentre l'inviluppo del segnale che ha energia è più energico del rumore, è frammentato attraverso le soglie. E se considerassimo la "popolarità" come una misura di energia? Questo è ciò che faremo con (il mio greggio) implementazione di una funzione di densità del kernel , (KDE), con un kernel gaussiano.

Per fare ciò, viene preso ogni campione e viene costruita una funzione gaussiana usando il suo valore come media, e una larghezza di banda preimpostata (varianza) selezionata a priori. L'impostazione della varianza del gaussiano è un parametro importante, ma è possibile impostarlo in base alle statistiche del rumore basate sull'applicazione e sui segnali tipici. (Ho solo i tuoi 2 file per andare avanti). Se poi costruiamo la stima di KDE, otteniamo il seguente diagramma:

inserisci qui la descrizione dell'immagine

Puoi pensare a KDE come una forma continua di un istogramma, per così dire, e alla varianza come larghezza del cestino. Tuttavia ha il vantaggio di garantire un PDF fluido su cui possiamo quindi eseguire il primo e il secondo calcolo derivato. Ora che abbiamo i KDE gaussiani, possiamo vedere dove i campioni di rumore raggiungono il picco di popolarità. Ricorda che l'asse x qui rappresenta le proiezioni dei nostri dati sullo spazio di ampiezza. Quindi, possiamo vedere in quali soglie il rumore è il più "energetico" e quelli ci dicono quali soglie evitare.

Nel secondo diagramma, viene presa la prima derivata dei KDE gaussiani e scegliamo l'ascissa del primo campione dopo la prima derivata dopo il picco della miscela di gaussiani per raggiungere un certo valore vicino allo zero. (O primo zero-crossing). Possiamo usare questo metodo ed essere "sicuri" perché il nostro KDE è stato costruito con gaussiani lisci con una larghezza di banda ragionevole, ed è stata presa la prima derivata di questa funzione fluida e senza rumore. (Tipicamente i primi derivati ​​possono essere problematici in qualsiasi cosa tranne segnali SNR elevati poiché ingrandiscono il rumore).

Le linee nere mostrano quindi a quali soglie saremmo saggi per "segmentare" l'immagine, in modo da evitare l'intero rumore di fondo. Se poi applichiamo ai nostri segnali originali, otteniamo i seguenti grafici, con le linee nere che indicano l'inizio dell'energia dei nostri segnali:

inserisci qui la descrizione dell'immagine

Questo produce quindi un campioni.δt=241

Spero che questo abbia aiutato.


Wow. Grazie mille. Queste sono tutte nuove tecniche per me che inizierò a ricercare. C'è un modo per dare un'occhiata al codice matlab che hai usato?
Nick Sinas,

Quindi ho fatto i passaggi n. 1 e n. 2 in Matlab e i miei risultati corrispondono ai tuoi, ma sto riscontrando problemi con il passaggio n. 3. Quali funzioni hai usato?
Nick Sinas,

@NickS. Chiedi, .. e riceverai, sparami una e-mail e posso inviarti il ​​codice che ho usato.
Spacey,

@Mohammed Potresti pubblicare il tuo codice per stimare il ritardo. Ti ho inviato un'e-mail in merito a questa questione, quindi ti preghiamo di aiutare

6

Ci sono alcuni problemi nel fare questo con l'autocorrelazione

  1. Enorme offset CC (già riparato)
  2. Finestra temporale: xcorr () di Matlab ha la fastidiosa convenzione di essenzialmente "azzerare" il segnale ad entrambe le estremità mentre si fa scorrere il ritardo. Cioè la finestra dei dati è una funzione del ritardo. Ciò creerà una forma triangolare per qualsiasi segnale stazionario (comprese le onde sinusoidali). Le scelte migliori sono scegliere una finestra di correlazione in modo che le dimensioni della finestra più il ritardo massimo si adattino alla finestra dei dati totali o normalizzare la correlazione incrociata per il numero di campioni non riempiti.
  3. I due segnali non mi sembrano particolarmente correlati. La forma è in qualche modo simile ma la spaziatura specifica di picchi e avvallamenti è piuttosto diversa, quindi dubito che anche una corretta auto-correlazione produrrebbe molte intuizioni qui.

Un approccio molto più semplice sarebbe usare un rilevatore di soglia per trovare i punti di partenza e semplicemente usare la differenza tra questi punti come ritardo.


4

Come indicato da Pichenettes, in questo caso un picco al centro dell'uscita indica 0 ritardo. L'offset del picco dal punto centrale è il ritardo.

EDIT: Mi preoccupa che la correlazione sia così quasi un triangolo perfetto. Ciò mi indica che la correlazione incrociata non sta eseguendo la normalizzazione di potenza. Ciò dà una propensione ingiusta a ritardi minori rispetto a ritardi maggiori. Modificherei la tua chiamata xcorr a "cc = xcorr (x1, x2, 'imparziale');".

Questa, non è una soluzione perfetta, perché i risultati a grande ritardo sono ora più instabili rispetto ai risultati a basso ritardo perché si basano su meno dati. Un grande picco alle estremità può essere falso per lo stesso motivo per cui puoi ottenere il 100% di teste e nessuna coda in pochi lanci di monete, mentre è estremamente improbabile che accada su molti lanci.


Vuoi dire che i segnali non sono ritardati?
Nick Sinas,

Non sono sicuro: dov'è il picco? Vedo che è vicino al centro, ma non è chiaro che sia effettivamente nel mezzo. Inoltre, c'è un problema di normalizzazione dell'alimentazione che affronterò in una modifica della mia risposta.
Jim Clay,

Il parametro 'imparziale' lo rende decisamente migliore. più di quello che mi aspetterei. Continuerò a esaminare questo. Grazie.
Nick Sinas,

@JimClay Forse Nick S, sta correlando gli inviluppi dei suoi segnali e non i segnali effettivi, (Nick è vero?). Ciò produrrebbe (approssimativamente) questa forma triangolare che immagino.
Spacey,

2
@NickS. Il commento di Mohammad mi ha fatto guardare e rendermi conto che hai un enorme offset DC che sta rovinando i tuoi risultati. Sottrai la media da entrambi i tuoi segnali e poi esegui xcorr su di essi. Lo proverei prima senza l'opzione "imparziale".
Jim Clay,

4

Come hanno sottolineato gli altri, e sembra che tu ti sia reso conto in base alla tua ultima modifica alla domanda, non sembra che la correlazione incrociata ti fornirà una buona stima del ritardo per i set di dati mostrati. La correlazione misura la somiglianza nella forma tra due serie storiche facendo scorrere l'una sull'altra per una serie di ritardi e calcolando un prodotto interno tra le due serie ad ogni ritardo. Il risultato avrà una grande importanza quando le due serie sono qualitativamente simili o "correlate" tra loro. Questo è simile al modo in cui un prodotto interno di due vettori è maggiore quando i due vettori sono puntati nella stessa direzione.

Il problema con i dati che hai mostrato è che (almeno per i frammenti che possiamo vedere) non sembra esserci molta somiglianza nella forma. Non c'è alcun ritardo che puoi applicare a uno dei segnali per farlo sembrare come l'altro, che è esattamente quello che stai facendo calcolando la loro correlazione incrociata.

Ci sono casi in cui la correlazione incrociata è utile, tuttavia. Supponi che il tuo secondo segnale fosse in realtà una versione spostata nel tempo dell'originale, anche con l'aggiunta di qualche rumore aggiuntivo:

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)

inserisci qui la descrizione dell'immagine

Ora non è immediatamente chiaro che i due segnali sono correlati da un ritardo. Tuttavia, se prendiamo la correlazione incrociata, otteniamo:

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

inserisci qui la descrizione dell'immagine

che mostra un picco al ritardo corretto di 200 campioni. La correlazione può essere uno strumento utile per determinare il ritardo, se applicato a set di dati che contengono il giusto tipo di somiglianza.


Qualche idea su cos'altro potrei fare? Forse un'altra tecnica diversa dalla correlazione incrociata o forse un tipo di filtro? Grazie.
Nick Sinas,

@NickS. L'ho anche guardato e non sono copie in ritardo l'una dell'altra. Detto questo, vuoi stimare il ritardo dell'energia ? Penso che avrebbe più senso in questo caso, ritardo VS dei segnali . Se ci dici di più sul canale / esperimento sottostante che stai eseguendo, possiamo dirti di più sui possibili percorsi.
Spacey,

@Mohammad Grazie. Il canale sottostante è l'acciaio. Qualche idea su come stimare il ritardo dell'energia?
Nick Sinas,

@Mohammad pensi che la distorsione dei segnali potrebbe essere un qualche tipo di riverbero che potrebbe essere pulito con il filtraggio?
Nick Sinas,

@NickS. Potrebbero esserci alcuni trucchi per la pulizia del riverbero (non sono consapevole di come si realizzerebbero), ma ho messo insieme qualcosa di semplice che sarà uno stimatore di energia se vuoi dare un'occhiata.
Spacey,

0

Sulla base del suggerimento di Maometto, ho cercato di creare una sceneggiatura di Matlab. Tuttavia, non sono in grado di dedurre se costruisce una distribuzione gaussiana sulla base delle varianze e quindi prende una stima KDE o esegue una stima KDE con ipotesi gaussiana.

Inoltre, è difficile dedurre come traduca il tempo di offset di KDE nel dominio del tempo. Ecco il mio tentativo di farlo. Qualsiasi utente interessato all'utilizzo dello script è libero e se possibile aggiorna la versione migliorata.

%% 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')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.