In Bezug auf dieses Thema habe ich den Sobel Edge Detection- Filter erfolgreich in GLSL implementiert . Hier ist der Fragment-Shader-Code des Filters:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D screenTexture;
mat3 sx = mat3(
1.0, 2.0, 1.0,
0.0, 0.0, 0.0,
-1.0, -2.0, -1.0
);
mat3 sy = mat3(
1.0, 0.0, -1.0,
2.0, 0.0, -2.0,
1.0, 0.0, -1.0
);
void main()
{
vec3 diffuse = texture(screenTexture, TexCoords.st).rgb;
mat3 I;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
vec3 sample = texelFetch(screenTexture, ivec2(gl_FragCoord) + ivec2(i-1,j-1), 0 ).rgb;
I[i][j] = length(sample);
}
}
float gx = dot(sx[0], I[0]) + dot(sx[1], I[1]) + dot(sx[2], I[2]);
float gy = dot(sy[0], I[0]) + dot(sy[1], I[1]) + dot(sy[2], I[2]);
float g = sqrt(pow(gx, 2.0)+pow(gy, 2.0));
color = vec4(diffuse - vec3(g), 1.0);
}
Und hier ist das Ergebnis eines Würfels mit Sobel-Kantenerkennung:
Wenn Sie das Bild vergrößern, werden Sie feststellen, dass Sobel viel "Rauschen" erzeugt: Aufgrund des blau / weißen Verlaufs sind überall in der Szene graue horizontale Streifen zu sehen. Darüber hinaus erzeugen die Lichtkegel ein unerwünschtes Muster auf dem Würfel. Die schwarzen Ränder links vom Würfel scheinen aufgrund des Lichtkegels in der linken Würfelhälfte ebenfalls zu verblassen.
Also las ich diesen Artikel, in dem angegeben wurde, dass man das Bild zuerst in Graustufen skalieren und einen Gaußschen Unschärfefilter verwenden sollte, um die Kanten deutlicher zu machen. Am Ende des Artikels befindet sich auch der Filter zur Erkennung kniffliger Kanten, der anscheinend bessere Ergebnisse liefert.
Jetzt habe ich zwei Fragen:
Sind die folgenden Schritte korrekt, um die bestmöglichen Kantenerkennungsergebnisse zu erzielen:
- Graustufen
- Gaußsche Unschärfe
- Sobel / Canny Kantenerkennung
Wenn ja, wie würde ich das Originalbild mit dem verarbeiteten Bild zusammenführen? Ich meine, nach der Verarbeitung der oben genannten Schritte erhalte ich ein Bild, das entweder vollständig schwarz mit weißen Rändern oder umgekehrt ist. Wie würde ich die Kanten auf mein Originalbild / meine Originaltextur setzen?
Danke für Ihre Hilfe!
quelle
Antworten:
Die besten Ergebnisse hängen stark von Ihrem Anwendungsfall ab. Sie hängen auch davon ab, welchen Effekt Sie erzielen möchten. Sobel ist nur ein Flankenerkennungsfilter: Die Flanken hängen vom Eingangssignal ab. Die Wahl des Eingangssignals liegt bei Ihnen.
Hier verwenden Sie das Farbbild als Eingabe, und der Filter erkennt zu Recht schwache Kanten im blauen Farbverlauf, während die Kanten des Würfels unterbrochen werden, wenn seine Farbe zu nahe an der Hintergrundfarbe liegt.
Da ich davon ausgehe, dass Ihr Programm auch für das Zeichnen des Cubes verantwortlich ist, haben Sie Zugriff auf andere Informationen, die Sie Ihrem Sobel-Filter zuführen können. Zum Beispiel sind Tiefe und Normalen gute Kandidaten für die Kantenerkennung. Die Albedo vor dem Anzünden könnte man gewohnt sein. Testen Sie mit verschiedenen Eingaben und entscheiden Sie, welche verwendet werden sollen, abhängig von den Ergebnissen, die Sie erhalten.
In Bezug auf Ihre Frage zum Kombinieren der Kanteninformationen empfehle ich Ihnen,
g
vor der Verwendung ein wenig zu filtern . Dann können Sie damit zwischen der Originalfarbe und der gewünschten Kantenfarbe interpolieren.Zum Beispiel könnten Sie so etwas versuchen:
Nachtrag
Um Tiefe oder Normalen zu verwenden, müssten Sie sie in einer Textur speichern, wenn dies noch nicht geschehen ist. Wenn Sie den Bildspeicher für Ihren regulären Rendering-Durchgang erstellen, können Sie ihm verschiedene Texturen hinzufügen (siehe
glFramebufferTexture2D
) und andere Informationen als nur die Farbe der Szene darauf schreiben.Wenn Sie eine Tiefenstruktur (mit
GL_DEPTH_ATTACHMENT
) anhängen , wird diese automatisch für die Tiefe verwendet. Wenn Sie eine oder mehrere Farbtexturen (mitGL_COLOR_ATTACHMENTi
) anhängen , können Sie darauf schreiben, indem Sie Ihren Fragment-Shadern mehrere Ausgaben deklarieren (dies wurde früher durchgeführtgl_FragData
; so oder so, sieheglDrawBuffers
).Weitere Informationen zum Thema finden Sie unter "Multi Render Target" (MRT).
quelle