Editing Images with Convolution Matrices using Node.js and JIMP
By: Chris Webb
Tags: Jimp, Image Processing, JavaScript, Nodejs, Web Development

Editing Images with Convolution Matrices using Node.js and JIMP

Photo: Chris Webb

The phrase “convolution matrix” sounds a bit scary if you are not familiar with the topic but it is actually a very simple concept to understand and extremely powerful. The process is best explained with a diagram.

On the left is a grid of pixels representing a section of a digital image, on the right is the new value for the centre pixel, and the two centre grids show how the new value is calculated.

To obtain the new value for the centre pixel, which is currently 128, we multiply each of the values in the grid by its corresponding value in the kernel matrix. The results are shown in the Products matrix. These nine values are then added to give a final value, and the process repeated for every pixel in the image. If the result is outside the 0–255 range then 0 or 255 are used.

I have used greyscale for simplicity but RGB images work in the same way, just with three times as many values.

Each kernel has a certain effect on the image, for example sharpening or blurring. I will show a few well-known ones in the code.

The Project

This project use the JIMP npm package which provides a method for applying a convolution matrix to an image. The full documentation for JIMP can be found at https://www.npmjs.com/package/jimp and you can install it with:

npm install --save jimp

The JIMP implementation of convolution matrices is very rudimentary and I am working on a more flexible implementation for a project I am working on. However, you can still carry out some useful enhancements with the JIMP version and it is also ideal for learning the topic.

The source code for this project consists of one short JavaScript file which you can clone or download from the Github repository. The image above I used for testing is included in the repository; if you want to use your own photo just edit the filename on line 19.

This is the listing.

Firstly I have created an array of objects, each with a name and a kernel . The names give a clue to the effect each particular kernel has on the image. This array is then iterated in a for/of loop within which we open the original image, log the particular kernel details, apply it with the convolute method, and finally save the resulting image.

You might think, as I did, that the convolute method would return a copy. It doesn’t! It actually edits the existing image which is why I re-opened it each time.

Now let’s run the code.

node convolutionmatrix.js

The resulting images are shown below. As you may have noticed the filenames are the original filename with the convolution matrix name suffixed.

Emboss

Edge detect. Check out the Wikipedia article on the topic

Edge enhance. Again check out the Wikipedia article.

Blur. You don’t need Wikipedia to understand this one!

Sharpen. The effect is a bit excessive so you might like to experiment with other similar values.

I have demonstrated a few of the well known and useful convolution matrices but of course there is an infinite number of possible ones.

The scope is intriguing. Are there any as-yet undiscovered matrices which have useful, bizarre or spectacular effects?