Wednesday, November 13, 2013

Edge Detection in Images


In Image Processing edge detection plays a major role since it helps to extract features what we are interested in. If we are able to find edges of an object then we can segment the object.
The fundamental idea in edge detection is using an appropriate kernel to find the edges we are interested in. We can represent an image in its grayscale form rather than using rgb or another representation since it makes our job easy.
Think there is a 5 * 5 image as shown below.
250   240   250   30   20
230   240   250   30   25
240   240   250   30   20
250   240   250   30   20
250   240   250   30   20
 
Clearly we can see a edge which is going from high value to a low value in vertical direction. This is<strong> vertical edge.</strong> To identify these type of vertical edges, we can create a new image by taking the difference of each pixel value and its adjacent right pixel. I can create a new Image I2 from original image I, such that
I2(x,y) = I(x,y) - I(x+1,y)
So the resultant image is

 10    -10    220    10   20
-10   -10    220      5   25
   0    -10    220    10   20
 10    -10    220    10   20
 10    -10    220    10   20  

So our image I1 has sharp values along the edge. What we did is we take the difference between two pixels in horizontal directions. Consider this 1 by 2 matrix, G = [1,-1] . Mathematically what we have done here can be represented as a <strong>convolution</strong> between matrix G and original image I, so mathematically
I2 = I * G , here * is for convolution. And we named our matrix G as kernel. if our G is u by v matrix Convolution operation can be written as
I2(x,y) = sum( I(x-u,y-v) * G(u, v) ) here * is for normal multiplication. This is what we have done above.
So by convolve our image I and kernel G == [1,-1] we were able to find vertical edges. So if we define our kernel as
[ 1
-1 ]
then we will be able to find horizontal edges. So to find edges is convolve a suitable kernel with the source image.
Here is sample output of detecting horizontal edges by using the second kernel I mentioned.




 And here is the sample output using kernel [1, -1]. This kernel detects the vertical edges as explained    earlier.



Note that in our second image vertical edges are high lighted than in the previous one, why ? It is because kernel we used. So we have identified horizontal and vertical edge finding methods. So if we wanted to find edges in any direction or gradient image then we can use previously defined two images take I2 as horizontal edge image and I3 as vertical edge image then our gradient image E can be found by
E(x,y) = sqrt( square(I2(x,y)) + square(I3(x,y)) )
Here is the result from previous defined two kernels.



And note that we can achieve better result if we applied a Gaussian filter before edge detection, anyway we can see the difference in each images.
Next I will tell about implementation in java.
Download Project Source code here.

First I load Image from the file using ImageIO and take a BufferedImage object.

image = ImageIO.read(new File("raiway.jpg")); 

Next I converted this image to gray scale image by taking average of R,G,B values and I take raw byte data to perform calculation so I represented image by using a 2 dimensional byte array. Here is How I converted RGB image to gray level data.



After that I wrote a convolve operation as a java method so that I could convolve any matrix with my image data.

Finally the Gradient image finding method which uses two kernels.




So define your own kernels and find edges. Just convolve them.