Wednesday, 27 December 2017

Edge detection in an Image

Hi, in this post I will show you what is edge detection and how you can implement it in python.

1.What is edge detection?

Edge detection is an image processing technique for finding the boundaries of objects within images. It works by detecting discontinuities in brightness.

Canny edge detection applied to a photograph. src



Common edge detection algorithms include 
  1. Sobel
  2. Canny
  3. Prewitt
  4. Roberts
All these algorithms(except canny) defer in the mask that is applied on the image. Canny is a little more complex and includes few more steps.

2.Types of edges


  1. Step Edge: The intensity of the image pixels change abruptly, i.e. the difference in the intensity of adjacent pixels in an image is large.
  2. Ramp Edge: The intensity change but smoothly.
  3. Line Edge: The intensity abruptly changes and then gets back to original value.
  4. Roof Edge: The intensity changes smoothly and then gets back to the original value.






3.Gradient

The magnitude of change of intensity is called the gradient of a pixel. The gradient in 2-D is equivalent to the first derivative. The intensity of the pixels in the image can change in horizontally and vertically. The change in intensity along the horizontal direction is called the horizontal gradient or gx and the change in the vertical direction is called the vertical gradient or gy. 

Note - The coordinate system of the image starts from the top left corner with x increasing as we go towards the right and y increasing as we go down. x and y are also sometimes represented as i and j respectively.

The formula shown below calculates the gradient of a pixel. We need to calculate the gradient at every pixel.
SRC: wiki
df/dy and df/dx are horizontal and the vertical gradients. These are very easy to calculate, what we have to do is basically subtract two or three-pixel values for each horizontal and vertical gradient. How we subtract pixels depends on which edge detection algorithm we are using.

3.1Calculating the gradients

The basic idea of calculating the gradient is the same irrespective of the edge detection algorithm we use. The idea is to do addition/subtraction along the horizontal and vertical axis to calculate the horizontal and vertical gradients.  We do this by taking 3 by 3 window of pixels of the original image at a time and doing computations on them. The value that gets calculated is for the center pixel. We create a new 2D array of the same size as the original image to put in the gradient values we will be calculating. Let's see how to calculate the gradients with Sobels edge operator with an example.

Sobels Edge Operator


This is the Sobels edge operator. What it is telling us is for calculating the horizontal gradient(gx) we need to multiply the Gx in the above image to the corresponding values in a 3x3 window of the original image and then take the sum of all these elements and put at the center pixel. eg 

-1*(1,1) + 0*(1,2) + 1*(1,3) and so on.

Let's take a sample image to make this more clear.



This is a 4*5 image. We start by taking the first 3*3 window:


Calculating the horizontal gradient(gx) for this window:

-1*125 + 0*80 + 1*95 + (-2)*90 + 0*240 + 2*200 + (-1)*10  + 0*250 +1*250 = 430
Now we place this in the new 2D array that we create at the center position of this window which is 2,2( with index starting from 1). 

So now the 2D array of the horizontal gradient will look like:

Now we move the 3x3 window one pixel towards the right. The window would look like:


Similarly, we calculate the horizontal gradient(gx) for this window and put it at the center, which would correspond to 2,3. When we reach the end of the image by sliding this 3x3 window we move the window one pixel down and start from the extreme left of the image again(column 1). we do this till we reach the bottom right of the image.

After we calculate all the horizontal gradients in this manner the array of the horizontal gradients would look like this:



Similarly, we would calculate the vertical gradient using the Gy in Sobels edge operator.


The total magnitude of change at a pixel is given by :


For example, the total magnitude of change at a pixel 2,2 is:
square root( square(value of gx at 2,2) + square( value of gy at 2,2) )  

The direction of change is(gradient angle) :



Note that this is the direction of the change of magnitude and not the direction(angle) of the edge. The edge angle is gradient angle + 90.



4.Steps involved in edge detection


  1. Filtering: This is done to remove the noise from the image. It may lead to loss of sharpness and the edged may become blurry. 
  2. Gradient calculation - In this, we calculate the gradient of each pixel.
  3. Thresholding - In this step we threshold the gradients so that only the gradients that are above certain threshold remain. We do this to remove weak edges and some noise. 
  4. Localization

5. Code


 import numpy as np  
 import cv2  
 from matplotlib import pyplot as plt  
   
 #read image  
 image = cv2.imread("coins.png", 0)  
 plt.imshow(image, cmap='gray')  
 plt.show()  
 rows, columns = image.shape  
   
 #initializing empty arrays, We take a array of zeros as the 3x3 edge detector is not defined at the top, bottom ,left and right most rows  
 gx = np.zeros((rows, columns))  
 gy = np.zeros((rows, columns))  
 gradient_magnitude = np.zeros((rows,columns))  
 gradient_direction = np.zeros((rows,columns))  
   
 for i in range(1, rows-1):  
   for j in range(1, columns-1):  
     gx[i][j] = -1*image[i-1][j-1] -2*image[i][j-1] -1*image[i+1][j-1] + 1*image[i-1][j+1] + 2*image[i][j+1] + 1*image[i+1][j+1]  
     gy[i][j] = 1*image[i-1][j-1] + 2*image[i-1][j] + 1*image[i-1][j+1] -1*image[i+1][j-1] -2*image[i+1][j] -1*image[i+1][j+1]  
     gradient_magnitude[i][j] = np.sqrt(np.square(gx[i][j]) + np.square(gy[i][j]))  
     gradient_direction[i][j] = np.arctan(gradient_magnitude[i][j])  
   
 plt.imshow(gradient_magnitude , cmap='gray')  
 plt.show()  


References

  1. https://en.wikipedia.org/wiki/Edge_detection
  2. https://www.mathworks.com/discovery/edge-detection.html
  3. https://en.wikipedia.org/wiki/Image_gradient
  4. Machine Vision






Sunday, 3 December 2017

Building a new 8 core PC in $100

Hi, recently my laptop broke down and I decided to build a cheap PC. My target was $100 for the CPU. At first, when I saw the prices of parts for a decent configuration I thought it won't be possible to achieve my target of $100, but when I saw some really great offers due to the Black Friday and Cyber Monday deal I thought it might be possible.

The best offers were from AMD and Micro Center. AMD was giving $40 rebate of few of its processors and Micro Center was giving additional discounts($30) if I bought a motherboard with a compatible processor. The total for this was just $42.54(inc tax) after the rebate, combo discount and $5 discount coupon I got from retailmenot.com website for Micro Center.

The case had a $15 rebate and again I used the $5 off coupon from retailmenot.com so the total for the case came out to be around $18 after tax.

The power supply had a $20 rebate and $2 on shipping so the total for the PSU came out to be $22.

Sadly there was no discounts or rebates on the RAM and it cost $31. Although If you search you can find RAM for a cheaper price. I went with this as it had good reviews.

For the hard drive, my laptop had 2 SSD so I took out one of them and put it into the PC. The good thing about Thermaltake case is that it has space to mount 2.5" harddrive. You can get these for around $40.

For keyboard and mouse, you can them for around $10-15. I got the Logitech K400 Plus for $19. 


Parts:

Motherboard - ASUS M5A78L-M/USB3
Processor - AMD Fx-8320E
Power supply - CORSAIR CX Series CX450
Case - Thermaltake V3 Black Edition
RAM - Patriot Signature 4GB DDR3


Price(before and after rebate):

The actual price of the parts was the following:
Motherboard - $55(Micro Center), $10 rebate and $30 off when buying with compatible processor
Processor - $75(Micro Center)  ,  $35 after rebate
Case - $35(Micro Center)  , $15 rebate
Power Supply - $40(Newegg) , $20 rebate
RAM - $31( No discount on this sadly)

Total price of all these parts - 35+75+55+40 + 31 = $205


Total after discounts and rebates = $42.54 + $17.65 + $22 +31 = $113.19

I know it's a little over $100, but I think with these specs it was a pretty good deal.


Rebate Process:

I have not received the money from the rebate yet but I have filled the form for all. It usually takes around 4-6 weeks. The easiest rebate process was for AMD. I just had to fill and form online and upload the bill. For the rest of the parts, I had to take printouts of the rebate forms and a copy of the invoice and mail it to them. The worst(as of now) was of Thermaltake. I had to attach the original UPC code from the box for which I had to cut that part of the box as the sticker was not coming of.



Benchmarks:

3D mark and PCMark 10 did not complete the benchmark and gave an error.
Novabench score - 909