Tuesday, August 25, 2009

Activity 14 - Pattern Recognition

The main objective of this activity is to classify various objects with different characteristics through pattern recognition.

In pattern recognition, the characteristics of an object belonging to a type or class are called features. These are quantified which may be the object's area, color, and many others. Pattern is then a set of features and a class is a set of patterns which share common features. The task is thus finding the features of an unknown object belonging to one of the several classes.

There are 3 classes assembled in this activity. They are all edible which include Snacku rice crackers, Superthin biscuits, and Nova multigrain snack. Each class is composed of 10 samples. The setup is shown below.


The 30 samples are grouped according to their respective classes for simplified image processing. Each class is divided into two, 5 samples serve as the training set and the other 5 correspond to the test set. Features that have been decided to use for pattern recognition are the sample's pixel area, average normalized chromaticity values in red, green, and blue for a total of 4.
The pixel area is attained by binarizing and inverting the cropped image of a class using the most appropriate predetermined threshold value. The funciton bwlabel of Scilab is then implemented to sum up the white pixels of each cluster equivalent to the pixel area of a sample and this is similar to the algorithm in Activity 9.
Meanwhile, parametric segmentation in Activity 12 is employed to get the normalized chromaticity values in red, green, and blue of each sample. This is operated through cropped individual sample images of each class. Note that the normalized chromaticity values in red, green, and blue are ensured that these just came from the samples (not with the background) by extracting the pixel coordinates of the segmented images.
Next, quantified features are ordered into a matrix called feature vector. Hence, in this case, a sample's feature vector consists 4 elements. Mean feature vectors representing each class are then obtained using the following equation.



Here, N_j is the total number number of samples in a class w_j which is here, equal to 5 while the 1 x 4 matrix x_j is composed of all 4 feature vectors acquired from image processing and then this is summed for N_j samples. Through minimum distance classification stated by the following expression, the features of each sample in the test set is then compared to the matrix of mean features m_j in the training set.




From the expressions above, x is the feature vector of a test sample, W is the total number of class and T is the transpose matrix operation. The class index j of the minimum distance D_j(x) is then assigned to the Nth sample from the test set of a class.

The results from the training set are shown in the table below (click the table for larger view).


Finally, the resulting classification of the test set is summarized in the following table (click the table for larger view).


It can be observed that the calculated distance D_j(x) is relatively large when a test sample does not match the expected class. Notice that the distances are big numbers because recall that the quantified feature pixel area is relatively larger than the normalized chromaticity values. But most importantly, all 15 samples in the test set are classified correctly.

Since I have understood the process of pattern recognition using the minimum distance classification and at the same time, successfully classifying all the samples in the test set, I grade myself 10/10 in this activity.

I have successfully completed this activity through discussions with Gary.

Appendix
The whole Scilab code below is utilized in this activity.

stacksize(4e7);

//snacku = gray_imread('snacku.jpg');

//scf(0);
//imshow(snacku);
//imwrite(snacku, 'gray snacku.bmp');

snack_A = [];
for a = 1:3
snack = gray_imread('gray snack'+string(a)+'.bmp');

if a == 1
snack = im2bw(snack, 175/255);
elseif a == 2
snack = im2bw(snack, 160/255);
else
snack = im2bw(snack, 155/255);
end

snack = 1 - snack;

//scf(a);
//imshow(snack);

[L, n] = bwlabel(snack);

A = [];
for i = 1:n
b = (L == i);
A(i) = sum(b);
snack_A(i, a) = A(i);
end

end

snacku_A = snack_A(:,1);
superthin_A = snack_A(:,2);
nova_A = snack_A(:,3);

training_snack_A = [snacku_A(1:5), superthin_A(1:5), nova_A(1:5)];
test_snack_A = [snacku_A(6:10), superthin_A(6:10), nova_A(6:10)];

// Average Normalized RGB Values

mean_snacku_r = [];
mean_snacku_g = [];
mean_snacku_b = [];
for j = 1:10
image = imread('snacku'+string(j)+'.jpg');
I = imread('snacku ROI.jpg');

R = I(:,:,1);
G = I(:,:,2);
B = I(:,:,3);

RGB = R + G + B;

r = R./RGB;
b = B./RGB;
g = G./RGB;

Ri = image(:,:,1);
Gi = image(:,:,2);
Bi = image(:,:,3);

RGBi = Ri + Gi + Bi;

ri = Ri./RGBi;
bi = Bi./RGBi;
gi = Gi./RGBi;

// Parametric Segmentation

rmean = mean(r);
gmean = mean(g);
rsigma = stdev(r);
gsigma = stdev(g);

rp = (1/(rsigma*sqrt(2*%pi)))*exp(-((ri - rmean).^2)/(2*rsigma^2));
gp = (1/(gsigma*sqrt(2*%pi)))*exp(-((gi - gmean).^2)/(2*gsigma^2));

rgp = round(rp.*gp);

//scf(j + 3);
//imshow(rgp);

[x, y] = find(rgp ~= 0);

snacku_r = [];
snacku_g = [];
snacku_b = [];
for k = 1:length(x)
snacku_r = [snacku_r, ri(x(k), y(k))];
snacku_g = [snacku_g, gi(x(k), y(k))];
snacku_b = [snacku_b, bi(x(k), y(k))];
end

mean_snacku_r(j,:) = mean(snacku_r);
mean_snacku_g(j,:) = mean(snacku_g);
mean_snacku_b(j,:) = mean(snacku_b);

end

training_mean_snacku_r = mean_snacku_r(1:5);
training_mean_snacku_g = mean_snacku_g(1:5);
training_mean_snacku_b = mean_snacku_b(1:5);
training_color_snacku = [mean(training_mean_snacku_r), mean(training_mean_snacku_g), mean(training_mean_snacku_b)];
//fprintfMat('training_color_snack1.txt', training_color_snacku);

test_mean_snacku_r = mean_snacku_r(6:10);
test_mean_snacku_g = mean_snacku_g(6:10);
test_mean_snacku_b = mean_snacku_b(6:10);
test_color_snacku = [test_mean_snacku_r, test_mean_snacku_g, test_mean_snacku_b];
//fprintfMat('test_color_snack1.txt', test_color_snacku);

// Test Object Classification

D_test_snack = [];
for l = 1:3
for m = 1:3
training_color_snack = fscanfMat('training_color_snack'+string(l)+'.txt');
m_snack = [mean(training_snack_A(:,l)), training_color_snack];

test_color_snack = fscanfMat('test_color_snack'+string(m)+'.txt');

for n = 1:5
x_snack = [test_snack_A(n, m), test_color_snack(n, 1), test_color_snack(n, 2), test_color_snack(n, 3)];
D_test = [x_snack - m_snack];
D_test_snack = [D_test_snack; sqrt(D_test*D_test')];
end

end

end

D_test_snacku = D_test_snack(1:15);
D_test_superthin = D_test_snack(16:30);
D_test_nova = D_test_snack(31:45);

D = [D_test_snacku, D_test_superthin, D_test_nova];

class = [];
for o = 1:15
[a, b] = find(D(o,:) == min(D(o,:)));
class = [class; b];
end

No comments:

Post a Comment