Thursday, October 20, 2016

Hough Transform Lines (Octave)

Hough transform was developed to detect lines in 2D pictures.
This post documents simple examples and results I got while working on UD810.

Functions implemented:
  • hough_lines_acc(img_edgs, rho_resolution, theta_resolution)
  • hough_peaks(Hough_acc, NHoodSize)
  • hough_lines_draw(img, output, peaks, rho, theta)

 % create an example array
img = zeros(200, 200);

% Add lines
img(50*200+50 : 201 : 150*200 +150) = 255;
img(50*200+150 : 199 : 150*200 + 50) = 255;

% converting to gray image
I = mat2gray(img);










% extract edges using Canny operator
edges = edge(I, 'canny');










% Hough Transform
[H, T, R] = hough_lines_acc(edges);
% The tricky part of implementing this function is
% to handle negative values:
% rhos and thetas can be positive and negative
% but array index must be positive

% plot voting lines in Hough domain
fig1 = figure 1;
imagesc(H);
saveas(fig1,'lines_in_hough_domain.png');















% Plot hough lines 
% Don't forget use cosd and sind because Theta is in degree
hough_lines_draw(I, 'output.png', P, R, T);

% calculate peaks
% This function not only sort and pick the top peaks
% but also needs to eliminate neighbours (nHoodSize, an odd parameter)
% for each peaks found
% The tricky part is to handle boundary condition, rest is straightforward

P = hough_peaks(H,2) % since we know there are two lines in this example


% Plot outputs from each step
















% Try the flow on football field photo
img = imread('football-field.jpeg');






% Converting to gray image, then extract edges
I2 = rgb2gray(img);

edges = edge(I2, 'canny')
[H, R, T] = hough_lines_acc(edges);















%Plot Hough Domain
imagesc(H);











P = hough_peaks(H,20);
% draw original image, lines and Hough lines
hough_lines_draw(I2, 'football_output.png', P, R, T);

















Monday, September 12, 2016

Canny Edge Detector

Canny Edge Detector

Canny Edge Detector

Canny edge dector uses several steps to extract edges in image:

  • Apply Gaussian filter to smooth image (reduce noise)
  • Calculate gradients of the image (1 and 2 can be combined into one step)
  • Use high threshold to extract "significant" gradients (strong edge pixels)
  • "Thin" to reduce edge pixels to the local peak of gradient (along gradient direction)
  • Linking stage: using low threshold to extend edges extracted the strong edges (clever!)

It is very easy to apply Canny Edge Detector in Matlab:

    edge_img = edge(org_img, 'canny');

In this blog, we will use the Canny edge dector from skimage package

In [18]:
# First part borrow from scikit webpage
# Simple demo using square
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy import ndimage as ndi
from skimage import feature

# Ensure plots embeded in notebook
%matplotlib inline
plt.rcParams['figure.figsize']= (8.0, 6.0)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
In [11]:
# Generate a square with noise
im = np.zeros((256, 256))
im[64:-64, 64:-64] = 1
im = ndi.rotate(im, 30, mode='constant')
im = ndi.gaussian_filter(im, 5)
im += 0.2 * np.random.randn(*im.shape)
plt.imshow(im)
plt.show()
In [14]:
# Extract edges using two different sigma values
edges_default = feature.canny(im)
edges_major = feature.canny(im, sigma=3)
edges_overMajor =  feature.canny(im, sigma=5)
plt.subplot(131)
plt.title('Default Canny Filter')
plt.imshow(edges_default, cmap='gray')
plt.axis('off')
plt.subplot(132)
plt.title('Canny Filter, Sigma = 3')
plt.imshow(edges_major, cmap='gray')
plt.axis('off')
plt.subplot(133)
plt.title('Canny Filter, Sigma = 5')
plt.imshow(edges_overMajor, cmap='gray')
plt.axis('off')

plt.show()
In [24]:
# Second Part, Hummingbird example
bird_im = np.array(Image.open('hummingbird.jpg').convert('L'))
bird_edge_default = feature.canny(bird_im)
bird_edge_sigma2 = feature.canny(bird_im, sigma=2)
bird_edge_sigma3 = feature.canny(bird_im, sigma=3)
plt.subplot(2,2,1)
plt.title('Original Image')
plt.axis('off')
plt.imshow(bird_im)
plt.subplot(2,2,2)
plt.title('Default Canny')
plt.axis('off')
plt.imshow(bird_edge_default)
plt.subplot(2,2,3)
plt.title('Canny, Sigma = 2')
plt.axis('off')
plt.imshow(bird_edge_sigma2)
plt.subplot(2,2,4)
plt.title('Canny, Sigma = 3')
plt.axis('off')
plt.imshow(bird_edge_sigma3)

plt.show()