2014-08-29 8 views
15

Ho un segnale 1-D in cui sto cercando di trovare i picchi. Sto cercando di trovarli perfettamente.segnale scipy find_peaks_cwt che non trova i picchi con precisione?

Attualmente sto facendo:

import scipy.signal as signal 
peaks = signal.find_peaks_cwt(data, np.arange(100,200)) 

Il seguente è un grafico di macchie rosse che mostrano la posizione dei picchi come si trova da find_peaks_cwt().

Signal + Peaks

Come si può vedere, i picchi calcolati non sono sufficientemente accurate. Quelli che sono veramente importanti sono i tre sul lato destro.

La mia domanda: Come posso renderlo più preciso?

UPDATE: I dati qui: http://pastebin.com/KSBTRUmW

Per alcuni retroscena, quello che sto cercando di fare è individuare lo spazio in-tra le dita in un'immagine. Ciò che viene tracciato è la coordinata x del contorno attorno alla mano. Macchie cian = picchi. Se c'è un approccio più affidabile/robusto, per favore lascia un commento.

enter image description here

+0

Se ho capito bene, il picco di precisione della localizzazione è limitata dal numero più piccolo nel parametro larghezza del picco. Quindi invece di 'np.arange (100.200)', forse 'np.array ([10, 50, 100, 200]) 'darà risultati migliori. –

+0

Quindi, ho appena provato questo, e sembra che sia meglio, ma trova anche molti dossi locali, piuttosto che solo quelli grandi, il che rende l'output pieno di falsi positivi. – cjm2671

+0

Ho riscontrato il problema simile e voglio chiedere come determinare correttamente il parametro della larghezza del picco? Voglio testare i tuoi dati ancora non riesco ad aprire il link (l'URL richiesto non può essere recuperato_) – AnnabellChan

risposta

14

risolto, soluzione:

Filtrare i dati prima:

window = signal.general_gaussian(51, p=0.5, sig=20) 
    filtered = signal.fftconvolve(window, data) 
    filtered = (np.average(data)/np.average(filtered)) * filtered 
    filtered = np.roll(filtered, -25) 

Quindi utilizzare angrelextrema come per la risposta di rapelpy.

Risultato:

enter image description here

+0

potresti aggiungere il codice per trovare i picchi? Penso che la risposta di rapelpy sia stata modificata –

+0

cjm2671, ti preghiamo di spiegare la tua risposta in dettaglio, compresa la convoluzione con un kernel laplaciano, ridimensionamento e laminazione. – rafaelvalle

2

A cura dopo aver ottenuto i dati grezzi.

argelmax e arglextrma sono fuori gara.

La curva è molto rumorosa, quindi è necessario giocare con una larghezza di picco ridotta (come indicato in precedenza) e il rumore.

Il migliore che ho trovato sembra non molto buono.

import numpy as np 
import scipy.signal as signal 

peakidx = signal.find_peaks_cwt(y_array, np.arange(10,15), noise_perc=0.1) 
print peakidx 

[10, 100, 132, 187, 287, 351, 523, 597, 800, 1157, 1451, 1673, 1742, 1836] 

enter image description here

+0

Ho provato questo, sfortunatamente i miei risultati erano piuttosto peggiori dei tuoi http://imgur.com/E4QbRXY. Potrei lisciare i dati per primi, sebbene ritenga che ciò possa distorcere il risultato. – cjm2671

+0

Forse funzionerà: signal.argrelmax (array_y, ordine = 5) Dove l'ordine è quanti punti su ciascun lato utilizzare per il confronto. – rapelpy

+0

Purtroppo no; produce meno punti, ma sembra sacrificare punti buoni per quelli cattivi :(. Altre idee? – cjm2671