Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

how to normalize local binary pattern for kullback leibler?

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
}

how to normalize local binary pattern for kullback leibler?

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.

P.S. I found out it has something to do with the conversion from CV_32SC1 to CV_32FC1 to CV_8UC1. But still get negative values.

#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);
    normalize(lbp, lbp, 0, 255, NORM_MINMAX);

    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);

        normalize(lbp1, lbp1, 0, 255, NORM_MINMAX);

        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
}