Question

I calcule l'histogramme (un simple tableau 1d) pour une image en niveaux de gris 3D. Maintenant, je voudrais calculer le gradient pour l'cet histogramme à chaque point. Donc, cela signifierait en fait je dois calculer le gradient d'une fonction 1D à certains points. Cependant, je n'ai pas une fonction. Alors, comment puis-je calculer avec valeurs x et y concrètes?

Par souci de simplicité pourrait vous expliquer sans doute cela pour moi sur un histogramme exemple - par exemple avec les valeurs suivantes (x est l'intensité, et y la fréquence de cette intensité):

x1 = 1; y1 = 3

x2 = 2; y2 = 6

x3 = 3; y3 = 8

x4 = 4; y4 = 5

x5 = 5; y5 = 9

x6 = 6; y6 = 12

x7 = 7; y7 = 5

x8 = 8; y8 = 3

x9 = 9; Y9 = 5

x10 = 10; y10 = 2

Je sais que cela est aussi un problème de mathématiques, mais étant donné que je dois résoudre en c ++ je pensais que vous pourriez me aider.

Merci pour vos conseils Marc

Était-ce utile?

La solution

Je pense que vous pouvez calculer votre gradient en utilisant la même approche utilisée dans la détection des frontières d'image (qui est un calcul de gradient). Si votre histogramme est un vecteur, vous pouvez calculer une approximation du gradient comme *:

for each point in the histogram compute 
     gradient[x] = (hist[x+1] - hist[x])

est un moyen très simple de le faire, mais je ne suis pas sûr est la plus précise.

  • approximation parce que vous travaillez avec des données discrètes au lieu de service continu

Edité :

D'autres opérateurs peuvent mettre l'accent sur les petites différences (petits gradients seront devenus plus accentuées). Roberts algorithme dérive du calcul dérivé:

lim delta -> 0 = f(x + delta) - f(x) / delta

delta tend infiniment à 0 (afin d'éviter la division 0) mais jamais nul. Comme dans la mémoire de l'ordinateur ce qui est impossible, le plus petit, nous pouvons obtenir du delta est 1 (car 1 est la plus petite distance de à points dans une image (ou histogramme)).

Substituer

lim delta -> 0 to lim delta -> 1

nous obtenons

f(x + 1) - f(x) / 1 = f(x + 1) - f(x) => vet[x+1] - vet[x]

Autres conseils

Deux approches généralement ici:

  1. une approximation discrète de la dérivée
  2. prendre la dérivée d'une fonction réelle ajustée

Dans le premier cas essayer:

g = (y_(i+1) - y_(i-1))/2*dx

à tous les points, à l'exception des extrémités, ou une de

g_left-end  = (y_(i+1) - y_i)/dx
g_right-end = (y_i - y_(i-1))/dx

dx est l'espacement entre les points x. (Contrairement à la définition correcte également Andres suggéré , celui-ci est symétrique. Que ce qui compte ou ne dépend pas de vous utilisez le cas.)

second cas , installer un spline à vos données [*], et demander à la bibliothèque de la spline dérivée au point que vous voulez.

[*] Utilisez une bibliothèque! Ne pas mettre en œuvre vous-même à moins que cela est un projet d'apprentissage. J'utiliser ROOT parce que je l'ai déjà sur ma machine, mais il est un paquet assez lourd juste obtenir une spline ...


Enfin, si vous les données est bruyant, vous voulez Ma lisser avant de faire la détection de pente. C'était vous évitez chasser le bruit, et ne regardez grandes pentes à grande échelle.

  1. Prenez le papier quadrillé et dessiner dessus votre histogramme. Dessinez également des axes verticaux et horizontaux à travers le point de votre 0,0 histogramme.

  2. Prenez un bord droit et, à chaque point qui vous intéresse, faites pivoter le bord droit jusqu'à ce qu'il accorde à votre idée de ce que le gradient à ce moment-là est. Il est le plus important ce que vous faites, votre définition du gradient est celui que vous voulez.

  3. Une fois que le bord droit est à l'angle que vous désirez tracer une ligne à cet angle.

  4. abaisse des perpendiculaires des 2 points sur la ligne que vous venez de dessiner. Il sera plus facile de passer à l'étape suivante si la distance horizontale entre les 2 points que vous choisissez est d'environ 25% ou plus de la largeur de votre histogramme. De la même 2 points tracer des lignes horizontales à couper l'axe vertical de votre histogramme.

  5. Vos lignes définissent maintenant une distance x et y distance, à savoir la longueur des axes (respectivement) horizontal / vertical tracé par leurs intersections avec les lignes horizontales perpendiculaires /. Le gradient que vous voulez est la distance y divisée par la distance x.

Maintenant, pour traduire en code est très simple, à l'exception de l'étape 2. Vous devez définir quels sont les critères pour déterminer ce que le gradient en tout point de l'histogramme est. choix simples comprennent:

a) à chaque point, situé en bas de votre bord droit de passer par le point et le suivant à sa droite;

b) à chaque point, situé en bas de votre bord droit de passer par le point et le suivant à sa gauche;

c) à chaque point, situé en bas de votre bord droit de passer à travers la pointe vers la gauche et le point vers la droite.

Vous pouvez enquêter sur des choix plus complexes, comme ajustement d'une courbe (comme un polynôme d'ordre supérieur du second degré ou) par un certain nombre de points sur votre histogramme et en utilisant le dérivé de ce pour représenter le gradient.

Jusqu'à ce que vous comprenez la question sur le papier, éviter le codage en C ++ ou quoi que ce soit d'autre. Une fois que vous faites le comprendre, le codage doit être trivial.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top