Ask Your Question
1

How to train Local Binary Patterns to SVM

asked 2016-04-16 18:46:20 -0600

sirflippy gravatar image

updated 2016-04-17 07:21:37 -0600

 public: cv::Mat LBP(Mat pic1){
        bool affiche = true;
        Mat Image(pic1.rows, pic1.cols, CV_8UC1), lbp(pic1.rows, pic1.cols, CV_8UC1);
        cvtColor(pic1, Image, CV_BGR2GRAY);
        unsigned center = 0, center_lbp = 0;
        Mat H(1, 256, CV_32FC1, Scalar::all(0));
        for (int row = 1; row < Image.rows - 1; row++)
        {
            for (int col = 1; col < Image.cols - 1; col++)
            {
                center = Image.at<float>(row, col);
                center_lbp = 0;
                if (center <= Image.at<float>(row - 1, col - 1))
                    center_lbp += 1;
                if (center <= Image.at<float>(row - 1, col))
                    center_lbp += 2;
                if (center <= Image.at<float>(row - 1, col + 1))
                    center_lbp += 4;
                if (center <= Image.at<float>(row, col - 1))
                    center_lbp += 8;
                if (center <= Image.at<float>(row, col + 1))
                    center_lbp += 16;
                if (center <= Image.at<float>(row + 1, col - 1))
                    center_lbp += 32;
                if (center <= Image.at<float>(row + 1, col))
                    center_lbp += 64;
                if (center <= Image.at<float>(row + 1, col + 1))
                    center_lbp += 128;
                lbp.at<float>(row, col) = center_lbp;
                H.at<float>(center_lbp) += 1;
            }
        }
        normalize(H, H, 0, 1, NORM_MINMAX, -1, Mat());
        textureData.push_back(H);
        return H;
    }

I am a beginner in openCV. The code above is inside a function that should return the finished training data. My problem is that I don't know how to get the numbers inside H and how to create the training data for the SVM. Can somebody help me with this?

edit retag flag offensive close merge delete

Comments

  • what are you trying to do with it ? (your "use case")
  • H.at<uchar>(center_lbp) += 1; should only appear once (at the end)
  • your histogram should be float type, not uchar (else the normalization will wreck it)
  • which opencv version is it ?
  • if (pic1.channels() == 3) <-- you need an else case here, or Image won't be initialized
berak gravatar imageberak ( 2016-04-17 02:51:26 -0600 )edit
1
  1. I am trying to make a classifier that will classify images with similar patterns, like grass and stones.
  2. Done
  3. I changed it to float and it won't run
  4. 3.0.0
  5. Done
sirflippy gravatar imagesirflippy ( 2016-04-17 06:18:17 -0600 )edit

3: you will need to change:

Mat H(1, 256, CV_32FC1, Scalar::all(0));

and:

H.at<float>(center_lbp) += 1;
berak gravatar imageberak ( 2016-04-17 06:33:25 -0600 )edit

It triggered a breakpoint at normalize();

sirflippy gravatar imagesirflippy ( 2016-04-17 06:40:50 -0600 )edit

could you update your code ?

berak gravatar imageberak ( 2016-04-17 07:06:44 -0600 )edit
1

^^^updated

sirflippy gravatar imagesirflippy ( 2016-04-17 07:22:17 -0600 )edit

your histogram is float, but your Image is still uchar, so: Image.at<uchar> .

please try to use a debug build, cases like this should trigger an exception.

berak gravatar imageberak ( 2016-04-17 07:47:42 -0600 )edit

"I don't know how to get the numbers inside H" -- you can just print it out:

cerr << H << endl;
berak gravatar imageberak ( 2016-04-17 08:18:59 -0600 )edit

I have a problem. Using CV_32FC1 does not output an array inside H that looks like [0,1,0,1,0,0,1......] while using CV_8UC1 outputs the right array but will return a SEHException at svm->train().

sirflippy gravatar imagesirflippy ( 2016-04-17 21:43:07 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-04-17 06:31:31 -0600

berak gravatar image

ok, now you can setup your machine learning:

we need each feature on a row, and a resp. label:

Mat trainData; // initially empty.
Mat trainLabels;
for each img
{

    // calculate lbp histo:
    Mat histogram = ....
    trainData.push_back(histogram);         
    trainLabel.push_back(1); // e.g. stone=1, grass=2, etc.

}

Ptr<ml::SVM> svm = ml::SVM::create();
svm->setKernel(ml::SVM::LINEAR); //maybe, here's where the real work starts !

svm->train(trainData, ml::ROW_DATA, trainLabels);

later, predict:

Mat histogram = ...
int label = (int)svm->predict(histogram);
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-04-16 18:46:20 -0600

Seen: 2,508 times

Last updated: Apr 17 '16