2015-08-27 41 views
7

sto soffrendo nel trovare un buon modo per confrontare (misurare) la somiglianza tra due segnali diversi. Non voglio trovare il tempo di ritardo di un segnale a un altro, ma voglio vedere come sono simili tra loro. Ad esempio, ho i seguenti due segnali, diciamo s1 ans s2. i due segnali sembrano molto simili, tuttavia in un segnale c'è un salto improvviso che determina che la seconda parte del segnale (anche quella dominante) ha uno scostamento rispetto alla prima parte.misura due somiglianza del segnale (vettoriale) diverso

enter image description here

Quando uso il cross-covarianza così come cross-correlazione, mi dà un risultato molto povera, e cioè:

xcov(s1, s2, 0, 'coeff') ----> 0.2153 

Tuttavia guardando i due segnali, possiamo vedere che sono molto simili. Infatti se prendere la croce-covarianza dei due segnali solo dal campione (50-> alla fine del segnale), il risultato è molto buono:

xcov(s1(50:280), s2(50:280), 0, 'coeff') ----> 0.9666 

quindi credo che il problema è dovuto al grande salto attorno al campione 25 (nel segnale rosso).

Le mie domande sono:

  • come superare il problema di cui sopra?
  • La cross-covarianza (correlazione) è un buon modo per misurare la somiglianza tra due segnali?
  • C'è un altro modo per farlo?

Grazie mille. Apprezzo davvero ogni tuo aiuto!

+4

Vuoi prendere in considerazione la misurazione della somiglianza tra il * gradient * dei segnali? – Shai

+2

È possibile utilizzare un filtro media mobile per calcolare un valore medio su un intervallo breve, quindi sottrarlo dal segnale en, quindi verificare le similitudini? – Adriaan

+1

Se consideri che jump è un outlier, puoi provare metodi di rimozione di valori anomali come RANSAC (solo un pensiero ...) –

risposta

-1

È possibile calcolare l'area tra queste due curve. Le curve sono simili se l'area è piccola, non così simile se l'area è grande.

Modifica: per gestire le curve "salto" e casi di offset CC, l'area tra le due curve deve essere calcolata dopo aver eseguito l'allineamento ICP (Iterative Closest Point).

+0

Grazie @ Hesham Eraqui. Io non la penso così, prima di tutto, il salto causerebbe una seria differenza nel risultato. E anche a causa del rumore, o offset DC, l'area tra due curve può essere molto più grande di quanto supponga di essere. – bienle

+0

@bienle Ho modificato la mia risposta di conseguenza. –

3

Probabilmente dovresti esaminare anche i robusti coefficienti di correlazione. C'è un po 'di letteratura e ricerca in giro. Tuttavia, quando ho ricreato i tuoi segnali, avrei potuto trovare una soluzione per te. Dato che i segnali sono abbastanza stabili tranne che in un punto c'è un semplice trucco.

Possiamo ricreare il segnale con s1 = [s1(1) cumsum(diff(s1))];. Da qui l'idea è semplice. Vogliamo ignorare il grande salto. Pertanto dobbiamo limitare il valore massimo da diff(s1). È fatto da:

s1_robust = [s1(1) cumsum(sign(diff(s1)).*min(abs(diff(s1)),1))];.

Ho scelto 1 nel tipo di parte min(s1,1) arbitraria. Potresti voler impostare questo su un fattore della deviazione standard dei segnali.

Ecco il codice completo che ho utilizzato per analizzare il problema.

clc, clear all, close all 

signal = cos([0:0.1:20]); 
s1 = signal + rand(1,201); 
s2 = signal + rand(1,201); 
s2(50:end) = s2(50:end)-8; 

s1_robust = [s1(1) cumsum(sign(diff(s1)).*min(abs(diff(s1)),1))]; 
s2_robust = [s2(1) cumsum(sign(diff(s2)).*min(abs(diff(s2)),1))]; 
corr  = corrcoef(s1,s2) 
corr_robust = corrcoef(s1_robust,s2_robust) 

figure 
plot(s1); 
hold on; 
plot(s2); 

figure 
plot(cumsum(sign(diff(s1)).*min(abs(diff(s1)),1))); 
hold on; 
plot(cumsum(sign(diff(s2)).*min(abs(diff(s2)),1))); 
+0

Grazie mille @Dennis – bienle