An advanced, purely functional programming language

Google Summer of Code 2018 is just about over and I am absolutely thrilled to have worked for Haskell.org under my mentor Alp Mestanogullari. This summer, I worked towards implementing different classes of image processing algorithms using Haskell and incorporating

Coding the summer away!

the same to the existing code base of Haskell Image Processing (HIP) package to enhance its scope. The algorithms that I implemented have vast applications in real image processing tasks and this project was aimed at encouraging more and more users to actually use Haskell as an alternative for some computer vision problems.

This post is dedicated towards providing a brief overview of the work I managed to accomplish in this project this summer. A preview of which can be looked up at my commit history here.

Coding Phase-I

I started my journey by taking up the implementation of ‘Hough Transform’ as my first challenge. This transformation is generally used as a part of feature extraction in image analysis and computer vision tasks. It is a tool that makes it far easier to identify straight lines in the source image, whatever their orientation. The implementation of this includes computing the Linear Hough transform first and mapping each point in the target image, (ρ, θ) ​to the average color of the pixels on the corresponding line of the source image ​(x,y) space, where the line corresponds to points of the form ​(ρ = xcosθ + ysinθ ). Haskell implementation of the same can be found here. Sample input/output are as follows:

Input image

Output

The idea is that where there is a straight line in the original image, it corresponds to a

bright (or dark, depending on the color of the background field) spot. By applying a suitable filter to the results of the transform, it is possible to extract the locations of lines in the original image. Further extending it’s scope, the classical Hough Transform can be tweaked to correctly detect the positions of arbitrary shapes, including circles and ellipses.

Next algorithm in my bucket list was Adaptive Histogram Equalization. Adaptive histogram equalization (AHE) is a technique used to improve contrast in images. It adjusts image intensity in small regions (neighborhood) in the image. It operates on small ‘contextual’ regions of the image. It enhances the contrast of each region and this technique works well when the distribution of pixel values is similar throughout the image. Haskell implementation of the above can be found here.

Input image

Sample output

The idea is to perform contrast enhancement in ‘neighborhood region’ of each pixel and the size

of the region is a parameter of the method. It constitutes a characteristic length scale: contrast at smaller scales is enhanced, while contrast at larger scales is reduced. However, AHE tends to over amplify the noise in relatively homogeneous regions of the image. This could be taken care of by it’s variant ‘Contrast Limited Adaptive Histogram Equalization (CLAHE).

Coding Phase-II

In the second coding phase of GSoC’18, I started taking up some important convolution filters which were yet to be implemented in the HIP Package. First, I took up the implementation of ‘Laplacian filter’. The Laplacian is a 2-D isotropic measure of the 2nd spatial derivative of an image. The Laplacian of an image highlights regions of rapid intensity change and is therefore often used for edge detection purposes.

Since derivative filters are very sensitive to noise, it is common to smooth the image (e.g., using a Gaussian filter) before applying the Laplacian. This two-step process is call the Laplacian of Gaussian (LoG) operation. The LoG operator takes the second derivative of the image. Where the image is basically uniform, the LoG will give zero. Wherever a change occurs, the LoG will give a positive response on the darker side and a negative response on the lighter side.

For coding purposes, any variants (in terms of kernel) of these may be used (eg., negative central peak). The convolution kernels used for implementation purposes were pre-computed and were of sizes 3 x 3 and 9 x 9 for Laplacian and Laplacian of Gaussian respectively.

Haskell implementation of these can be found here.