Border description

We are going to describe the borders of the outlines of the previous images.

Cell array

A cell array is a matrix of matrices. For example, the following cell array:


>> C = {x1, x2, x3}
>> C
C =
	[512x512  uint8]
	[   12x3 double]
	[    1x4 double]

C contains three matrices: x1, x2, and x3. The first matrix contains an image of size 512x512 of type uint8. The second matrix is an image of size 12x3 in double format, and x3 is a vector of type double.

To get any of the three elements, we type:


>> C{3}
ans =
	1	2	3	4

With the boundaries.p command, we can return a cell array where each element contains all the closed borders detected in the image (two-column vectors containing the (x,y) values of the outline).

Cell fun


d = cellfun(’length’, B);
[max_d, k] = max(d);
b = B{k};

This function returns a vector with the length of each element of the cell array x2. With the function max we are determining the element with the largest dimension, and the index of said element. Inthe las line, we select the largest closed border detected in the image.

To see the biggest border, we use:


[M N] = size(g);
g2 = bound2im(b, M, N, min(b(:,1)), min(b(:,2)));
figure, imshow(g2);

This command creates an image with the border in white and the rest of the pixels in black. Since we don't have the imformation on the size of the image, we pass it the width and height through M and N. For bound2im to draw the image correctly, we need to know the minimum coordinates in both the x and the y axis. Those two parameters are passed through min(b(:,1)) and min(b(:,2))

Border reduction

Sometimes the border obtained before has too much information and we would like to reduce it. For that we can use the MATLAB command:

[s, su] = bsubsamp(b, 50)

It takes samples of the border every 50 pixels and returns two matrices: s, that contains the new reduced border, and su, which contains the points that form the border, but with their separation scaled so that it's unitary.

Since the previous image doesn't represent well the borders, we join the points with a polygon, using:

cn = connectpoly(s(:,1), s(:,2))

where we introduce the coordinates x and y separately. The result, cn, is a closed border.

Freeman's chain code

Given a border like the previous polygon, the Freeman chain code algorithm tells us how much the angle varies from point to point. These angles are normally in representations of 0, 90, 180, 270 degrees, or in 0, 45, 90, 135, 180, 225, 270 and 315 degrees:

Freeman angles representation
Directions of vicinity: To the left, vicinity 4, to the right, vivinity 8.

c = fchcode(su)

Here, su is the polygon border and c is a structure that contains the following information:

They are all vectors of dimension n, except the last one, that has a dimension of 2. For example:


c = 

      x0y0: [7 3]
       fcc: [1x32 double]
      diff: [1x32 double]
        mm: [1x32 double]
    diffmm: [1x32 double]

Imagine that the first pixel makes and angle of 45 degrees with the second pixel. Then the first element of our chain will have a value of 1 in a vicinity of 8. Now, the second pixel has an angle of 0 degrees with respect to the third pixel. Our chain now has a value of 10. We do this for all the pixels of the polygon to obtain c.fcc.

This is not invariant to image rotations, so we have to take the angle difference to model the chain. This difference is calculated counting the number of changes of direction (anticlockwise) that separate two neighbour elements in the chain. For example, if we are counting only 4 directions in our chain, a chain code of 10103322 would be 3133030 once we convert it to angle differences.

The c.mm representation also allow us to make chains more stable against changes or transformations in our images. Since the pixel where we stat to create the chain is random, c.mm starts the chain from the smallest pixel created by the chain code.

Vicinity of 4 and 8

Vicinity of 4 and 8
To the left, a vicinity of 4 only considers the pixels in the directions -180, 180, 90 and -90 degrees. To the right, a vicinity of 8 considers also the pixels at angles of -45, 45, 135 and -135 degrees.

b = boundaries(f, vicinity, direction)

Here, vicinity can be 4 or 8, as shown in the figure. The parameter direction indicates the direction towards which the border is going to be searched, and it can be clockwise ('cw') or counter-clockwise ('ccw').

Polygon representation

[x, y] = minperpoly(f, cellsize)

With this command we can make a representation in polygons of an image, where cellsize is the minimum division to apply to the image in order to calculate the polygons. The algorithm uses a decomposition in quadtrees. It returns the coordinates where the polygon vertices are, in two vectors with the coordinates in the X and Y axis respectively.

Border signature

A signature is a way to describe a closed border. Basically it checks how the distance to the centroid varies with respect to the angle.


[st, angle, x0, y0] = signature(b);
figure, plot(angle, st)

where b is the border, st is the signature, angle is the value in which the angle is sampled, and x0 and y0 is the point of the image with respect to which the measurements have been done.

Signature of two different figures

Fourier decomposition

z = frdescp(b)

Here, b is the outline that we want to decompose and z is the decomposition of said outline.

We can also calculate the inverse transform:

bn = ifrdescp(z, num)

where z is the Fourier decomposition of an outline, and num is the number of components that we want to use to recreate that outline in the spatial domain. The more elements we add, the larger amount of details we will take from our environment.

You can practice these concepts using snippet07.