How to create a LBP histogram using OpenCV?

asked 2014-08-06 21:08:20 -0500

Uzzal gravatar image

updated 2014-08-06 23:45:04 -0500

berak gravatar image

I want to create a lbp histogram in OpenCV for a picture. Is there any change to create a lbp histogram? Hope for Help..

 #include "histogram.hpp"
 #include <vector>

template <typename _Tp>
void lbp::histogram_(const Mat& src, Mat& hist, int numPatterns) {
    hist = Mat::zeros(1, numPatterns, CV_32SC1);
    for(int i = 0; i < src.rows; i++) {
        for(int j = 0; j < src.cols; j++) {
            int bin = src.at<_Tp>(i,j);
            hist.at<int>(0,bin) += 1;
        }
    }
}

template <typename _Tp>
double lbp::chi_square_(const Mat& histogram0, const Mat& histogram1) {
    if(histogram0.type() != histogram1.type())
            CV_Error(CV_StsBadArg, "Histograms must be of equal type.");
    if(histogram0.rows != 1 || histogram0.rows != histogram1.rows || histogram0.cols != histogram1.cols)
            CV_Error(CV_StsBadArg, "Histograms must be of equal dimension.");
    double result = 0.0;
    for(int i=0; i < histogram0.cols; i++) {
        double a = histogram0.at<_Tp>(0,i) - histogram1.at<_Tp>(0,i);
        double b = histogram0.at<_Tp>(0,i) + histogram1.at<_Tp>(0,i);
        if(abs(b) > numeric_limits<double>::epsilon()) {
            result+=(a*a)/b;
        }
    }
    return result;
}


void lbp::spatial_histogram(const Mat& src, Mat& hist, int numPatterns, const Size& window, int overlap) {
    int width = src.cols;
    int height = src.rows;
    vector<Mat> histograms;
    for(int x=0; x < width - window.width; x+=(window.width-overlap)) {
        for(int y=0; y < height-window.height; y+=(window.height-overlap)) {
            Mat cell = Mat(src, Rect(x,y,window.width, window.height));
            histograms.push_back(histogram(cell, numPatterns));
        }
    }
    hist.create(1, histograms.size()*numPatterns, CV_32SC1);
    // i know this is a bit lame now... feel free to make this a bit more efficient...
    for(int histIdx=0; histIdx < histograms.size(); histIdx++) {
        for(int valIdx = 0; valIdx < numPatterns; valIdx++) {
            int y = histIdx*numPatterns+valIdx;
            hist.at<int>(0,y) = histograms[histIdx].at<int>(valIdx);
        }
    }
}

// wrappers
void lbp::histogram(const Mat& src, Mat& hist, int numPatterns) {
    switch(src.type()) {
        case CV_8SC1: histogram_<char>(src, hist, numPatterns); break;
        case CV_8UC1: histogram_<unsigned char>(src, hist, numPatterns); break;
        case CV_16SC1: histogram_<short>(src, hist, numPatterns); break;
        case CV_16UC1: histogram_<unsigned short>(src, hist, numPatterns); break;
        case CV_32SC1: histogram_<int>(src, hist, numPatterns); break;
    }
}

double lbp::chi_square(const Mat& histogram0, const Mat& histogram1) {
    switch(histogram0.type()) {
        case CV_8SC1: return chi_square_<char>(histogram0,histogram1); break;
        case CV_8UC1: return chi_square_<unsigned char>(histogram0,histogram1); break;
        case CV_16SC1: return chi_square_<short>(histogram0, histogram1); break;
        case CV_16UC1: return chi_square_<unsigned short>(histogram0,histogram1); break;
        case CV_32SC1: return chi_square_<int>(histogram0,histogram1); break;
    }
}

void lbp::spatial_histogram(const Mat& src, Mat& dst, int numPatterns, int gridx, int gridy, int overlap) {
    int width = static_cast<int>(floor(src.cols/gridx));
    int height = static_cast<int>(floor(src.rows / gridy));
    spatial_histogram(src, dst, numPatterns, Size_<int>(width, height), overlap);
}

// Mat return type functions
Mat lbp::histogram(const Mat& src, int numPatterns) {
    Mat hist;
    histogram(src, hist, numPatterns);
    return hist;
}


Mat lbp::spatial_histogram(const Mat& src, int numPatterns, const Size& window, int overlap) {
    Mat hist;
    spatial_histogram(src, hist, numPatterns, window, overlap);
    return hist;
}


Mat lbp::spatial_histogram(const Mat& src, int numPatterns, int gridx, int gridy, int overlap) {
    Mat hist;
    spatial_histogram(src, hist ...
(more)
edit retag flag offensive close merge delete

Comments

you forgot to mention the problem

berak gravatar imageberak ( 2014-08-06 23:44:26 -0500 )edit

I want to create a lbp histogram

Uzzal gravatar imageUzzal ( 2014-08-07 01:37:48 -0500 )edit
1

if you give an lbp image to your histogram function, you'll receive an lbp-histogram.

again, what exactly is the problem ?

berak gravatar imageberak ( 2014-08-07 01:40:33 -0500 )edit

Your message is very unclear. If you have all this code for creating an LBP histogram, then why you are asking us to explain how to do it? This seems like a 'hey i got a project, i copied someones code, now i cannot run it, help me' - problem... If so, then please indicate so that I can point you to the forum guidelines...

StevenPuttemans gravatar imageStevenPuttemans ( 2014-08-07 06:44:33 -0500 )edit

Also, start reading here this is made by the guy who implemented the face recognizer module that uses LBP histograms internally. We should try to make that function public.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-08-07 06:46:57 -0500 )edit

And to add something extra, I am checking if it is possible to expose the LBPFaceRecognizers histogram attribute which shouldn't be that hard. I will keep you posted of progress.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-08-07 07:05:38 -0500 )edit
1

Hmm it seems no that easy ... tried adding another getter, but it seems I cannot get the default values back ...

StevenPuttemans gravatar imageStevenPuttemans ( 2014-08-07 07:26:55 -0500 )edit

@berak, this line of code makes sure you could retrieve parameters right? Since they are public. Do you know why this doesn't work then?

 Ptr&lt;FaceRecognizer&gt; model =  createLBPHFaceRecognizer();
 model-&gt;train(images, labels);
 const int test = model-&gt;radius();

which should return the default value of 1

StevenPuttemans gravatar imageStevenPuttemans ( 2014-08-07 07:33:10 -0500 )edit