• No results found

The Image Processing Toolbox does not contain a hough routine, and although the Hough transform can be obtained by other means, it is a pleasant programming exercise to write our own. Following the procedure outlined above, we will:

1. decide on a discrete set of values of and to use,

2. for each foreground pixel   in the image calculate the values of &  

for all of our chosen values of ,

3. create an accumulator array whose sizes are the numbers of angles and values in our chosen discretizations from step 1,

4. step through all of our  values updating the accumulator array as we go. We shall consider each step in turn:

Discretizing  and . We observe that even though a particular pair   corresponds to only one line, a given line can be parameterized in different ways. For example, the line  



 can be parameterized using #



and   as shown in figure 10.7(a). However, the same line can be parameterized using 



and 



 . So we have a choice: we may restrict the values of , say to the range







  , and let  have both positive and negative values, or we may let take any value chosen from the range 



# and restrict  to non-negative values. Since we are going to use the values of and as indices into the accumulator array, it is simplest to take the second option. However, consider figure 10.7(a) slightly redrawn to take into account the directions of  and  as column and row indices of a matrix, as shown in (b). Since our image, for which both and will be positive, will sit in the bottom right quadrant, we will only have positive  values for



  



. For if is outside that range, the perpendicular will point into the second (upper left) quadrant, which would require a negative value of  if the line was to intersect the image.

We can choose any discrete set of values we like, but let us take all the integer degree values in the given range, but convert them to radians for the purposes of calculation:

10.2. IMPLEMENTING THE HOUGH TRANSFORM IN MATLAB 175       #   

(a) Using ordinary Cartesian axes

Image     #   

(b) Using matrix axes

Figure 10.7: A line parameterized with and

>> angles=[-90:180]*pi/180;

Calculating the  values. Suppose that the image is binary, then we can find the positions of all the foreground pixels with a simple application of the find function:

>> [x,y]=find(im);

If the image is not binary, we can create a binary edge image by use of the edge function. Now we can calculate all the  values with one simple command:

>> r=floor(x*cos(angles)+y*sin(angles)); where we use floor so as to obtain only integer values.

Forming the accumulator array. If the image is of size  pixels, then supposing the origin to be at the upper left corner, the maximum value of  will be





 . So the size of the accumulator array can be set at







  . However, we are only interested in positive values of : given our choice of range of , negative values can be discarded. So we can first find the largest positive value of  , and use that as one dimension of the array:

>> rmax=max(r(find(r>0))); >> acc=zeros(rmax+1,270);

The rmax+1 allows us to have values of  .

Updating the accumulator array. We now have to step through the array of  values, and for each value   , increase the corresponding accumulator value by one. First notice that the array

176 CHAPTER 10. THE HOUGH AND DISTANCE TRANSFORMS r, as define above, has size   , where is the number of foreground pixels. Hence the second index of both r and acc corresponds to the angle.

This can be done with nested loops, at the heart of which will be the command if r(i,j)>=0, acc(r(i,j)+1,i)=acc(r(i,j)+1,i)+1;

Note that this is not a very efficient method of creating the accumulator array, but it does have the advantage of following the theory very closely. The entire program is shown in figure 10.8.

function res=hough(image) %

% HOUGH(IMAGE) creates the Hough transform corresponding to the image IMAGE % if ~isbw(image) edges=edge(image,’canny’); else edges=image; end; [x,y]=find(edges); angles=[-90:180]*pi/180; r=floor(x*cos(angles)+y*sin(angles)); rmax=max(r(find(r>0))); acc=zeros(rmax+1,270); for i=1:length(x), for j=1:270, if r(i,j)>=0 acc(r(i,j)+1,j)=acc(r(i,j)+1,j)+1; end; end; end; res=acc;

Figure 10.8: A simple Matlab function for implementing the Hough transform

An example

Let us take the cameraman image, and apply our Hough transform procedure to it: >> c=imread(’cameraman.tif’);

>> hc=hough(c);

This last command may take some time, because of the inefficient nested loops. The first thing we may do is to view the result:

>> imshow(mat2gray(hc)*1.5)

where the extra 1.5 at the end is just to brighten up the image. The result is shown in figure 10.9. What we are viewing here is the accumulator array. And it is what we should expect: a series of curves, with some bright points indicating places of maximum intersection. Because of the use of

10.2. IMPLEMENTING THE HOUGH TRANSFORM IN MATLAB 177

Figure 10.9: The result of a Hough transform

sines and cosines in the construction of the transform, we can expect the curves to be of a sinusoidal nature.

What now? Let us find the maximum value of the transform: >> max(hc(:))

ans = 91

We can now find the and values corresponding to the maximum: >> [r,theta]=find(hc==91)

r = 138

theta = 181

However, since we are using the pixel coordinates as cartesian coordinates, our  and  axes have been rotated counter-clockwise by . Thus we are measuring in a clockwise direction from the left vertical edge of our image. Figure 10.10 shows how this works:

We have also got the problem that We can easily create a small function to draw lines for us, given their perpendicular distance from the origin, and the angle of the perpendicular from the  axis. The tool for this will be the line function, which in the form

178 CHAPTER 10. THE HOUGH AND DISTANCE TRANSFORMS      

Figure 10.10: A line from the Hough transform

draws a line between coordinates    and     over the current image. The only difficulty here is that line takes the  axis to be on the top, and the axis going down on the left. This is easily dealt with by replacing with 



, and a simple function for drawing lines is shown in figure 10.11.

The only thing to notice is the expression 181-theta in the line angle=pi*(181-theta)/180;

This can be interpreted as







; the initial



swaps between cartesian and matrix coordinates, and the extra 1 counters the accumulation of r+1 in the function hough.m.

We can use this as follows:

>> c2=imadd(imdivide(cm,4),192); >> imshow(c2)

>> houghline(c2,r,theta)

The idea of using c2 is simply to lighten the image so as to show the line more clearly. The result is shown on the left in figure 10.12. To draw other lines, we can extract some more points from the transform: >> [r,theta]=find(hc>80) r = 148 138 131

10.2. IMPLEMENTING THE HOUGH TRANSFORM IN MATLAB 179

function houghline(image,r,theta) %

% Draws a line at perpendicular distance R from the upper left corner of the % current figure, with perpendicular angle THETA to the left vertical axis. % THETA is assumed to be in degrees.

% [x,y]=size(image); angle=pi*(181-theta)/180; X=[1:x]; if sin(angle)==0 line([r r],[0,y],’Color’,’black’) else line([0,y],[r/sin(angle),(r-y*cos(angle))/sin(angle)],’Color’,’black’) end;

Figure 10.11: A simple Matlab function for drawing lines on an image

180 CHAPTER 10. THE HOUGH AND DISTANCE TRANSFORMS 85 90 theta = 169 181 182 204 204

Then the command

>> houghline(c,r(1),theta(1))

will place the line as shown on the right in figure 10.12. Clearly we can use these functions to find any lines we like.