Im Allgemeinen läuft die Kantenerkennung darauf hinaus, Bereiche des Bildes mit hohem Gradientenwert zu erkennen.
In unserem Fall können wir den Gradienten grob als Ableitung der Bildfunktion sehen, daher gibt Ihnen die Größe des Gradienten eine Information darüber, wie stark sich Ihr Bild lokal ändert (in Bezug auf benachbarte Pixel / Texel).
Nun, eine Kante ist, wie Sie sagen, ein Hinweis auf Diskontinuität. Nachdem wir nun den Gradienten definiert haben, ist klar, dass diese Informationen alles sind, was wir brauchen. Sobald wir den Gradienten eines Bildes gefunden haben, müssen wir nur noch einen Schwellenwert darauf anwenden, um einen Binärwert für die Kante / Nichtkante zu erhalten.
Wie findest du diesen Gradienten ist wirklich das, was du fragst und ich muss noch antworten :)
Viele Möglichkeiten! Hier ein paar :)
Eingebaute Shader-Funktionen
Sowohl hlsl als auch glsl bieten abgeleitete Funktionen. In GLSL haben Sie dFdx und dFdy , die Ihnen Gradienteninformationen in x- und y-Richtung geben. Typischerweise werden diese Funktionen in einem Block von 2x2 Fragmenten ausgewertet.
Wenn Sie nicht an einer einzelnen Richtung interessiert sind, ist ein guter Weg, um ein kompaktes Ergebnis zu erzielen , das angibt, wie stark der Gradient in der Region ist, die Breite , die Ihnen nichts anderes als die Summe der absoluten Werte von dFdy und dFdy gibt.
Es ist wahrscheinlich, dass Sie eher an einer Kante des Gesamtbilds als an einem bestimmten Kanal interessiert sind. Daher möchten Sie möglicherweise Ihre Bildfunktion in Luma umwandeln. In diesem Sinne könnte Ihr Shader bei der Kantenerkennung Folgendes enthalten:
float luminance = dot(yourFinalColour,vec3(0.2126, 0.7152, 0.0722));
float gradient = fwidth(luminance );
float isEdge = gradient > threshold;
Bei einem hohen Schwellenwert finden Sie gröbere Kanten, und bei einem niedrigen Schwellenwert können Sie möglicherweise falsche Kanten erkennen. Sie müssen experimentieren, um den Schwellenwert zu finden, der Ihren Anforderungen besser entspricht.
Der Grund, warum diese Funktionen funktionieren, ist erwähnenswert, aber ich habe jetzt keine Zeit dafür. Ich werde diese Antwort wahrscheinlich später aktualisieren :)
Nachbearbeitung des Bildschirmbereichs
Sie könnten schicker sein, jetzt ist das Feld der Kantenerkennung in der Bildverarbeitung immens. Ich könnte Ihnen Dutzende guter Möglichkeiten nennen, um die Kantenerkennung gemäß Ihren Anforderungen zu erkennen, aber lassen Sie es uns vorerst einfach halten. Wenn Sie interessiert sind, kann ich Ihnen weitere Optionen nennen!
Die Idee wäre also ähnlich wie oben, mit dem Unterschied, dass Sie sich eine größere Nachbarschaft ansehen und eine Reihe von Gewichten für umgebende Samples verwenden könnten, wenn Sie möchten. Normalerweise führen Sie eine Faltung über Ihr Bild mit einem Kernel durch, der Ihnen als Ergebnis gute Verlaufsinformationen liefert.
Eine sehr häufige Wahl ist der Sobel-Kernel
Welche geben Ihnen Gradienten in x- und y-Richtung:
G r a di e n t M.a gn i t u de = ( G r a di e n tx)2+ ( G r a di e n ty)2- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -√
Dann können Sie wie oben erwähnt einen Schwellenwert festlegen.
Wie Sie sehen können, gibt dieser Kernel dem zentralen Pixel mehr Gewicht, sodass der Gradient + ein wenig Glättung effektiv berechnet werden, was traditionell hilfreich ist (häufig ist das Bild Gaußsch verschwommen, um kleine Kanten zu beseitigen).
Das obige funktioniert ganz gut, aber wenn Sie die Glättung nicht mögen, können Sie die Prewitt-Kernel verwenden:
(Beachten Sie, dass ich in Eile bin und bald richtig formatierten Text anstelle von Bildern schreiben werde!)
Wirklich, es gibt viel mehr Kernel und Techniken, um die Kantenerkennung auf bildprozessähnliche Weise zu finden, als Echtzeitgrafiken. Daher habe ich kompliziertere (Wortspiel nicht beabsichtigte) Methoden ausgeschlossen, da Sie mit dFdx / y-Funktionen wahrscheinlich in Ordnung wären .