Aug 6, 2015

Convolutional edge detection filters design

In this post I want to talk about edge detection filters, that are a type of convolution filters, this filters are widely used in features classification algorithms. I will show you all the theory beside edge detection and how to tweak the parameters to match your needs.
An edge can be defined as the change of color between two contiguous area of pixels, bigger the change of color, more noticeable is the edge. This definition perfectly match the definition of derivative:

Edge detection filters are in fact an application of the Derivative. Since we can treat an image as a discrete function, we will use an approximation and instead of $\Delta_x\to0$ and $\Delta_y\to0$ we will use $\Delta_x=1$ and $\Delta_y=1$, so now we have:

$$G_x=f_{(x+1,y)}-f_{(x,y)}$$
$$G_y=f_{(x,y+1)}-f_{(x,y)}$$

$G_x$ and $G_y$ are the partial derivatives of $f_{(x,y)}$ and the gradient and direction can be calculated as:

$$G=\sqrt{G_x^2+G_y^2}$$
$$dir=\arctan{\frac{G_y}{G_x}}$$

Sometimes $G=|G_y|+|G_x|$ is used as an approximation for the gradient, for fast calculation. With all the theory presented we can start hacking some code.

Also, I have included the option to see the gradient just in one of the directions. And here we can compare the results:

This filter is a good approach to edge detection, but suffer a serious problem, its very sensible to noise. This filter will mark garbage as if it were a real edge. But we are lucky because we had seen a trick to remove noise in an image. We can just apply a gaussian filter to the image and then the edge detection algorithm, but this will require us to apply two operations to the image, do you remember my post about image convolution? do you remember this kernel?:

The first derivative is commonly known as Differential of Gaussian, while the second derivative is commonly known as Laplacian of Gaussian.
In the following graph you can see the gaussian filter, and it's first and second derivatives in $\mathbb{R}^2$:

We can tweak the parameters to obtain the most common edge detection filters as for example the Sobel, Prewitt or Scharr operators, or we can even extend the kernel for bigger radius. Here are some examples:

You can try tweaking the parameters of the filter, for example, a bigger radius gives as result a stronger edge, but also remarks spurious pixels, bigger sigma values reduces spurious pixel but gives thiner edges, you can disable round for an accurate but slower result.
Here is an example for radius = 2, sigma = 10, scaleXY = 0.5, scaleW = 200 and round = false: