关于此主题,我已经在GLSL中成功实现了Sobel Edge Detection过滤器。这是过滤器的片段着色器代码:
#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边缘检测的多维数据集的结果:
如果放大图片,您将看到Sobel产生很多“噪音”:由于蓝/白渐变,整个场景中都有灰色水平条纹。此外,光锥在立方体上产生不需要的图案。由于立方体左半部的光锥,立方体左侧的黑色边缘似乎也逐渐消失。
因此,我阅读了这篇文章,指出应该先对图像进行灰度处理,然后使用高斯模糊滤镜使边缘更明显。在文章的底部,还有似乎可以产生更好结果的精巧边缘检测过滤器。
现在我有两个问题:
以下步骤是否正确以产生最佳的边缘检测结果:
- 灰阶
- 高斯模糊
- Sobel / Canny边缘检测
如果是,我将如何合并原始图像和经过处理的图像?我的意思是,在完成上述步骤后,我得到的图像要么是完全黑的,带有白色边缘,要么是反之。如何将边缘放在原始图像/纹理上?
谢谢你的帮助!