Що стосується цієї теми, я успішно застосував фільтр Sobel Edge Detekction в GLSL. Ось фрагмент шейдерного коду фільтра:
#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);
}
І ось результат куба з виявленням краю Собеля:
Якщо ви збільшите картинку, ви побачите, що в компанії Sobel багато "шуму": по всій сцені є сірі горизонтальні смуги через синій / білий градієнт. Крім того, світлі шишки створюють небажаний візерунок на кубі. Чорні краї зліва від куба також схожі на вицвітання через світлий конус на лівій половині куба.
Тому я прочитав цю статтю, в якій сказано, що слід спершу розмалювати масштаб зображення і використовувати фільтр розмитості Гаусса, щоб зробити краї більш очевидними. Внизу статті є також фільтр виявлення реберних ребер, який, здається, дає кращі результати.
Зараз у мене є два питання:
Чи правильні наступні кроки для отримання найкращих можливих результатів виявлення краю:
- Відтінки сірого
- Gaussian Blur
- Виявлення краю Собеля / Кенні
Якщо так, то як би я об'єднав оригінальне зображення з обробленим зображенням? Я маю на увазі, обробляючи описані вище етапи, я отримую зображення, яке є повністю чорним з білими краями або віце-веркою. Як би я наклав краї на моє оригінальне зображення / текстуру?
Спасибі за вашу допомогу!