Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

well, maybe it even works with lbp histograms, the procedure would work like this:

  1. gather a lot of (grayscale) train images for each case.
  2. make an lbp histogram for each image, and add this histogram, and a label (agglutinated or not) to the training dataset.
  3. setup a classifier with this data. compareHist() is used with 1-nearest-neighbour classification below.
  4. then, later, you can predict agglutination on an image, 1st take the histogram again, then feed it to the classifier for prediction.

here's some code:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

//
// if you squint hard, you'll see the close similarity to opencv's face recognition code ;)
//
void lbp_hist(const Mat &I, Mat &histogram)
{
    Mat_<uchar> img(I);
    Mat_<float> hist(1, 256, 0.0f);
    const int m=1;
    for (int r=m; r<img.rows-m; r++)
    {
        for (int c=m; c<img.cols-m; c++)
        {
            uchar v = 0;
            uchar cen = img(r,c);
            v |= (img(r-1,c  ) > cen) << 0;
            v |= (img(r-1,c+1) > cen) << 1;
            v |= (img(r  ,c+1) > cen) << 2;
            v |= (img(r+1,c+1) > cen) << 3;
            v |= (img(r+1,c  ) > cen) << 4;
            v |= (img(r+1,c-1) > cen) << 5;
            v |= (img(r  ,c-1) > cen) << 6;
            v |= (img(r-1,c-1) > cen) << 7;
            hist(v) ++;
        }
    }
    histogram = hist;
}

struct Classifier
{
    vector<Mat> histograms;
    vector<int> labels;

    Classifier( vector<Mat> &histograms, vector<int> &labels)
        : histograms(histograms)
        , labels(labels)
    {} // nothing else to do

    // nearest neighbour distance:
    int predict(const Mat &histogram)
    {
        double minDist=DBL_MAX;
        int minLabel = -1;
        for (size_t i=0; i<histograms.size(); i++)
        {
            // i tried a few, and CHISQR_ALT seemed best.
            double d = compareHist(histogram, histograms[i], HISTCMP_CHISQR_ALT);
            if (d < minDist)
            {
                minDist = d;
                minLabel = labels[i];
            }
        }
        return minLabel;
    }
};

int main() 
{
    Mat ref = imread("agref.jpg",1);
    Mat a1 = imread("ag1.jpg",1);
    Mat a2 = imread("ag2.jpg",1);
    // make histograms
    Mat h1,h2,h3;
    lbp_hist(ref,h1);
    lbp_hist(a1,h2);
    lbp_hist(a2,h3);
    // since we only got a few images(you need **lots* more!!)
    // augment our train data by simply flipping the existing images:
    Mat f1;  flip(ref,f1,0); // x-axis
    Mat f2;  flip(a1,f2,0);
    Mat f3;  flip(a2,f3,0);
    Mat h4,h5,h6;
    lbp_hist(f1,h4);
    lbp_hist(f2,h5);
    lbp_hist(f3,h6);

    // setup data for classifying:
    // (a histogram, and a label for each img)
    vector<Mat> hists;
    vector<int> labels; // 1==agglutinated, 0==not.
    // ref
    hists.push_back(h1); labels.push_back(0);
    hists.push_back(h4); labels.push_back(0);
    // agglutinated:
    hists.push_back(h2); labels.push_back(1);
    hists.push_back(h3); labels.push_back(1);
    hists.push_back(h5); labels.push_back(1);
    hists.push_back(h6); labels.push_back(1);

    // "train" the classifier:
    Classifier cls(hists, labels);

    // flip images for testing, so they again look a bit different:
    // (again, this is only for the demo)
    Mat f7;  flip(ref,f7,1); // y-axis
    Mat f8;  flip(a1,f8,1);
    Mat f9;  flip(a2,f9,1);
    Mat h7,h8,h9;
    lbp_hist(f7,h7);
    lbp_hist(f8,h8);
    lbp_hist(f9,h9);

    int p1 = cls.predict(h7); // ref
    int p2 = cls.predict(h8); // agg.
    int p3 = cls.predict(h9); // agg.

    cerr << p1 << " " << p2 << " " << p3 << endl;
    return 0;
}


output:
0 1 1