|
|
The aim of this laboratory session is to experiment with edge detection and implement the Hough transform for finding lines in images.
Convert your image to greyscale and smooth it with a Gaussian filter (as you did in Lab4). To find the gradient in the vertical and horizontal directions convolve the image with simple differencing filters. The horizontal differencing filter is
| -1 | 0 | 1 |
It is quite possible that your gradient strength image will be very dark. This is most likely caused by a few values in the image being very large. When the image is rescaled to the range 1-255 for display, most parts of the image end up being very dark. To compensate for this you can use the function adjgamma to adjust the gamma of the image and enhance the dark regions of the image (e.g., try a gamma value of 2).
Generate the gradient strength image for three very different levels of Gaussian smoothing and observe the differences.
To get to an edge image the gradient strength image needs to undergo non-maximal suppression and hysteresis thresholding. Rather than implement this one can simply use MATLAB's edge function which implements a variety of edge detection methods, and performs non-maximal suppression and thresholding (see the help page for edge).
Use the edge function, with the 'canny' option, to generate an edge map of yourself. You will need to experiment with the hysteresis threshold values to get a reasonable result.
Write a function, hough that meets the following specification
% HOUGH % % Function takes a grey scale image, constructs an edge map by applying % the Canny detector, and then constructs a Hough transform for finding % lines in the image. % % Usage: h = hough(im, Thresh, nrho, ntheta) % % arguments: % im - The grey scale image to be transformed % Thresh - A 2 -vector giving the upper and lower % hysteresis threshold values % nrho - Number of quantised levels of rho to use % ntheta - Number of quantised levels of theta to use % % returns; % h - The Hough transform function h = hough(im, Thresh, nrho, ntheta)The steps you should follow:
|
(Alternatively, we can enforce rho to be always positive while letting theta to be in the range from 0 to 2pi.)
Then for each edge point (xi, yi) in the image we let the parameter theta equal each of the allowed discretised values of theta , and solve for the corresponding rho using the equation
|
The accumulator array should then have all its entries corresponding to the discretised rho and theta values that make up this sinusoidal curve incremented by 1.
At the end of this procedure, a value of M in this accumulator array corresponds to M points in the xy plane that lie on the line
|
The fiddly bit of this code is getting the conversion between rho and theta and the corresponding row and column number in the accumulator array correct. Here is some code to save you some grief!
rhomax = sqrt(rows^2 + cols^2); % The maximum possible value of rho.
drho = 2*rhomax/(nrho-1); % The increment in rho between successive
% entries in the accumulator matrix.
% Remember we go between +-rhomax.
dtheta = pi/ntheta; % The increment in theta between entries.
theta = [0:dtheta:(pi-dtheta)]; % Array of theta values across the accumulator matrix.
% To convert a value of rho or theta to its appropriate index in the array use:
rhoindex = round(rho/drho + nrho/2);
thetaindex = round(theta/dtheta + 1);
Your Hough Transform should look something like this
Having calculated the Hough Transform we now want to find what the dominant lines are and overlay them in the image. Write a function with the following specification
% HOUGHLINES % % Function takes an image and its Hough transform, finds the % significant lines and draws them over the image % % Usage: houghlines(im, h, thresh) % % arguments: % im - The original image % h - Its Hough Transform % thresh - The threshold level to use in the Hough Transform to % decide whether an edge is significant function houghlines(im, h, thresh)What this code has to do is find the local peaks within the Hough transform.
for n = 1:nregions
mask = bwl == n; % Form a mask for each region.
region = mask .* h; % Point-wise multiply mask by Hough Transform
% to give you an image with just one region of
% the Hough Transform.
...
end
Note that you can use MATLAB's max function to find the indices of the peak
[maxval, index_of_max] = max(X)If matrix X is 2D maxval will be an array giving the maximum value in each column of X and index_of_max will be an array giving the row where the maximum value was in each column. A second call to max on the array maxval will identify the absolute maximum value in X and the column in which it occurs.
You should be able to make your Matlab script to handle the plotting of both vertical and horizontal lines automatically.
An alternative (and probably better) way of picking out the peaks in the Hough transform would be to use the function nonmaxsuppts.
This function was originally written for non-maximal suppression of corner strength images. What this code does is a greyscale dilation of the image (within the structuring element area every pixel is replaced with the maximum pixel value within the structuring element area). Where the greyscale dilated image matches the original image will correspond to local maxima.
In using this function you would pass your Hough transform in as the 'corner image'. The size of the structuring element controls how close together you are prepared to have local maxima.
There is plenty of room for refinements. The Hough Transform 'surface' tends to be very rough. This is partly caused by the primitive way in which we 'draw' the sinusoidal votes into it. Note that if for some increment in theta the rho value changes by two or more we should be 'drawing in' extra points to ensure that we do not skip the intermediate rho values.
One can get some improvement by smoothing the transform very slightly. Some morphological processing may also be useful after the thresholding process.
Here is the warning again! In all of the above beware of getting confused between x and y, and row and column number.
The following should be included in your portfolio:
Your Matlab functions/scripts will be run and tested in the marking. So, do not forget to include all other Matlab functions (excluding the Matlab library functions but including Dr Peter Kovesi's) that are needed by your Matlab functions/scripts.
You might find it more tidy to save your MATLAB code and input/output test image files into subdirectories away from your HTML file. Ensure that all the links in your HTML file are correct. You should also provide some explanation in your HTML file to demonstrate your understanding about the problem and the work that you carried out.