well, maybe it even works with lbp histograms, the procedure would work like this:
- gather a lot of (grayscale) train images for each case.
- make an lbp histogram for each image, and add this histogram, and a label (agglutinated or not) to the training dataset.
- setup a classifier with this data. compareHist() is used with 1-nearest-neighbour classification below.
- 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 ...
(more)
yup, I am looking to determine blood group.I am looking for whether the image is agglutinated or not you can see that reference image and test2 image are agglutinated while test1 image is not I want to see whether the image is agglutinated or not. if there is a better alternative than classifier that will also work I hope you got what I am looking for in an image. and thanks berak :)