Free Online Image Tools

Edit photos directly in your web browser!

online-image-apps-at-fiveko
Home » Blog » Tutorials » Image edge detection with simple JavaScript

Image edge detection with simple JavaScript

In this article we will discuss how to implement simple image edge detection in pure Java Script. The post reveals several techniques that are suitable for use in a web browser to solve edge detection tasks.

First, let’s start with direct pixel manipulation using the 2D rendering API of the HTML5 Canvas element.

Pure JavaScript and 2D Canvas Context

The source code below shows how to implement an edge detection algorithm using image gradient approximation in pure Java Script and CanvasRenderingContext2D.

How it works?

After putting image data into an HTML5 canvas element, we can retrieve the pixels from it using getImageData. This gives us access to the underlying image data and so we can apply various image processing algorithms on it.

The proposed source code extracts the image outlines using gradients approximation. The most popular algorithms from this family of edge detectors are Sobel operator and Prewitt.

The following sample code implements two helper functions, conv3x and conv3y, which extract horizontal and vertical image edges through a simple two-dimensional convolution.

/**
* @param data - input pixels data
* @param idx - the index of the central pixel
* @param w - image width (width*4 in case of RGBA)
* @param m - the gradient mask (for Sobel=[1, 2, 1])
*/
function conv3x(data, idx, w, m){
  return (m[0]*data[idx - w - 4] + m[1]*data[idx - 4] + m[2]*data[idx + w - 4]
      -m[0]*data[idx - w + 4] - m[1]*data[idx + 4] - m[2]*data[idx + 4 + 4]);
}

function conv3y(data, idx, w, m){
  return (m[0]*data[idx - w - 4] + m[1]*data[idx - w] + m[2]*data[idx - w + 4]
      -(m[0]*data[idx + w - 4] + m[1]*data[idx + w] + m[2]*data[idx + w + 4]));
}


/**
* @param pixels - Object of image parameters
* @param mask - gradient operator e.g. Prewitt, Sobel, Scharr, etc. 
*/
function gradient_internal(pixels, mask)
{
  var data = pixels.data;
  var w = pixels.width*4;
  var l = data.length - w - 4;
  var buff = new data.constructor(new ArrayBuffer(data.length));
  
  for (var i = w + 4; i < l; i+=4){
    var dx = conv3x(data, i, w, mask);
    var dy = conv3y(data, i, w, mask);
    buff[i] = buff[i + 1] = buff[i + 2] = Math.sqrt(dx*dx + dy*dy);
    buff[i + 3] = 255;
  }
  pixels.data.set(buff);
}

/**
* @param canvas - HTML5 Canvas elementFromPoint
*/
function gradient(canvas){
  var context = canvas.getContext('2d');
  var pixels = context.getImageData(0, 0, canvas.width,canvas.height);
  gradient_internal(pixels, [1, 2, 1]); // Apply Sobel operator
  context.putImageData(pixels, 0, 0);
}

The output of this source code is a gradient gray-scale image and it can easily apply different kind of edge detection mask (aka kernels). A nice feature of this family of boundary detectors is that they can produce strong and thin edges using Canny’s algorithm.

Example output

The picture below shows an example output of the Prewitt edge detector.

prewitt-gradient-detection-example
Example output of Prewitt operator

Edge Detection by Canvas Filter API

The Canvas Filter API is a relatively new addition to the web standard. Although this new feature is not mature it is currently supported by major web browsers like Google Chrome and Microsoft Edge.

Essentially, this API is analogous to SVG filters, so they provide the convenience of using them as pure JavaScript code.

The following source snippet shows how we can use the Canvas Filters to implement edge detection through a simple 2D convolution.

function drawFrame(source){
  const canvas = document.querySelector("canvas");
  const context = canvas.getContext("2d");
  canvas.width = source.naturalWidth || source.videoWidth;
  canvas.height = source.naturalHeight || source.videoHeight;
  ctx.filter = new CanvasFilter([
      {
        filter: "convolveMatrix",
        kernelMatrix: [[0, 1, 0], [1, -4, 1], [0, 1, 0]],
         bias: 0,
         divisor: 1,
         preserveAlpha: "true",
      }
   ]);
  context.drawImage(source, 0, 0);
}

The output of the code snippet yields a contour image extracted using discrete approximations to the Laplace filter.

Example output

The following picture shows an example result of the algorithm.

Laplacian edge detector by SVG filters
Example result of Laplacian via Canvas Filter API

Other Resources

The following additional resources may interest you:

Conclusion

Image edge detection is a common task in the fields of image processing and computer graphics. In this post we reveal how to do a simple edge detector in pure Java Script without dependencies and additional components. Although these algorithms are quite fast, they may not work as well for large images. For this reason, you may take a look at fast edge detector by WebGL.

WEB APPLET

See how it works in the browser!

Gradient detection demo app
TAGS:

Spectrum Audio Editor (Free!)

Effortless audio editing, made free. Edit sound like a pro with our online spectrum analyzer.

Sound CMD - Free Online Audio Editor

Fiveko Blog ↗

Discover articles and algorithms for image processing, programming, computer graphics, and more

Image Tools ↗

Free to use online image tools that run in a web browser. Apply photo effects to JPG, PNG, WebP and so on

Projects ↗

Small software projects and applications for various tasks: Graphics, Audio processing and others