Ask Your Question
0

I am trying to recognize facial emotion using SVM, however every time I run the program I get an error stating "assertion failed (samples.cols== var_count && samples.type == CV_32F) in cv::ml::SVMImpl::predict in file....... line 1919"

asked 2016-11-01 09:51:31 -0600

Akash Garg gravatar image

For now I am trying to predict only 2 emotion- Happy & Sad. The code is given below:- int main(int argc, const char* argv) {

cout << "OpenCV Training SVM Emotion Recognition\n";
cout << "\n";

const char* path_Happy;
const char* path_Sad;
int numHappy;
int numSad;
int imageWidth=144;
int imageHeight=33;

argc=5;
argv[1]= "10";
argv[2]= "10";
argv[3]= "C:/Users/akash garg/Documents/Visual Studio 2012/Projects/ExpressionSVM/ExpressionSVM/Happy";
argv[4]= "C:/Users/akash garg/Documents/Visual Studio 2012/Projects/ExpressionSVM/ExpressionSVM/Sad";

//Check if user specify image to process
if(argc >= 5 )
{
    numHappy= atoi(argv[1]);
    numSad= atoi(argv[2]);
    path_Happy= argv[3];
    path_Sad= argv[4];

}else{
    return 0;
}        

Mat classes;
Mat trainingData;
Mat trainingImages;
vector<int> trainingLabels;

for(int i=0; i< numHappy; i++)
{

    stringstream ss(stringstream::in | stringstream::out);
    ss << path_Happy <<"/" <<i+1 << ".png";
    cout<<ss.str()<<endl;
    //Mat img=imread(ss.str(), 0);
    Mat m = imread(ss.str(), 1);
    Mat img;
    cvtColor(m,img,CV_BGR2GRAY);

    img= img.reshape(1, 1);
    trainingImages.push_back(img);
    trainingLabels.push_back(1);
}

for(int i=0; i< numSad; i++)
{
    stringstream ss(stringstream::in | stringstream::out);
    ss << path_Sad <<"/" << i+1 << ".png";
    Mat img=imread(ss.str(), 0);
    img= img.reshape(1, 1);
    trainingImages.push_back(img);
    trainingLabels.push_back(0);

}

Mat(trainingImages).copyTo(trainingData);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);

FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
Ptr<ml::SVM> svm= ml::SVM::create();
svm->setType(ml::SVM::C_SVC);
svm->setKernel(ml::SVM::CHI2);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
svm->train(trainingData, ml::ROW_SAMPLE, classes);
svm->save("Trained.xml");
cout<<"\n SVM classifier is trained and saved.";
//svm= cv::Algorithm::load<ml::SVM>("Trained.xml"); 

//svm->load("Trained.xml");

//cv::Ptr<cv::ml::SVM> svm2= ml::SVM::create();
//svm2 = cv::ml::SVM::load<cv::ml::SVM>("Trained.xml");

svm= cv::ml::SVM::load<cv::ml::SVM>("Trained.xml");
Mat TestData= imread("C:/Users/akash garg/Documents/Visual Studio 2012/Projects/ExpressionSVM/ExpressionSVM/Test.png",0);
imshow("Test_Image", TestData);
Mat TestDataMat(1, 1, CV_32FC1, &TestData);
//TestData.convertTo(TestData, CV_32FC1);
//TestData= TestData.reshape(1,1);
//float response = svm->predict(TestData);
float response = svm->predict(TestDataMat);
if(response==1)
    cout<<"\n Happy Image Detected";
else if(response==0)
    cout<<"\n Sad Image Detected";
else
    cout<<"\n No emotion detected";
waitKey(0);
return 0;

}*

I have made the test image of same type as of training dataset but still I am getting the same error. Please help! Thanks in advance.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-11-01 10:34:02 -0600

berak gravatar image

make sure, your test image has the same size as the train images, and process it in the same way:

Mat TestData = imread("test.png",0);
TestData.convertTo(TestData, CV_32FC1);
TestData = TestData.reshape(1,1);
float response = svm->predict(TestData);
edit flag offensive delete link more

Comments

Yes @berak I did that also (the part I have commented out), but I got the same error. What should I do now????

Akash Garg gravatar imageAkash Garg ( 2016-11-01 11:20:13 -0600 )edit
  1. check image size again
  2. update question, remove all commented code, so we can see, what you're really doing now.
berak gravatar imageberak ( 2016-11-01 11:27:24 -0600 )edit
1

Thanks @berak. Solved the problem. Actually i got confuse in reshape and resize. If my input image is 640x490, reshape(1,1) will produce an image of size(313600x1) whereas Mat TestDataMat(1, 1, CV_32FC1, &TestData) produces an image if 1x1. Therefore the size of training and testing image differs.

Akash Garg gravatar imageAkash Garg ( 2016-11-02 06:41:46 -0600 )edit

The next problem I am facing is the accuracy of the classifier is very poor. It ends up predicting happy emotion most of the times even when the test image emotion is not happy. What should I do??

Akash Garg gravatar imageAkash Garg ( 2016-11-02 07:53:32 -0600 )edit

well, that's where the real work starts, no ?

  • more images (like x100)
  • smaller images (like 100x100)
  • proper alignment / cropping / lighting normalization
  • tweak svm params
  • use other features (hog, maybe, or sample very small image patches based on facial landmarks, like mouth / eye corners and concatenate those
berak gravatar imageberak ( 2016-11-02 07:58:51 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-11-01 09:51:31 -0600

Seen: 706 times

Last updated: Nov 01 '16