Feature Extraction from Binary Images*

A picture tells a thousand words. That’s cliche but that is true. In some cases, that is good, but for some purposes, especially in computer vision, it’s undesirable. You see, the information contained in an image is too large that a dumb computer (and a lazy programmer) would find it hard to process them efficiently. In order to lessen the information to its bare essentials, an image undergoes a process called feature extraction.

Consider the image below taken from www.cs.uwa.edu.au/undergraduate/units/CITS4240/Images/. The first step is to convert the image into a binary image. This involves finding a suitable threshold for the image. Since the SIP toolbox does not have an equivalent of graythresh() yet, I used that function in Matlab which yielded a value of 0.4510. Using that value for the threshold, I converted the grayscale image into binary using imgbw = 1*(img < = 0.4510); . The boolean operation img < = 0.4510 needs to be multiplied by 1 because in Scilab, true values are stored as %T and not 1. The binary image is shown below. Note that many of the light-colored objects are not visible due to the choice of threshold.

Using the sequential-labelling algorithm, implemented in SIP through bwlabel(), the pixels representing each object were identified. The objects, colored differently for each, are shown below. From a binary image, several information can be derived from an object’s shape. Examples of these are area, centroid and angle. The following is a listing of a Scilab function that returns the aforementioned examples. This assumes that the input binary image contains one object only.

function [area, centroid, theta] = moments(I)
// Function calculates the moments of a binary image (I) and returns the
// area and the centroid. The function assumes that there is only one object
// in the binary image.
//
// function [area, centroid, theta] = moments(I)
//
// Argument: im - a binary image containing values of 0 or 1
//
// Returns: area - the area of the binary image
// centroid - a 2 element vector
// theta - object orientation, in radians
//
// The function also displays the image and overlays the position of
// the centroid. The area and theta computed
// by the function should be displayed as the title of the image.

[m, n] = find(I==1);
area = size(m,2); //count number of pixels within threshold
centroid(1) = sum(m')/area;
centroid(2) = sum(n')/area;

mu11 = sum(m' .* n') - area*centroid(1)*centroid(2);
mu20 = sum(m' .* m') - area*centroid(1)*centroid(1);
if mu20 == mu02
theta = %inf;
else
theta = 0.5 * atan((2*mu11) / (mu20 - mu02));
end;

f = scf();
img = I + 1;
img(int(centroid(1)), int(centroid(2))) = 3;
imshow(img, []);
f.figure_name = 'area = '+string(area)+'; angle = '+string(theta);
endfunction

The function was tested using the test images below. The computed values were the same as the ground truth values.   area = 341 pixels centroid = (25,45) theta = 0 area = 341 pixels centroid = (45,25) theta = Inf area = 10000 pixels centroid = (50.5,50.5) theta = 0.5082634

The following are the results when the moments function is applied to some of the objects in the image.   area = 1307 pixels centroid = (76.8,395.9) theta = 0.5082634 area = 886 pixels centroid = (55.7,336.6) theta = -0.3683659 area = 1868 pixels centroid = (87.1, 263.3) theta = -0.5441308