2010-05-25 6 views
6

J'ai un tableau de valeurs à virgule flottante à une dimension (C# double FYI) et j'ai besoin de trouver le "pic" des valeurs ... comme s'il était représenté graphiquement.Ajustement de crête à une dimension

Je ne peux pas simplement prendre la valeur la plus élevée, car le pic est en fait un plateau qui a de petites fluctuations. Ce plateau est au milieu d'un tas de bruit. Je cherche une solution qui me donnerait le centre de ce plateau.

Un tableau exemple pourrait ressembler à ceci:

1,2,1,1,2,1,3,2,4,4,4,5,6, 8,8,8,8 , 7,8,7,9,7, 5,4,4,3,3,2,2,1,1,1,1,1,1,1,1,1,1

où le pic est quelque part dans la section en gras.

Des idées?

Répondre

3

Vous devez d'abord définir ce que vous voulez dire par «petit». Dites, la «petite» fluctuation autour du maximum est définie comme toute valeur comprise dans & plusmn; ϵ du maximum. Ensuite, il est facile d'identifier le plateau.

Passez les données pour identifier le maximum, puis effectuez une seconde passe pour identifier toutes les valeurs comprises dans & plusmn; ϵ du maximum.

+0

Quelques personnes ici ont donné des réponses similaires, la vôtre était la première. Merci Anon, je n'ai pas pensé à aborder le problème de cette façon. J'ai récupéré les indices de tableau d'une "fenêtre" à ± ε du maximum, et fait la moyenne de ces deux valeurs. C'est une excellente combinaison de vitesse et de précision. Merci encore! – bufferz

6

Vous pouvez appliquer un low-pass filter à votre tableau d'entrée, pour lisser les petites fluctuations, puis trouver le pic dans les données filtrées. L'exemple le plus simple est probablement un filtre "boxcar" , où la valeur de sortie est la somme des valeurs d'entrée dans une certaine distance à partir de la position de réseau actuelle. En pseudocode, il ressemblerait à quelque chose comme ceci:

for i = 0, samplecount-1 
    if (i < boxcar_radius) or (i >= (samplecount - boxcar_radius)) then 
     filtered_data[i] = 0 // boxcar runs off edge of input array, don't use 
    else 
    filtered_data[i] = 0 
    for j = i-boxcar_radius, i+boxcar_radius 
     filtered_data[i] = filtered_data[i] + input_data[j] 
    endfor 
    endif 
endfor 

Si vous avez une idée large du « plateau » sera, vous pouvez choisir le rayon de Boxcar (environ la moitié de la largeur du plateau attendu) pour détecter des caractéristiques à la échelle appropriée.

2

La détection de crête est l'une des étapes de Phase Correlation et d'autres algorithmes d'estimation de mouvement utilisés dans des endroits comme la compression vidéo. Une approche est la suivante: envisager un candidat pour un pic et une fenêtre d'un certain nombre de voisins. Ajuster maintenant une fonction quadratique en utilisant la régression standard. Le pic, avec une précision subpixel, est au maximum du quadratique ajusté.

1

Il est évident que la solution exacte dépend des détails. Si votre distribution est toujours agréable, comme dans votre exemple, vous pourriez avoir:

def GetPeak(l): 
    large = max(l) * 0.8 
    above_large = [i for i in xrange(len(l)) if l[i] > large] 
    left_peak = min(above_large) 
    right_peak = max(above_large) 
    return (left_peak, right_peak)