Tuesday, June 28, 2011

Nearest Neighbor Classification using Color Histograms as features

Was able to get the K-Nearest Neighbor classifier running today and the results are better than I expected.
Skip down to view results.

Took about half a day debugging and trying to understand OpenCV's new structures as most of the example code online uses deprecated OpenCV structures.

Problems encountered:
The machine learning model in OpenCV takes a very specific format for the feature vectors, so it took some time concatenating everything together into one big matrix. Basically it was a pain using the cv::Mat structure because documentation is spread out across their older deprecated structures like cvMat and sample code online uses mostly the older structs.
Set elements:
Mat A;
A.at<type>(i,j) = ...

Set rows:
Mat A;
Mat Ai = A.row(i);
otherRow.copyTo(Ai);

In the future, I would recommend using MATLAB for ANY Matrix handling as it is a hassle in OpenCV, but I don't think I want to spend my time stitching MATLAB and C++ together right now.

Results:
First I split the data set in half into training and testing sets.
Then, I extracted the 2-D histogram features (Hue & Saturation) as documented in my last post, and pass them and the truth labels into the cv::kNearest classifier.



Here are the pictures of a single candidate from each species for reference:


























I decided to test the classifier with only the first two classes at first, and it received 100% accuracy!
I used the following parameters:
number of hue bins: 30
number of saturation bins: 32
k for k-nearest: 1 (nearest neighbor)

After adding one class at a time and re-running the classifier, accuracy was still quite high for the first four classes, about ~90%.

Then the accuracy started to drop to about 75% after a few more classes were added, and after adding in all 11 classes it is now at 67% (138/204).
I tried varying the parameters, but it didn't make much difference.

Here is the confusion matrix representing the final classifier results for today:
A confusion matrix shows the number of samples that were predicted to be X, but were actually Y.
Ideally, we want the numbers to be as high across the diagonal of the matrix as possible.
x-axis represents predicted label, and y-axis represents actual label.

       0  1  2  3  4  5  6  7  8  9  10        

0 |  [8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
1 |   0, 26, 0, 1, 0, 0, 2, 0, 1, 1, 0;
2 |   0, 2, 19, 0, 0, 0, 0, 0, 4, 0, 2;
3 |   0, 4, 0, 16, 0, 0, 1, 0, 0, 1, 0;
4 |   0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 0;
5 |   0, 1, 5, 0, 1, 4, 0, 0, 0, 0, 2;
6 |   0, 4, 0, 0, 0, 0, 2, 0, 4, 1, 0;
7 |   0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0;
8 |   0, 0, 5, 0, 0, 0, 0, 0, 13, 0, 0;
9 |   0, 5, 0, 3, 0, 0, 0, 0, 0, 16, 0;
10|  0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 17]

Take note that classes 4, 5, and 6 had the most number of incorrectly identified samples. Class 4 had no correctly identified samples. At a quick glance, it looks to me as though all their colors are dull, and perhaps the reason why the classifier does a poor job of distinguishing them.

Notes:
Things to try out later:


  • vary number of bins for hue and saturation
  • vary k value for kNearest classifier
  • remove images that contain knife blade such as:
    Since I'm not sure how to segment it out yet.
  • Produce graphs of data clusters
  • Produce graphs of performance when varying parameters
On the Computer Vision side of things... I think I will need to begin looking into re-orienting the insects so they all face the same direction, edge detection/contour detection, and maybe using hough transforms to detect lines/circles.

2 comments:

  1. Can i use it for object classification problem?

    ReplyDelete
  2. Hello Romeo, What kind of objects are you looking to classify?

    ReplyDelete