2013-04-03 2 views
2

Je dois mesurer des vitesses de balayage dans des signaux comme celui de l'image ci-dessous. J'ai besoin du taux de balayage de la partie marquée par la flèche grise. Pour l'instant, je lisse le signal avec une fenêtre de hann pour se débarrasser du bruit éventuel et pour aplatir les pics. Ensuite, je recherche (en commençant à droite) les points de 30% et 70% et calculer le taux de balayage entre ces deux points. Mais mon problème est, que le signal s'aplatit après le lissage. Par conséquent, la vitesse de balayage calculée n'est pas aussi élevée qu'elle devrait l'être. Si je réduis le lissage, alors les pics (vous pouvez voir le côté droit de l'image) augmentent et le point de 30% est finalement trouvé à la mauvaise position.Mesure du taux de balayage

Existe-t-il un moyen meilleur/plus sûr de trouver la vitesse de balayage requise?

Répondre

3

Si vous connaissez entre quelles sont les valeurs de votre signal est en train de passer, et votre bruit est pas trop grand, vous pouvez simplement calculer les différences de temps entre les points de passage de 30% et tous les points de passage de 70% et de garder la plus petite:

import numpy as np 
import matplotlib.pyplot as plt 

s100, s0 = 5, 0 

signal = np.concatenate((np.ones((25,)) * s100, 
         s100 + (np.random.rand(25) - 0.5) * (s100-s0), 
         np.linspace(s100, s0, 25), 
         s0 + (np.random.rand(25) - 0.5) * (s100-s0), 
         np.ones((25,)) * s0)) 


# Interpolate to find crossings with 30% and 70% of signal 
# The general linear interpolation formula between (x0, y0) and (x1, y1) is: 
# y = y0 + (x-x0) * (y1-y0)/(x1-x0) 
# to find the x at which the crossing with y happens: 
# x = x0 + (y-y0) * (x1-x0)/(y1-y0) 
# Because we are using indices as time, x1-x0 == 1, and if the crossing 
# happens within the interval, then 0 <= x <= 1. 
# The following code is just a vectorized version of the above 
delta_s = np.diff(signal) 
t30 = (s0 + (s100-s0)*.3 - signal[:-1])/delta_s 
idx30 = np.where((t30 > 0) & (t30 < 1))[0] 
t30 = idx30 + t30[idx30] 
t70 = (s0 + (s100-s0)*.7 - signal[:-1])/delta_s 
idx70 = np.where((t70 > 0) & (t70 < 1))[0] 
t70 = idx70 + t70[idx70] 

# compute all possible transition times, keep the smallest 
idx = np.unravel_index(np.argmin(t30[:, None] - t70), 
         (len(t30), len(t70),)) 

print t30[idx[0]] - t70[idx[1]] 
# 9.6 

plt. plot(signal) 
plt.plot(t30, [s0 + (s100-s0)*.3]*len(t30), 'go') 
plt.plot(t30[idx[0]], [s0 + (s100-s0)*.3], 'o', mec='g', mfc='None', ms=10) 
plt.plot(t70, [s0 + (s100-s0)*.7]*len(t70), 'ro') 
plt.plot(t70[idx[1]], [s0 + (s100-s0)*.7], 'o', mec='r', mfc='None', ms=10) 
plt.show() 

enter image description here

+0

approche très intéressante. Mais pour le moment j'ai du mal à comprendre votre implémentation. Comment obtenez-vous l'information de temps? Votre signal ne contient aucune valeur de temps. – wewa

+0

@wewa J'utilise la position dans le tableau comme un proxy pour le temps. Si votre signal est échantillonné avec un pas de temps constant 'dt', alors tout ce que vous devez faire est de tout multiplier par cela pour avoir des temps réels. – Jaime

+0

Merci, c'est ce que je pensais déjà. Mais pour moi, il n'est pas vraiment clair comment vous calculez «t30», «t70», «idx30», «idx70» et «idx». Pourriez-vous s'il vous plaît commenter ceci dans votre code? – wewa

Questions connexes