{"id":1000,"date":"2019-08-04T16:46:03","date_gmt":"2019-08-04T16:46:03","guid":{"rendered":"https:\/\/muthu.co\/?p=1000"},"modified":"2021-05-24T02:54:05","modified_gmt":"2021-05-24T02:54:05","slug":"basics-of-image-convolution","status":"publish","type":"post","link":"http:\/\/write.muthu.co\/basics-of-image-convolution\/","title":{"rendered":"Basics of Image Convolution"},"content":{"rendered":"\n

Convolution is a process used for applying general-purpose filter effects like blurring, sharpening, embossing, edge detection, and more.<\/p>\n\n\n\n

To understand convolutions we must first understand what a convolution matrix<\/em> is, also referred to as kernel<\/em>. Take for example the blurring filter. In blur filter, we set each pixel to the mean of its neighbouring pixels. Take a look at the below averaging operation. We replaced 227 with 225.<\/p>\n\n\n\n

\"\"<\/a><\/figure><\/div>\n\n\n\n

This is a simple blur filter. We repeat this for all pixels in the image. For corner pixels, we either ignore it or use the immediate neighbour pixels. The matrix representation of each 3×3 window on which we apply our filter looks like:<\/p>\n\n\n\n

\"\"<\/a><\/figure><\/div>\n\n\n\n

The blur operation can be represented as<\/p>\n\n\n\n

h0 = (h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 + h8 ) \/ 9<\/pre>\n\n\n\n

Now if we were to represent the above operation using a matrix, we would get the below representation:<\/p>\n\n\n\n

\"\"<\/a>
Convolution of the center pixel. For the sake of simplicity, I am only considering a convolution for pixels with 8 neighbours. For corners, the average will be between 4 or 6 pixels.<\/figcaption><\/figure><\/div>\n\n\n\n

What happened above is, we multiplied each pixel to its corresponding pixel (which in this case is 1\/9) in the convolution matrix, then summed it up to get the value of the centre pixel. This process is called Convolution represented by the symbol * with a circle around it. The second matrix is called a kernel, mask or a convolution matrix.<\/p>\n\n\n\n

The above convolution operation can be represented mathematically as below:<\/p>\n\n\n\n

\"\"<\/a><\/figure><\/div>\n\n\n\n

where, F(x,y)<\/em> is the output image, f(x,y)<\/em> is the original image, h(i,j)<\/em> is the kernal.<\/p>\n\n\n\n

The below code perform convolutions in python.<\/p>\n\n\n\n

import numpy as np\nfrom scipy.ndimage.filters import convolve\n\na = np.array([[228, 227, 222],[228, 227, 222],[228, 227, 222]])\nb = np.array([[1\/9, 1\/9, 1\/9],[1\/9, 1\/9, 1\/9],[1\/9, 1\/9, 1\/9]])\n\nprint(convolve(a, b))\n\n--------\n\n#the output would be like\narray([[227, 225, 223],\n       [227, 225, 223],\n       [227, 225, 223]])\n\n#the corner pixels used only 4 or 6 pixels. \n\n<\/code><\/pre>\n\n\n\n

For coloured images, we perform convolution on each colour space separately and then merge them together.  Applying the blurring convolution on a full image we get the below result.<\/p>\n\n\n\n

\"\"<\/a><\/figure><\/div>\n\n\n\n

The code used for the above processing is:<\/p>\n\n\n\n

import matplotlib.pyplot as plt\nimport numpy as np\n\nfrom skimage.io import imread\nfrom scipy.ndimage.filters import convolve\n\nimg = imread(\"beautiful-woman.jpg\")\n\nbox_blur_kernel = np.array([[1\/9, 1\/9, 1\/9],\n                            [1\/9, 1\/9, 1\/9],\n                            [1\/9, 1\/9, 1\/9]])\n\nimage_copy = img.copy()\nimage_copy[:,:,0] = convolve(image_copy[:,:,0], box_blur_kernel)\nimage_copy[:,:,1] = convolve(image_copy[:,:,1], box_blur_kernel)\nimage_copy[:,:,2] = convolve(image_copy[:,:,2], box_blur_kernel)\n\nfig, ax = plt.subplots(ncols=2)\nax[0].set_title(\"original\")\nax[0].imshow(img)\nax[1].set_title(\"box blurred\")\nax[1].imshow(image_copy)<\/code><\/pre>\n\n\n\n

There are many other kernels for various image processing operations.<\/p>\n\n\n\n

Gaussian blur<\/h4>\n\n\n\n
\"\"<\/a><\/td>\"\"<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n

Edge detection<\/h4>\n\n\n\n

This one will require the image to converted to grayscale first before convolution.<\/p>\n\n\n\n

\"\"<\/a><\/td>\"\"<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n

Sharpen image<\/h4>\n\n\n\n
\"\"<\/a><\/td>\"\"<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n

Emboss Image<\/h4>\n\n\n\n
\"\"<\/a><\/td>\"\"<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n

References:<\/h2>\n\n\n\n
  • https:\/\/en.wikipedia.org\/wiki\/Kernel_(image_processing)<\/li>
  • https:\/\/en.wikipedia.org\/wiki\/Gaussian_blur<\/li><\/ul>\n\n\n\n

    Sample Image:<\/h2>\n\n\n\n
    • https:\/\/www.pexels.com\/photo\/close-up-photo-of-woman-with-her-eyes-closed-2351707\/<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"

      Convolution is a process used for applying general-purpose filter effects like blurring, sharpening, embossing, edge detection, and more. To understand convolutions we must first understand what a convolution matrix is, also referred to as kernel. Take for example the blurring filter. In blur filter, we set each pixel to the mean of its neighbouring pixels. […]<\/p>\n","protected":false},"author":1,"featured_media":1009,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38],"tags":[47],"_links":{"self":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/1000"}],"collection":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/comments?post=1000"}],"version-history":[{"count":3,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/1000\/revisions"}],"predecessor-version":[{"id":1869,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/1000\/revisions\/1869"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/media\/1009"}],"wp:attachment":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/media?parent=1000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/categories?post=1000"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/tags?post=1000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}