CSC 370

Binary Image Processing

[Due Wednesday, September 30]

The simplest image type is the binary image. They are used for many different purposes, but one application is as a mask. A binary mask is a binary image used in association with some other image to indicate areas of interest or areas that require further processing. For example, in the wrench image below, one could create a mask for each of the three wrenches, indicating its spatial extent in the image. One such mask is shown at right.

Getting a good mask is not as difficult as it might seem, at least for this image. The Matlab function that computes connected components is called bwlabel. It works just like the algorithm presented in class: given a binary image, it returns a new matrix with a different integer label on every connected component of the foreground (and zero on all the background pixels). Try the following sequence (note that the mask produced will not look exactly as shown above):

>> img = imread('wrenches.jpg');
>> imshow(img);
>> imshow(img < 160);
>> lbl = bwlabel(img < 160);
>> imagesc(lbl);
>> colorbar;
>> imshow(lbl == 26);

Once a mask of an object has been extracted, its position and orientation may be computed. This has many uses. For example, before a robot arm can grasp an object, it must know its position and orientation in advance in order to plan the arm movement and get a good grasp on the object. Another use of computer vision is in industrial processes, where a video camera trained on an assembly line produces images of parts in production. The job of the computer is to identify, based on these images, any errors in the manufacturing process, so they can be fixed or the misformed parts eliminated. One factor that may be important is the position and orientation of a part. (If it is misaligned when it goes into a machine, it may not be processed correctly and could end up breaking an expensive piece of equipment.) For your convenience, the equations used to compute information about a binary image are reproduced below:

ERRATUM: in the formula for theta above, the numerator should say 2b instead of b.

Recall that the formula for theta above locates a value where the second derivative is zero. This may be either the maximum or a minimum, so you should check the value of at the perpendicular as well, and add 90 degrees (pi/2 radians) if necessary. Once you have both values you can compute the elongation.

Creating M-files

An M-file is Matlab's version of the function. In Matlab, each global function must be put into its own separate file, identified with a .m suffix. Functions in Matlab tend to do more than in other languages like C. Each function can take multiple arguments as input, and produce multiple arguments as output. (We've already seen an example of using a function that returns multiple outputs: the size function, used in the first interpolation example above.)

You can create a new M-file using the File menu. Copy the program below into the editor window that opens up, and save it as BinaryStats.m.

% BinaryStats:  Compute statistics about a binary image mask
%
% Current outputs:
%   area:  the area of the mask, in pixels
%
% Usage: [area] = BinaryStats(mask)
 
function [area] = BinaryStats(mask)
 
area = sum(sum(mask ~= 0));

Notable points:

The example below shows how you would use this M-file. It is called twice with different arguments to get the areas of the mask foreground and background, respectively, following on the example used above.

>> mask = (lbl == 26);
>> BinaryStats(mask)
ans =
        8802
>> BinaryStats(~mask)
ans =
      110670
>> A = BinaryStats(mask);
>> A
A =
        8802

Exercises

I. Augment the BinaryStats function so that it computes the center of mass, elongation, and orientation of a binary image. Then use your function to compute those values for the masks of each of the three wrenches separately. You should avoid using the regionprops function for your solution to this problem, but you may use it to check your answers.

There are several ways you can implement the component analysis process, but you should be able to do it entirely without loops by using predefined Matlab functions and operators. (This is desirable because the built-in functions often run faster than custom loops.) All solutions to this problem will be accepted, but highest credit will go towards those that avoid loops. The following functions may be of use to you: meshgrid, sum, sqrt. Also, you may wish to use the .* and .^ operators, which perform componentwise (rather than matrix) operations.

You can check your function's result by plotting it on top of the image itself, using the plot function. The code below shows an example, assuming that the position of the part and its angle of orientation have been computed and stored in the variables x, y, and th, respectively. Note that the orientation line of each wrench will not lie exactly parallel with the shaft. (Why?) When you're done, you should turn in a printout of the original wrench image with the positions and orientations of each of the parts superimposed, plus the code of the M-file that you wrote.

>> % Assume that x and y already hold the position coordinates
>> % and th holds the angle of orientation.
>> imshow(mask)
>> hold on
>> plot(x,y,'o')
>> plot(x+[-50 50]*cos(th),y+[-50 50]*sin(th),'r-')

noisy Smith College II. This will give you a chance to try some morphology for yourself. The image at right is a text image that has been corrupted by noise. Your job is to restore it as much as possible to its original condition. Pick a suitable threshold to produce a binary image, then use a combination of morphological operations to reduce the noise and reconnect the letters. (In Matlab, opening and closing are the imclose and imopen functions. You can also use strel to create a structuring element. Start with elements that are circular masks inside square windows. You may, if you wish, experiment with asymmetric structuring elements.)

III. Another fun use of morphology is to get outline images. Using the wrench mask you created for the last assignment, dilate the mask slightly to get a new mask. Now subtract the first, and you have an outline image.

handwritten letters IV. Skeletonization is the reduction of a shape to a central spine, and is related to the erosion operator. You can think of a shape skeleton as the result of repeated erosion to single-pixel width. One issue with skeletonization is how to prune spines resulting from noise on the image boundary. You will test out two pruning methods. Download the image at right, and find an appropriate threshold to get a good binary image. Now suppose that you want to reduce this to a skeleton. The method Matlab provides uses a pruning method based upon spur length. The function bwmorph implements a number of morphological operations; sk1 = bwmorph(img,'skel',Inf) will give a skeletonization. Contrast this with the skeletonization produced by sk2 = (skelgrad(img) > 10), which implements pruning based upon the separation of the nearest edge points along the perimeter. (Note: skelgrad is not a builtin Matlab function; it has been compiled as a mex-file from C source code. The source code is in skelgrad.cpp. If you work in a science center computer lab, you should have access to skelgrad if the Matlab path includes N:/COURSES/CSC/CSC370. Otherwise, you will have to compile the source code using mex.)