Ask Your Question
1

How to start with neural network implementation with Opencv and C++??

asked 2016-12-16 02:55:48 -0600

KirtiSwagat gravatar image

updated 2016-12-16 02:57:18 -0600

I want to train for face Recognition Problem. I want to test it with Neural Network and want to compare it with the result obtained from PCA+SVM.

Problem is some how like this:-

  1. 4 persons . I have to train the NN with 6 sample images for each person.
  2. Each person's having 40 images. I have to cross check for recognition.
  3. Output should be respective class no or name. But for new person output should be another class/ new person.

As I am new to this NN. Please provide me some link or Sample Code. So that I can start with it..

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
4

answered 2016-12-16 03:27:31 -0600

berak gravatar image

updated 2016-12-16 06:04:40 -0600

  1. it will get better with more images (and more persons, too)
  2. yes, cross-checking is a good idea. but rather split off 0-10 for testing, and use the remaining 30 for training, then repeat with 10-20, and so on, so every image was used once in the validation set (x-fold cross validation)
  3. though you can re-train an already trained network with new data, it's probably a better idea to start from scratch, else you might bias it too much in favour of the last seen data


i could not help it, and had to try the new BIF feature (a gabor-filterbank) here, so if you want to give it a go, uncomment some lines. with plain 80x80 images we get:

[6400 x 80] [10 x 80]
accuracy: 0.98

BIF gets us:

[9486 x 80] [10 x 80]
accuracy: 1

good luck, and happy coding ;)

#include <opencv2/opencv.hpp> 

// uncomment, if you want to use BIF (opencv_contrib, 3.1)
//#include "opencv2/face/bif.hpp"

#include <iostream>
using namespace cv;
using namespace std;

void train_test(int nclasses, const Mat &train_data, const Mat &train_labels, 
                              const Mat &test_data, const Mat &test_labels, Mat &confusion) {
    // setup the ann:
    int nfeatures = train_data.cols;
    Ptr<ml::ANN_MLP> ann = ml::ANN_MLP::create();
    Mat_<int> layers(4,1);
    layers(0) = nfeatures;     // input
    layers(1) = nclasses * 8;  // hidden
    layers(2) = nclasses * 4;  // hidden
    layers(3) = nclasses;      // output, 1 pin per class.
    ann->setLayerSizes(layers);
    ann->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM,0,0);
    ann->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 300, 0.0001));
    ann->setTrainMethod(ml::ANN_MLP::BACKPROP, 0.0001);

    // ann requires "one-hot" encoding of class labels:
    Mat train_classes = Mat::zeros(train_data.rows, nclasses, CV_32FC1);
    for(int i=0; i<train_classes.rows; i++)
    {
        train_classes.at<float>(i, train_labels.at<int>(i)) = 1.f;
    }
    cerr << train_data.size() << " " << train_classes.size() << endl;

    ann->train(train_data, ml::ROW_SAMPLE, train_classes);

    // run tests on validation set:
    for(int i=0; i<test_data.rows; i++) {
        int pred  = ann->predict(test_data.row(i), noArray());
        int truth = test_labels.at<int>(i);
        confusion.at<int>(pred, truth) ++;
    }
    Mat correct = confusion.diag();
    float accuracy = sum(correct)[0] / sum(confusion)[0];
    cerr << "accuracy: " << accuracy << endl;
    cerr << "confusion:\n" << confusion << endl;
}

int main(int argc, char** argv) {
    int rot = 4; // BIF
    int bands = 6; //BIF
    int nclasses = 10; // of 40, i only got 2gb mem ..
    String att = "c:/data/faces/att/"; //40 persons a 10 images
    vector<String> fn;
    glob(att,fn,true);

    Mat confusion(nclasses,nclasses,CV_32S, Scalar(0)); // will hold our test results

    // uncomment, if you want BIF !
    //Ptr<cv::face::BIF> bif = cv::face::createBIF(rot,bands);

    int off = 0;
    int split = 2;
    for (int f=0; f<5; f++) { // folds
        cerr << "fold " << f << endl;
        Mat train_data,train_labels, test_data,test_labels;
        for (int p=0; p<nclasses; p++) { // persons
            cerr << "p " << p << "\r";
            for (int i=0; i<10; i++) {
                int k = p * 10 + i + 1; // att image index starts from 1
                cv::Mat image = cv::imread(fn[k], 0);
                if (image.empty()) {cerr << "no !" << fn[k] << endl; continue; }

                image.convertTo(image, CV_32F ...
(more)
edit flag offensive delete link more

Comments

1

@berak Thank you for your suggestion.. Waiting for some sample code.

KirtiSwagat gravatar imageKirtiSwagat ( 2016-12-16 03:56:19 -0600 )edit

@berak hello, Ive used this to try and utilise it on linux (raspberry pi) and im struggling to make it work. i just keep getting the "no!" x10 every time i try and load it. i have 10 images named 1-10.jpg and it still wont work, any ideas?

t24-white gravatar imaget24-white ( 2017-02-26 14:49:22 -0600 )edit

@berak my output is as follows:

fold 0
no !/home/pi/selfdrivingcar/train_data/10.jpg
    no !/home/pi/selfdrivingcar/train_data/2.jpg
    no !/home/pi/selfdrivingcar/train_data/3.jpg
    no !/home/pi/selfdrivingcar/train_data/4.jpg
    no !/home/pi/selfdrivingcar/train_data/5.jpg
    no !/home/pi/selfdrivingcar/train_data/6.jpg
    no !/home/pi/selfdrivingcar/train_data/7.jpg
    no !/home/pi/selfdrivingcar/train_data/8.jpg
    no !/home/pi/selfdrivingcar/train_data/9.jpg
    no ! 
    no !
    no !
    no !
    no !
    no !

    (program exited with code:139)

what could be the problem?

t24-white gravatar imaget24-white ( 2017-02-26 15:00:11 -0600 )edit

@t-24-white : this example expected the att database, which has 40 subfolders (one per person), and 10 images each. a lot of things are hardcoded, you'll have to adapt it to your needs, if your data is organized differently.

berak gravatar imageberak ( 2017-02-27 08:13:51 -0600 )edit

@berak I changed the image path so it is correct (see output), From what I can see in the code there is a "no !" on line: if (image.empty()) {cerr << "no !" << fn[k] << endl; continue; } , i also added a +".jpg" on the imRead section to account for the file type. and still no luck, is there anything alse you can suggest?

t24-white gravatar imaget24-white ( 2017-02-27 09:07:32 -0600 )edit

again, since your folder-structure differs, you either have to adjust your data, or your code.

berak gravatar imageberak ( 2017-02-27 09:26:53 -0600 )edit

@berak hi, i used the above code to model a nn for hand gesture recognition which is giving an accuracy of 36.73% . I am using a training set of hand images for various symbols. Is this approach correct or do I need to do something different.Please help, I am new to neural networks as well as opencv (c++). Thanks!

theshubham998 gravatar imagetheshubham998 ( 2017-04-19 23:09:03 -0600 )edit

train_classes.at<float>(i, train_labels.at<int>(i)) = 1.f;

What does this line do? Please explain and thanks!

damiya14 gravatar imagedamiya14 ( 2017-05-05 03:49:26 -0600 )edit

@damiya14 , one-hot encoded response vector

(the desired output node gets a 1, all other a 0)

berak gravatar imageberak ( 2017-05-05 03:57:30 -0600 )edit

how can i save this ANN and load it again and input image and classify it?

damiya14 gravatar imagedamiya14 ( 2017-06-05 04:28:26 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2016-12-16 02:55:48 -0600

Seen: 10,762 times

Last updated: Dec 16 '16