local binary pattern with texture classification
So I tried to do local binary pattern and histogram comparison on my texture. I used the local binary program from here (https://github.com/bytefish/opencv/tr...) and tried to compare the histogram difference for two images, but for some reason the match is really high even when the texture differs a lot. I modified the main.cpp just a little bit so that I can get the histogram comparison value to show. Below is my code. As you can see the result turns out to be 94.48% match, so I would like to know what I am doing wrong so I can improve the result. I am using OLBP. The image below shows histogram and result. I would like to compare with histogram but not feature matching.
int main(int argc, const char *argv[]) {
int deviceId = 0;
if(argc > 1)
deviceId = atoi(argv[1]);
VideoCapture cap(deviceId);
if(!cap.isOpened()) {
cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
return -1;
}
// initial values
int radius = 1;
int neighbors = 8;
// windows
namedWindow("original",CV_WINDOW_AUTOSIZE);
namedWindow("lbp",CV_WINDOW_AUTOSIZE);
// matrices used
Mat test;
Mat test1;
Mat frame; // always references the last frame
Mat dst; // image after preprocessing
Mat dst1;
Mat lbp; // lbp image
Mat lbp1;
// just to switch between possible lbp operators
vector<string> lbp_names;
lbp_names.push_back("Extended LBP"); // 0
lbp_names.push_back("Fixed Sampling LBP"); // 1
lbp_names.push_back("Variance-based LBP"); // 2
int lbp_operator=1;
bool running=true;
while(running) {
//cap >> frame;
dst = imread("Hist1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale
dst1 = imread("Hist3.jpg", CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale
//cvtColor(frame, dst, CV_BGR2GRAY);
//GaussianBlur(test, dst, Size(7,7), 5, 3, BORDER_CONSTANT); // tiny bit of smoothing is always a good idea
//GaussianBlur(test1, dst1, Size(7,7), 5, 3, BORDER_CONSTANT); // tiny bit of smoothing is always a good idea
// comment the following lines for original size
//resize(frame, frame, Size(), 0.5, 0.5);
//resize(test,dst,Size(), 0.5, 0.5);
//
switch(lbp_operator) {
case 0:
lbp::ELBP(test, lbp, radius, neighbors); // use the extended operator
break;
case 1:
lbp::OLBP(dst, lbp); // use the original operator
lbp::OLBP(dst1, lbp1); // use the original operator
break;
case 2:
lbp::VARLBP(dst, lbp, radius, neighbors);
break;
}
// now to show the patterns a normalization is necessary
// a simple min-max norm will do the job...
normalize(lbp, lbp, 0, 255, NORM_MINMAX, CV_8UC1);
Mat lbp_hist, lbp1_hist;
int histSize[] = {256};
float s_ranges[] = { 0, 256 };
const float* ranges[] = { s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0 };
calcHist( &lbp, 1, channels, Mat(), lbp_hist, 1, histSize, ranges, true, false );
normalize( lbp1_hist, lbp1_hist, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &lbp1, 1, channels, Mat(), lbp1_hist, 1, histSize, ranges, true, false );
normalize( lbp_hist, lbp_hist, 0, 1, NORM_MINMAX, -1, Mat() );
double base_base = compareHist( lbp_hist, lbp1_hist, 0 );
printf("%f\n",base_base);
imshow("original", lbp);
imshow("lbp", lbp1);
char key = (char) waitKey(0);;
}
return 0; // success
}
the L in LBP stands for LOCAL. what you've got so far, is a global binary pattern image.
you're supposed to chop that up into NxN grid patches (e.g. N=8), calculate histograms on each of them seperately, and later concatatenate those to a large 1d feature vector. see here
(oh, and by the way, try to experiment with different comparison types. to my findings, HISTCMP_HELLINGER works best, HISTCMP_CORREL(what yo're using now) worst !)
I found out I misplaced lbp1 in my normalized function. I am using Kullback-Leibler divergence suggested here (http://xy-27.pythonxy.googlecode.com/...). I will take a look at spatial_histogram, thanks for the lead.
i somehow doubt, that kl-divergence will work better. maybe report back your findings ?
10 fold crossvalidation on lfw-deepfunneled:
I followed Python code to calculate ELBP and set the radius to 2 with 16 neighborhood which gives a pretty good answer for Kullback-Leibler distance (same image as 0). But using Hellinger with this parameter does not seem to work well.
ah, ok. seems like a 2^16 feature vector plays nicer with this kind of distance (but usually you can't allow for gargantuan features like this.)
interesting result anyway, thanks for reporting back !
I am interested with your code PLEASE send me full code because when I run it , the Images after LBP just appears with me