This is my third post for local binary pattern. I've gotten the scikit-image code to work here (http://scikit-image.org/docs/dev/auto_examples/plot_local_binary_pattern.html), but I would like to transport my result to Opencv. The scikit-image code does a histogram like this, hist, _ = np.histogram(lbp, normed=True, bins=n_bins, range=(0, n_bins)) with lbp being the lbp image, and n_bins being n_bins = lbp.max() + 1 which I checked is 18.0. They also have it normalized. This is using Numpy histogram with radius 2 and neighbor 16. Now I do the same thing with Opencv cv::calcHist( &lbp, 1, channels, Mat(), lbp_hist, 1, histSize, ranges, true, false ); with lbp being the lbp image for radius 2 and neighbor 16, except I change the histsize and ranges to 256. I believe this should be the same as Numpy Histogram. The problem is when I try to normalize the Opencv histogram with the normalize function normalize(lbp_hist, lbp_hist, 0, 1, NORM_MINMAX, -1, Mat() ); from 0 to 1. And then do a compare histogram with Kullback-Leibler double base_base = compareHist( lbp_hist, lbp1_hist, CV_COMP_KL_DIV );, I still get negative values sometimes. So my question is, how do I normalize the histogram correctly in range with radius 2 and neighbor 16? Below is my code.
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "lbp.hpp"
#include "histogram.hpp"
using namespace cv;
int main(int argc, const char *argv[]) {
// initial values
int radius = 2;
int neighbors = radius*8;
// 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;
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 };
dst = imread("B10.png", 1); //Load as grayscale
cvtColor(dst, dst, CV_BGR2GRAY);
lbp::ELBP(dst, lbp, 2, 16); // use the extended operator
lbp.convertTo(lbp, CV_32FC1);
imshow("lbp", lbp);
waitKey(0);
cv::calcHist( &lbp, 1, channels, Mat(), lbp_hist, 1, histSize, ranges, true, false );
normalize(lbp_hist, lbp_hist, 0, 1, NORM_MINMAX, -1, Mat() );
show_histogram("lbp_h", lbp);
waitKey(0);
int lbp_operator=1;
for (int i=1; i<31; i++) {
dst1 = imread("B" + to_string(i) +".png", 1); //Load as grayscale
cvtColor(dst1, dst1, CV_BGR2GRAY);
lbp::ELBP(dst1, lbp1, 2, 16); // use the original operator
lbp1.convertTo(lbp1, CV_32FC1);
cv::calcHist( &lbp1, 1, channels, Mat(), lbp1_hist, 1, histSize, ranges, true, false );
normalize(lbp1_hist, lbp1_hist, 0, 1, NORM_MINMAX, -1, Mat() );
double base_base = compareHist( lbp_hist, lbp1_hist, CV_COMP_KL_DIV );
printf("%f is %d\n",base_base,i);
}
system("pause");
return 0; // success
}