In this article we will describe how to implement a pretty fast image edge detector using OpenGL shader code.
Edge detection is a major task in many image processing algorithms and is great if we can get it to work quickly and optimally.
As discussed in our previous articles, we can make Sobel operator online with pure java script. However, this approach may not provide good performance.
With the support of WebGL, we can now offer efficient image processing online tools across many web browsers, enhancing our capabilities.
OpenGL source code
precision mediump float;
#define KERNEL_SIZE 3
// our texture
uniform sampler2D u_image;
uniform vec2 u_textureSize;
uniform float u_kernel[KERNEL_SIZE];
#define M_PI 3.141592654
#define GET_PIXEL(_x, _y) (texture2D(u_image, textCoord + onePixel*vec2(_x, _y)))
void main() {
vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;
vec2 textCoord = gl_FragCoord.xy / u_textureSize;
float dx = (length(GET_PIXEL(-1, -1)*u_kernel[0] +
GET_PIXEL(-1, 0)*u_kernel[1] +
GET_PIXEL(-1, +1)*u_kernel[2]) -
length(GET_PIXEL(+1, -1)*u_kernel[0] +
GET_PIXEL(+1, 0)*u_kernel[1] +
GET_PIXEL(+1, +1)*u_kernel[2]));
float dy = (length(GET_PIXEL(-1, -1)*u_kernel[0] +
GET_PIXEL(0, -1)*u_kernel[1] +
GET_PIXEL(+1, -1)*u_kernel[2]) -
length(GET_PIXEL(-1, +1)*u_kernel[0] +
GET_PIXEL(0, +1)*u_kernel[1] +
GET_PIXEL(+1, +1)*u_kernel[2]));
float theta = (atan(dy, dx) + M_PI) / (2.0*M_PI);
gl_FragColor = vec4(length(vec2(dx, dy)), theta, 0.0, 1.0);
}
Conclusion
In this post we reveal a simple GL shader that can extract picture contours using GPU. The code produce an image that contains image gradient strength and orientation. These parameters we can then use to get thin image contours via non-maximum suppression.
In case you find this article useful you may take a look at our image analysis algorithms and our software developers portal.
WEB APPLET
See how it works in the browser!