I'm using OpenCV v2.4.1
And this is the code I'm using
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
Mat toGrayscale(InputArray _src) {
Mat src = _src.getMat();
// only allow one channel
if(src.channels() != 1)
CV_Error(CV_StsBadArg, "Only Matrices with one channel are supported");
// create and return normalized image
Mat dst;
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
return dst;
}
void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file)
throw std::exception();
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
int main(int argc, const char *argv[]) {
// check for command line arguments
/*if (argc != 2) {
cout << "usage: " << argv[0] << " <csv.ext>" << endl;
exit(1);
}*/
// path to your CSV
string fn_csv = string("at.txt");
// images and corresponding labels
vector<Mat> images;
vector<int> labels;
// read in the data
try {
read_csv(fn_csv, images, labels);
} catch (exception&) {
cerr << "Error opening file \"" << fn_csv << "\"." << endl;
exit(1);
}
// get width and height
//int width = images[0].cols;
int height = images[0].rows;
// get test instances
Mat testSample = images[images.size() - 1];
int testLabel = labels[labels.size() - 1];
// ... and delete last element
images.pop_back();
labels.pop_back();
// build the Fisherfaces model
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
model->train(images, labels);
// test model
int predicted = model->predict(testSample);
cout << "predicted class = " << predicted << endl;
cout << "actual class = " << testLabel << endl;
// get the eigenvectors
Mat W = model->eigenvectors();
// show first 10 fisherfaces
for (int i = 0; i < min(10, W.cols); i++) {
// get eigenvector #i
Mat ev = W.col(i).clone();
// reshape to original size AND normalize between [0...255]
Mat grayscale = toGrayscale(ev.reshape(1, height));
// show image (with Jet colormap)
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
imshow(format("%d", i), cgrayscale);
}
waitKey(0);
return 0;
}
contents of at.txt input file :
./at/s10/2.pgm;9 ./at/s10/7.pgm;9 ./at/s10/6.pgm;9 ./at/s10/9.pgm;9 ./at/s10/5.pgm;9
Now the problem is , as long as I'm using this pgm files , It works fine . But when I specify any jpg file instead of pgm I get following error
OpenCV Error: Image step is wrong (The matrix is not continuous, thus its number of rows can not be changed) in unknown function, file ......\src\opencv\modul es\core\src\matrix.cpp, line 801
So far Im able to trace that error is coming from Fisherfaces.train() --> cv::Mat.reShape()
But I'm clueless , what could be the reason . Please help.