Fast edge detection with OpenGL/WebGL

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 mentioned in our previous articles, we can make Sobel operator online with pure java script. However, this approach may not provide good performance.

Thanks to WebGL support, this task is achievable for many web browsers, so we can provide image processing online.

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);


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.

Gradient detection demo app


See how it works in the browser!

Related articles