1 | initial version |
well, maybe it even works with lbp histograms, the procedure would work like this:
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