Hough Transform is about detecting curves in an image. The idea is to parameterize the curve, and search for parameters that constitute valid curves in the image.

Any image that is to be processed with this transform needs to be preprocessed by an edge detector, this can be done with e.g. Canny’s edge detection or gradient magnitudes.

Suppose the edge detector has partitioned the elements of the original image into a set of background elements and a set of foreground elements . If we where to try to find curves in the naive way, it would require a tremendous amount of work. Suppose there are elements in set , if we where to find straight lines, one could then take every pair (that is pairs), create a line joining them, and check for every other element in if it is also on this line, and then one could assume that the lines that had the most elements on it, where actual lines in the original image. Hovewer, this would require comparisons, which is unpractical.

The Hough transform is about detecting curves in each of the foreground sets by converting curves to a parameter space which is spanned by the parameters of the curve. Each curve in the original image space is then a point in this parameter space. The Hough transform traverses every element in and every element in a sufficient number of dimensions in the parameter space. Every traversed element in the parameter space would get a vote, and as we traverse the original elements, the elements in the parameter space corresponding to these points would accumulate votes. In the end, we would have certain points in the parameter space with more votes than the other, and we could then argue that these parameters are parameters in an actual curve in the original image space.

Straight line, cartesian coordinates

Every line in space could be described by , or equivivalently in space as . For the foregound class , create a grid which is called the accumulator grid, this is two-dimensional as there are two parameters describing a line in the space.

Traverse every element in , and for each element, traverse every and compute . With some metric, find the the closest in , . With this, you are really creating lines in the space. Now, there exist an accumulator function for every . Its initial value is zero for all parameter tuples. For every iteration explained above, increments with one. In the parameter space, grid cells with a high accumulator value, will appear as intersections, that is, the more lines occupying a grid cell, the higher accumulated value.

Figure 1: Example of Hough transform with cartesian coordinates.

In the end, every parameter pair with a corresponding accumulator value exeding some threshold constitutes a line in space.

Note that this only require (where is the size of ), while still a bit, it is much better than in the naive approach.

There are several problems with the cartesian way of describing lines, vertical lines would imply infinite parameter values, and in general, the range of the parameters are a problem. In stead we use polar coordinates, which is the perferred way.

Straight line, polar coordinates

Every line in space could be described in polar coordinates by , where we have convenient boundaries for the parameters, and , where . For the foreground class , create a grid which is called the accumulator grid, this is two-dimensional as there are two parameters ( and ) needed to describe a line in space. The values of the sets and are now bounded by the aforementioned ranges for the two parameters.

Figure 2: Polar representation of a line.

Traverse every element in , and for each element, traverse every and compute . With some metric, find the the closest in , .

While, in the case above we saw straight lines in the parameter space, we now see sinusoidals. As before, we have a accumulator function for every . Its initial value is zero for all parameter tuples. For every iteration explained above, increments with one. Since we are sampling all points for a certain tuple, we will have many sinusoidals in the parameter space, and as with the straight lines discussed above, their intersection frequency in a cell is equivalent with the value of the accumulator function.

In the end, every parameter pair with a corresponding accumulator value exeding some threshold constitutes a line in space.

Figure 3: Shapes in xy-space and corresponding parameter space accumulator (polar coordinates).
Figure 4: Example of parameter space accumulator values (polar coordinates).

Utilizing full gradient information

The images we are analysing, are already preprocessed with some edge detector, for example a low pass filter followed by a gradient filter. With the gradient filter it is common to get the vertical and the horizontal from the filtering, and then computing the gradient magnitude image and the gradient direction image (remember the rotated coordindate system that I am using for images). The idea is to, instead of, for each checking each angle , we will instead accumulate only the direction for the particular edge index . With this, we will not need to check as many parameters, and will get points in the parameter space in stead of sinusoudals.

Randomized Hough Transform

There are several problems with the ordinary Hough Transform, there are many redundant comparisons which effects the computation effort, and it would be great to somehow reduce the number of unnecessary searches. This is the main motivation behind the randomized Hough transform. I will describe it in brief below, and for a more extensive stydy, see this article from (Xu and Oja, 2009).

Pick a sufficient number of points in depending on the object that you are to detect (for lines you pick two, for circles you pick three etc.). Construct a line between the points, and find the parameter values for this line. Then accumulate the accumulator function for these parameter values. If there already exist an accumulator function for this parameter tuple (or a neighbouring tuple), increment it and set the new parameter tuple it is representing to some weighted average between the old and the new, then delete the old. If it does not exist, create it for this point, and set its value to 1. If the corresponding accumulator function has a sufficient value, put the parameter tuple into a set of candidate solutions. If the number of tuples in the set is above some threshold, examine all tuples in the set, and see if there are sufficient number of elements in the original image that can be expressed by this parameter tuple, if yes, store it as a solution, and delete its image elements from the image. If not, discard this solution. Return to start and pick a new set of image elements.

Pseudocode

  • is a representation of an object in -space.
  • is a representation of the corresponding object in -space.
  • is a set of foreground pixels in -space.
  • is a set of solution parameters , initially empty.
  • is a set of non-solution parameters , initially empty.
  • and are predefined positive thresholds.
  • is the accumulator value for parameter .
  • while True
    • Pick a sufficient (2 for line, 3 for circle etc) number of points .
    • Compute parameters using .
    • if
      • Contiunue from start and pick a new point.
    • else
      • if
        • Increment count for this parameter:
        • Set candidate solution parameter:
      • else if for some
        • Compute an average parameter
        • Insert it to the accumulator, and increment the count:
        • Delete
        • Set candidate solution parameter:
      • else
        • Insert this value to the accumulator with count 1:
        • Set candidate solution parameter:
      • end if
      • if
        • if
          • We found a solution:
          • Delete it from :
        • else
          • Blacklist it:
        • end if
      • end if
    • end if
    • if (max num iterations is reached) or ()
  • end while