Frage

Ich berechnete das Histogramm (ein einfaches 1D -Array) für ein 3D -Graustufenbild. Jetzt möchte ich den Gradienten für dieses Histogramm an jedem Punkt berechnen. Dies würde also tatsächlich bedeuten, dass ich den Gradienten für eine 1D -Funktion an bestimmten Stellen berechnen muss. Ich habe jedoch keine Funktion. Wie kann ich es also mit Beton -X- und Y -Werten berechnen?

Für den Einfachheit halber können Sie mir dies wahrscheinlich in einem Beispiel -Histogramm erklären - zum Beispiel mit den folgenden Werten (x ist die Intensität und y die Häufigkeit dieser Intensität):

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

Ich weiß, dass dies auch ein mathematisches Problem ist, aber da ich es in C ++ lösen muss, könnte ich mir hier helfen.

Vielen Dank für Ihren Rat Marc

War es hilfreich?

Lösung

Ich denke, Sie können Ihren Gradienten anhand desselben Ansatzes berechnen, der bei der Bildranderkennung verwendet wird (was ein Gradientenkalkül ist). Wenn sich Ihr Histogramm in einem Vektor befindet, können Sie eine Näherung des Gradienten als*berechnen:

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

Dies ist eine sehr einfache Möglichkeit, es zu tun, aber ich bin mir nicht sicher, ob es am genauesten ist.

  • Annäherung, weil Sie mit diskreten Daten anstelle von kontinuierlich arbeiten

Bearbeitet:

Andere Betreiber werden möglicherweise kleine Unterschiede hervorheben (kleine Gradienten werden stärker betont). Der Roberts -Algorithmus stammt aus dem Derivatkalkül:

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

Delta tendiert unendlich auf 0 (um 0 Division zu vermeiden), ist aber niemals Null. Wie im Speicher des Computers ist dies unmöglich, das kleinste, das wir von Delta erhalten können, ist 1 (da 1 der kleinste Abstand von Punkten in einem Bild (oder Histogramm) ist).

Ersetzen

lim delta -> 0 to lim delta -> 1

wir bekommen

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

Andere Tipps

Zwei nähert sich hier im Allgemeinen:

  1. eine diskrete Annäherung an das Derivat
  2. Nehmen Sie das eigentliche Ableitungen einer angepassten Funktion

In dem Erster Fall Versuchen:

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

an allen Punkten außer den Enden oder einer von

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

wo dx ist der Abstand zwischen x Punkten. (Im Gegensatz zur ebenso korrekten Definition Andres schlug vor, Dieser ist symmetrisch. Ob es wichtig ist oder nicht, hängt von Ihrem Anwendungsfall ab.)

In dem Zweiter Fall, fit a Spline zu Ihren Daten [*] und fragen Sie die Spline -Bibliothek nach dem gewünschten Punkt nach dem Derivat.

*] Verwenden Sie eine Bibliothek! Implementieren Sie dies nicht selbst, es sei denn, dies ist ein Lernprojekt. Ich würde benutzen WURZEL Weil ich es schon auf meiner Maschine habe, aber es ist ein ziemlich schweres Paket, nur um einen Spline zu bekommen ...


Wenn Ihre Daten laut sind, möchten Sie es schließlich glätten, bevor Sie die Hangerkennung durchführen. Das war, dass Sie es vermeiden, das Geräusch zu verfolgen und nur große Hänge auszusehen.

  1. Nehmen Sie ein quadratisches Papier und zeichnen Sie Ihr Histogramm darauf. Zeichnen Sie auch vertikale und horizontale Achsen durch den 0,0 -Punkt Ihres Histogramms.

  2. Nehmen Sie eine geraden Kante und drehen Sie an jedem Punkt, an dem Sie interessiert sind, die geraden Kante, bis sie mit Ihrer Vorstellung von dem Ablauf an diesem Punkt entspricht. Es ist am wichtigsten, dass Sie dies tun. Ihre Definition von Gradienten ist die gewünschte.

  3. Sobald die gerade Kante im Winkel ist, den Sie sich wünschen, ziehen Sie eine Linie in diesem Winkel.

  4. Lassen Sie die Senkrechte von 2 Punkten auf der Linie fallen, die Sie gerade gezeichnet haben. Es ist einfacher, den folgenden Schritt zu tun, wenn der horizontale Abstand zwischen den 2 Punkten, die Sie auswählen, etwa 25% oder mehr der Breite Ihres Histogramms beträgt. Zeichnen Sie aus den gleichen 2 Punkten horizontale Linien, um die vertikale Achse Ihres Histogramms zu schneiden.

  5. Ihre Linien definieren jetzt eine X-Distanz und eine Y-Distanz, dh die Länge der horizontalen/ vertikalen (jeweiligen) Achsen, die durch ihre Kreuzungen mit den senkrechten/ horizontalen Linien gekennzeichnet sind. Der Gradient, den Sie wollen, ist die Y-Distanz geteilt durch die X-Distanz.

Um dies in Code zu übersetzen, ist abgesehen von Schritt 2 sehr einfach, abgesehen von Schritt 2. Sie müssen definieren, welche Kriterien der Gradient an jedem Punkt im Histogramm sind. Einfache Entscheidungen umfassen:

A) Stellen Sie an jedem Punkt Ihre geraden Kante ab, um den Punkt und den nächsten rechts zu durchlaufen.

b) Legen Sie an jedem Punkt Ihre geraden Kante ab, um den Punkt und den nächsten nach links zu durchlaufen.

c) Legen Sie an jedem Punkt Ihre gerade Kante ab, um den Punkt links und den Punkt nach rechts zu durchlaufen.

Möglicherweise möchten Sie komplexere Auswahlmöglichkeiten untersuchen, z.

Bis Sie die Frage auf dem Papier verstehen, vermeiden Sie das Codieren in C ++ oder irgendetwas anderes. Sobald Sie es verstanden haben, sollte die Codierung trivial sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top