Algorithme de lissage
J'ai écrit ce code pour le lissage d'une courbe .
Il faut 5 points à côté d'un point et ajoute et moyennes .
/* Smoothing */
void smoothing(vector<Point2D> &a)
{
//How many neighbours to smooth
int NO_OF_NEIGHBOURS=10;
vector<Point2D> tmp=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=a.at(i+j).x;
a.at(i).y+=a.at(i+j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=tmp.at(i-j).x;
a.at(i).y+=tmp.at(i-j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
}
}
Mais j'obtiens de très hautes valeurs pour chaque point, au lieu de les mêmes valeurs pour le point précédent . La forme est agrandie beaucoup , ce qui ne va pas dans cet algorithme ?
Utilisation
Qu'advient-il si vous nourrir de données simple, où les résultats sont prévisibles, et vous le corriger?
j est égal à zéro, donc dans votre intérieur des boucles que vous n'êtes pas en lissant avec ]i, i+NO_OF_NEIGHBOURS], mais avec [i, i+NO_OF_NEIGHBOURS]
Qui a fait le tour , merci 🙂 .
Gardez à l'esprit que, dans la clause else vous accédez à des éléments qui ont déjà été modifiée par votre algorithme de lissage! Notez également que la moyenne d'un point avec ses voisins, vous devez diviser la somme par
+=
et /=
il rend votre code plus lisible (et a moins d'appels à at(i)
).Qu'advient-il si vous nourrir de données simple, où les résultats sont prévisibles, et vous le corriger?
j est égal à zéro, donc dans votre intérieur des boucles que vous n'êtes pas en lissant avec ]i, i+NO_OF_NEIGHBOURS], mais avec [i, i+NO_OF_NEIGHBOURS]
Qui a fait le tour , merci 🙂 .
Gardez à l'esprit que, dans la clause else vous accédez à des éléments qui ont déjà été modifiée par votre algorithme de lissage! Notez également que la moyenne d'un point avec ses voisins, vous devez diviser la somme par
1 + NO_OF_NEIGHBORS
, que le point lui-même est contenue à l'intérieur de cette somme.OriginalL'auteur rajat | 2012-10-19
Vous devez vous connecter pour publier un commentaire.
dans le bloc suivant:
pour chaque voisin vous ajoutez un.(i) x et y respectivement à des valeurs voisines.
je comprends bien, il devrait être quelque chose comme ça.
NO_OF_NEIGHBOURS
sera un de plus que le nombre réel de voisins utilisés.à droite, la condition doit être j<NO_OF_NEIGHBOURS+1, pour être plus clair, j devrait commencer à partir de 0, un.(i+j) devrait être un.(i+j+1).
La variable est nommée
NO_OF_NEIGHBOURS
sens le nombre de voisins à lisse avec. Compte tenu de votre corrigée bouclej
auraNO_OF_NEIGHBOURS - 1
des valeurs différentes, ce qui signifie queNO_OF_NEIGHBOURS - 1
voisins sera lissée, ce qui est un peu contre-intuitif pour le nom.OriginalL'auteur sardok
À quoi il ressemble, vous avez ici est un bass ackwards mise en œuvre d'une réponse impulsionnelle finie (FIR) filtre qui implémente un wagon fonction de fenêtre. La réflexion sur le problème en termes de DSP, vous avez besoin de filtrer les
vector
avecNO_OF_NEIGHBOURS
l'égalité de SAPIN coefficients qui ont chacun une valeur de1/NO_OF_NEIGHBOURS
. Il est normalement préférable d'utiliser un établi algorithme plutôt que de réinventer la roue.Voici une jolie débraillé de mise en œuvre que j'ai élaborées rapidement que les filtres doubles. Vous pouvez facilement modifier ce filtre à votre type de données. La démonstration montre que le filtrage de quelques cycles de montée vu de fonction (0,.25,.5,1) seulement pour les besoins de la démonstration. Il compile, de sorte que vous pouvez jouer avec elle.
Le nombre de coefficients d'un filtre à l'aide de cette ligne pour voir un progressivement de plus en plus lissée de sortie. Avec seulement 1 coefficients du filtre, il n'y a pas de lissage.
Le code est suffisamment flexible que vous pouvez même changer la fenêtre de la forme si vous le souhaitez. Le faire en modifiant les coefficients définis dans le constructeur.
Note: Ce sera un peu différent de sortie de votre mise en œuvre, car c'est l'une des causes de filtre (seulement dépend de l'échantillon et les exemples précédents). Votre application n'est pas causalité qu'il regarde en avant dans le temps à l'avenir des échantillons pour faire la moyenne, et c'est pourquoi vous devez les instructions conditionnelles pour le cas où vous sont près de la fin de votre vecteur. Si vous voulez de sortie comme ce que vous essayez de faire avec votre filtre à l'aide de cet algorithme, exécutez le vecteur par le biais de cet algorithme dans le sens inverse (Cela fonctionne bien aussi longtemps que la fenêtre de la fonction est symétrique). De cette façon, vous pouvez obtenir le même résultat sans le méchant conditionnelle partie de l'algorithme.
Absolument,
if
déclarations au moyen d'une fonction de filtrage sont méchants comme vous l'avez d'avoir un algorithme de vos limites. Voir mes modificationsYEY. Quelqu'un a donné ce un +1. C'EST la solution optimale. Se plaindre plaindre plaindre.
Une inversion de passe pourrait être utile pour prévenir la distorsion de phase (dans ce cas, c'est un zéro distorsion de phase du filtre).
OriginalL'auteur learnvst
De filtrage est bon pour la "mémoire" de lissage. C'est l'inverse pass pour la learnvst de l' réponse, pour éviter la distorsion de phase:
Plus sur zéro distorsion de phase filtre FIR dans MATLAB: http://www.mathworks.com/help/signal/ref/filtfilt.html
OriginalL'auteur trig-ger
Le courant de la valeur du point est utilisé deux fois: une fois parce que vous utilisez
+=
et une fois siy==0
. Donc, vous êtes à la construction de la somme de eg 6 points, mais seulement en divisant par 5. Ce problème est à la fois dans le if et ELSE cas. Aussi: vous devez vérifier que le vecteur est assez long, sinon votre AUTRE cas, allez lire négative des indices.Qui suit n'est pas un problème en soi, mais juste une pensée: Avez-vous envisagé d'utiliser un algorithme qui ne touche que chaque point deux fois?: Vous pouvez stocker temporairement x-y-valeur (initialisée à être identique au premier point), puis que vous visitez chaque point que vous venez d'ajouter le point nouveau et soustraire la très plus anciennes point si elle est plus loin que votre
NEIGHBOURS
dos. Vous gardez cette "somme" mise à jour pour chaque point et de stocker cette valeur divisée par leNEIGHBOURS
-nombre dans le nouveau point.Ohk,compris merci 🙂 . la complexité du temps n'est pas un souci à mon problème car j'ai un vecteur avec seulement 128 points .
OriginalL'auteur Bernd Elkemann
Vous faire plus avec point en lui-même lorsque vous avez besoin de prendre des points voisins - juste compenser indice 1:
OriginalL'auteur Denis Ermolin